1---
2layout: api
3page_title: Prepared Queries - HTTP API
4sidebar_current: api-query
5description: |-
6  The /query endpoints manage and execute prepared queries in Consul.
7---
8
9# Prepared Query HTTP Endpoint
10
11The `/query` endpoints create, update, destroy, and execute prepared queries.
12
13Prepared queries allow you to register a complex service query and then execute
14it later via its ID or name to get a set of healthy nodes that provide a given
15service. This is particularly useful in combination with Consul's
16[DNS Interface](/docs/agent/dns.html) as it allows for much richer queries than
17would be possible given the limited entry points exposed by DNS.
18
19See the [Geo Failover Guide](/docs/guides/geo-failover.html) for details and
20examples for using prepared queries to implement geo failover for services.
21
22See the ACL Guide's [prepared query rules](/docs/guides/acl.html#prepared-query-rules)
23section for more details about how prepared queries work with Consul's ACL system.
24
25### Prepared Query Templates
26
27Consul 0.6.4 and later support prepared query templates. These are created
28similar to static queries, except with some additional fields and features.
29Here is an example prepared query template:
30
31```json
32{
33  "Template": {
34    "Type": "name_prefix_match",
35    "Regexp": "^geo-db-(.*?)-([^\\-]+?)$",
36    "RemoveEmptyTags": false
37  }
38}
39```
40
41The `Template` structure configures a prepared query as a template instead of a
42static query. It has two fields:
43
44- `Type` is the query type, which must be `name_prefix_match`. This means that
45  the template will apply to any query lookup with a name whose prefix matches
46  the `Name` field of the template. In this example, any query for `geo-db` will
47  match this query. Query templates are resolved using a longest prefix match,
48  so it's possible to have high-level templates that are overridden for specific
49  services. Static queries are always resolved first, so they can also override
50  templates.
51
52- `Regexp` is an optional regular expression which is used to extract fields
53  from the entire name, once this template is selected. In this example, the
54  regular expression takes the first item after the "-" as the database name and
55  everything else after as a tag. See the
56  [RE2](https://github.com/google/re2/wiki/Syntax) reference for syntax of this
57  regular expression.
58
59- `RemoveEmptyTags` is optional, and if set to true, will cause the `Tags` list
60  inside the `Service` structure to be stripped of any empty strings. This defaults
61  to false, meaning that empty strings will remain in the list. This is useful
62  when interpolating into tags in a way where the tag is optional, and where
63  searching for an empty tag would yield no results from the query.
64
65All other fields of the query have the same meanings as for a static query,
66except that several interpolation variables are available to dynamically
67populate the query before it is executed. All of the string fields inside the
68`Service` structure are interpolated, with the following variables available:
69
70- `${name.full}` has the entire name that was queried. For example, a DNS lookup
71  for `geo-db-customer-primary.query.consul` in the example above would set this
72  variable to `geo-db-customer-primary`.
73
74- `${name.prefix}` has the prefix that matched. This would always be `geo-db`
75  for the example above.
76
77- `${name.suffix}` has the suffix after the prefix. For example, a DNS lookup
78  for `geo-db-customer-primary.query.consul` in the example above would set this
79  variable to `-customer-primary`.
80
81- `${match(N)}` returns the regular expression match at the given index N. The 0
82  index will have the entire match, and >0 will have the results of each match
83  group. For example, a DNS lookup for `geo-db-customer-primary.query.consul` in
84  the example above with a `Regexp` field set to `^geo-db-(.*?)-([^\-]+?)$`
85  would return `geo-db-customer-primary` for `${match(0)}`, `customer` for
86  `${match(1)}`, and `primary` for `${match(2)}`. If the regular expression
87  doesn't match, or an invalid index is given, then `${match(N)}` will return an
88  empty string.
89
90- `${agent.segment}` has the network segment (Enterprise-only) of the agent that
91  initiated the query. This can be used with the `NodeMeta` field to limit the results
92  of a query to service instances within its own network segment:
93
94    ```json
95    {
96      "Name": "",
97      "Template": {
98        "Type": "name_prefix_match"
99      },
100      "Service": {
101        "Service": "${name.full}",
102        "NodeMeta": {"consul-network-segment": "${agent.segment}"}
103      }
104    }
105    ```
106  This will map all names of the form `<service>.query.consul` over DNS to a query
107  that will select an instance of the service in the agent's own network segment.
108
109Using templates, it is possible to apply prepared query behaviors to many
110services with a single template. Here's an example template that matches any
111query and applies a failover policy to it:
112
113```json
114{
115  "Name": "",
116  "Template": {
117    "Type": "name_prefix_match"
118  },
119  "Service": {
120    "Service": "${name.full}",
121    "Failover": {
122      "NearestN": 3
123    }
124  }
125}
126```
127
128This will match any lookup for `*.query.consul` and will attempt to find the
129service locally, and otherwise attempt to find that service in the next three
130closest datacenters. If ACLs are enabled, a catch-all template like this with
131an empty `Name` requires an ACL token that can write to any query prefix. Also,
132only a single catch-all template can be registered at any time.
133
134## Create Prepared Query
135
136This endpoint creates a new prepared query and returns its ID if it is created
137successfully.
138
139| Method | Path                         | Produces                   |
140| ------ | ---------------------------- | -------------------------- |
141| `POST`  | `/query`                     | `application/json`         |
142
143The table below shows this endpoint's support for
144[blocking queries](/api/index.html#blocking-queries),
145[consistency modes](/api/index.html#consistency-modes),
146[agent caching](/api/index.html#agent-caching), and
147[required ACLs](/api/index.html#acls).
148
149| Blocking Queries | Consistency Modes | Agent Caching | ACL Required  |
150| ---------------- | ----------------- | ------------- | ------------- |
151| `NO`             | `none`            | `none`        | `query:write` |
152
153### Parameters
154
155- `dc` `(string: "")` - Specifies the datacenter to query. This will default to
156  the datacenter of the agent being queried. This is specified as part of the
157  URL as a query parameter.
158
159- `Name` `(string: "")` - Specifies an optional friendly name that can be used
160  to execute a query instead of using its ID.
161
162- `Session` `(string: "")` - Specifies the ID of an existing session. This
163  provides a way to automatically remove a prepared query when the given session
164  is invalidated. If not given the prepared query must be manually removed when
165  no longer needed.
166
167- `Token` `(string: "")` - Specifies the ACL token to use each time the query is
168  executed. This allows queries to be executed by clients with lesser or even no
169  ACL Token, so this should be used with care. The token itself can only be seen
170  by clients with a management token. If the `Token` field is left blank or
171  omitted, the client's ACL Token will be used to determine if they have access
172  to the service being queried. If the client does not supply an ACL Token, the
173  anonymous token will be used.
174
175- `Service` `(Service: <required>)` - Specifies the structure to define the query's behavior.
176
177  - `Service` `(string: <required>)` - Specifies the name of the service to
178    query.
179
180  - `Failover` contains two fields, both of which are optional, and determine
181    what happens if no healthy nodes are available in the local datacenter when
182    the query is executed. It allows the use of nodes in other datacenters with
183    very little configuration.
184
185      - `NearestN` `(int: 0)` - Specifies that the query will be forwarded to up
186        to `NearestN` other datacenters based on their estimated network round
187        trip time using [Network Coordinates](/docs/internals/coordinates.html)
188        from the WAN gossip pool. The median round trip time from the server
189        handling the query to the servers in the remote datacenter is used to
190        determine the priority.
191
192      - `Datacenters` `(array<string>: nil)` - Specifies a fixed list of remote
193        datacenters to forward the query to if there are no healthy nodes in the
194        local datacenter. Datacenters are queried in the order given in the
195        list. If this option is combined with `NearestN`, then the `NearestN`
196        queries will be performed first, followed by the list given by
197        `Datacenters`. A given datacenter will only be queried one time during a
198        failover, even if it is selected by both `NearestN` and is listed in
199        `Datacenters`.
200
201  - `IgnoreCheckIDs` `(array<string>: nil)` - Specifies a list of check IDs that
202    should be ignored when filtering unhealthy instances. This is mostly useful
203    in an emergency or as a temporary measure when a health check is found to be
204    unreliable. Being able to ignore it in centrally-defined queries can be
205    simpler than de-registering the check as an interim solution until the check
206    can be fixed.
207
208  - `OnlyPassing` `(bool: false)` - Specifies the behavior of the query's health
209    check filtering. If this is set to false, the results will include nodes
210    with checks in the passing as well as the warning states. If this is set to
211    true, only nodes with checks in the passing state will be returned.
212
213  - `Near` `(string: "")` - Specifies a node to sort near based on distance
214     sorting using [Network Coordinates](/docs/internals/coordinates.html). The
215     nearest instance to the specified node will be returned first, and subsequent
216     nodes in the response will be sorted in ascending order of estimated
217     round-trip times. If the node given does not exist, the nodes in the response
218     will be shuffled. If unspecified, the response will be shuffled by default.
219
220       - `_agent` - Returns results nearest the agent servicing the request.
221       - `_ip` - Returns results nearest to the node associated with the source IP
222         where the query was executed from. For HTTP the source IP is the remote
223         peer's IP address or the value of the X-Forwarded-For header with the
224         header taking precedence. For DNS the source IP is the remote peer's IP
225         address or the value of the ENDS client IP with the EDNS client IP
226         taking precedence.
227
228
229  - `Tags` `(array<string>: nil)` - Specifies a list of service tags to filter
230    the query results. For a service to pass the tag filter it must have *all*
231    of the required tags, and *none* of the excluded tags (prefixed with `!`).
232
233  - `NodeMeta` `(map<string|string>: nil)` - Specifies a list of user-defined
234    key/value pairs that will be used for filtering the query results to nodes
235    with the given metadata values present.
236
237  - `Connect` `(bool: false)` - If true, only [Connect-capable](/docs/connect/index.html) services
238    for the specified service name will be returned. This includes both
239	natively integrated services and proxies. For proxies, the proxy name
240	may not match `Service`, because the proxy destination will. Any
241	constrains beyond the service name such as `Near`, `Tags`, and `NodeMeta`
242	are applied to Connect-capable service.
243
244- `DNS` `(DNS: nil)` - Specifies DNS configuration
245
246  - `TTL` `(string: "")` - Specifies the TTL duration when query results are
247    served over DNS. If this is specified, it will take precedence over any
248    Consul agent-specific configuration.
249
250### Sample Payload
251
252```json
253{
254  "Name": "my-query",
255  "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
256  "Token": "",
257  "Service": {
258    "Service": "redis",
259    "Failover": {
260      "NearestN": 3,
261      "Datacenters": ["dc1", "dc2"]
262    },
263    "Near": "node1",
264    "OnlyPassing": false,
265    "Tags": ["primary", "!experimental"],
266    "NodeMeta": {"instance_type": "m3.large"}
267  },
268  "DNS": {
269    "TTL": "10s"
270  }
271}
272```
273
274### Sample Request
275
276```text
277$ curl \
278    --request POST \
279    --data @payload.json \
280    http://127.0.0.1:8500/v1/query
281```
282
283### Sample Response
284
285```json
286{
287  "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05"
288}
289```
290
291## Read Prepared Query
292
293This endpoint returns a list of all prepared queries.
294
295| Method | Path                         | Produces                   |
296| ------ | ---------------------------- | -------------------------- |
297| `GET`  | `/query`                     | `application/json`         |
298
299The table below shows this endpoint's support for
300[blocking queries](/api/index.html#blocking-queries),
301[consistency modes](/api/index.html#consistency-modes),
302[agent caching](/api/index.html#agent-caching), and
303[required ACLs](/api/index.html#acls).
304
305| Blocking Queries | Consistency Modes | Agent Caching | ACL Required |
306| ---------------- | ----------------- | ------------- | ------------ |
307| `NO`             | `none`            | `none`        | `query:read` |
308
309### Parameters
310
311- `dc` `(string: "")` - Specifies the datacenter to query. This will default to
312  the datacenter of the agent being queried. This is specified as part of the
313  URL as a query parameter.
314
315### Sample Request
316
317```text
318$ curl \
319    http://127.0.0.1:8500/v1/query
320```
321
322### Sample Response
323
324```json
325[
326  {
327    "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05",
328    "Name": "my-query",
329    "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
330    "Token": "<hidden>",
331    "Service": {
332      "Service": "redis",
333      "Failover": {
334        "NearestN": 3,
335        "Datacenters": ["dc1", "dc2"]
336      },
337      "OnlyPassing": false,
338      "Tags": ["primary", "!experimental"],
339      "NodeMeta": {"instance_type": "m3.large"}
340    },
341    "DNS": {
342      "TTL": "10s"
343    },
344    "RaftIndex": {
345      "CreateIndex": 23,
346      "ModifyIndex": 42
347    }
348  }
349]
350```
351
352### Update Prepared Query
353
354This endpoint updates an existing prepared query. If no query exists by the
355given ID, an error is returned.
356
357| Method | Path                         | Produces                   |
358| ------ | ---------------------------- | -------------------------- |
359| `PUT`  | `/query/:uuid`               | `application/json`         |
360
361The table below shows this endpoint's support for
362[blocking queries](/api/index.html#blocking-queries),
363[consistency modes](/api/index.html#consistency-modes),
364[agent caching](/api/index.html#agent-caching), and
365[required ACLs](/api/index.html#acls).
366
367| Blocking Queries | Consistency Modes | Agent Caching | ACL Required  |
368| ---------------- | ----------------- | ------------- | ------------- |
369| `NO`             | `none`            | `none`        | `query:write` |
370
371### Parameters
372
373- `uuid` `(string: <required>)` - Specifies the UUID of the query to update.
374  This is required and is specified as part of the URL path.
375
376- `dc` `(string: "")` - Specifies the datacenter to query. This will default to
377  the datacenter of the agent being queried. This is specified as part of the
378  URL as a query parameter.
379
380The body is the same as is used to create a prepared query. Please see above for
381more information.
382
383### Sample Request
384
385```text
386$ curl \
387    --request PUT \
388    --data @payload.json \
389    http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05
390```
391
392## Read Prepared Query
393
394This endpoint reads an existing prepared query. If no query exists by the
395given ID, an error is returned.
396
397| Method | Path                         | Produces                   |
398| ------ | ---------------------------- | -------------------------- |
399| `GET`  | `/query/:uuid`               | `application/json`         |
400
401The table below shows this endpoint's support for
402[blocking queries](/api/index.html#blocking-queries),
403[consistency modes](/api/index.html#consistency-modes),
404[agent caching](/api/index.html#agent-caching), and
405[required ACLs](/api/index.html#acls).
406
407| Blocking Queries | Consistency Modes | Agent Caching | ACL Required |
408| ---------------- | ----------------- | ------------- | ------------ |
409| `NO`             | `none`            | `none`        | `query:read` |
410
411### Parameters
412
413- `uuid` `(string: <required>)` - Specifies the UUID of the query to read.
414  This is required and is specified as part of the URL path.
415
416- `dc` `(string: "")` - Specifies the datacenter to query. This will default to
417  the datacenter of the agent being queried. This is specified as part of the
418  URL as a query parameter.
419
420### Sample Request
421
422```text
423$ curl \
424  http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05
425```
426
427### Sample Response
428
429The returned response is the same as the list of prepared queries above, only
430with a single item present.
431
432## Delete Prepared Query
433
434This endpoint deletes an existing prepared query. If no query exists by the
435given ID, an error is returned.
436
437| Method    | Path                         | Produces                   |
438| --------- | ---------------------------- | -------------------------- |
439| `DELETE`  | `/query/:uuid`               | `application/json`         |
440
441The table below shows this endpoint's support for
442[blocking queries](/api/index.html#blocking-queries),
443[consistency modes](/api/index.html#consistency-modes),
444[agent caching](/api/index.html#agent-caching), and
445[required ACLs](/api/index.html#acls).
446
447| Blocking Queries | Consistency Modes | Agent Caching | ACL Required  |
448| ---------------- | ----------------- | ------------- | ------------- |
449| `NO`             | `none`            | `none`        | `query:write` |
450
451### Parameters
452
453- `uuid` `(string: <required>)` - Specifies the UUID of the query to delete.
454  This is required and is specified as part of the URL path.
455
456- `dc` `(string: "")` - Specifies the datacenter to query. This will default to
457  the datacenter of the agent being queried. This is specified as part of the
458  URL as a query parameter.
459
460### Sample Request
461
462```text
463$ curl \
464    --request DELETE \
465    http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05
466```
467
468## Execute Prepared Query
469
470This endpoint executes an existing prepared query. If no query exists by the
471given ID, an error is returned.
472
473| Method | Path                         | Produces                   |
474| ------ | ---------------------------- | -------------------------- |
475| `GET`  | `/query/:uuid/execute`       | `application/json`         |
476
477The table below shows this endpoint's support for
478[blocking queries](/api/index.html#blocking-queries),
479[consistency modes](/api/index.html#consistency-modes),
480[agent caching](/api/index.html#agent-caching), and
481[required ACLs](/api/index.html#acls).
482
483| Blocking Queries | Consistency Modes | Agent Caching | ACL Required |
484| ---------------- | ----------------- | ------------- | ------------ |
485| `NO`             | `none`            | `simple`      | `depends`<sup>1</sup>    |
486
487<sup>1</sup> If an ACL Token was bound to the query when it was defined then it
488will be used when executing the request. Otherwise, the client's supplied ACL
489Token will be used.
490
491### Parameters
492
493- `uuid` `(string: <required>)` - Specifies the UUID of the query to execute.
494  This is required and is specified as part of the URL path. This can also be
495  the name of an existing prepared query, or a name that matches a prefix name
496  for a prepared query template.
497
498- `dc` `(string: "")` - Specifies the datacenter to query. This will default to
499  the datacenter of the agent being queried. This is specified as part of the
500  URL as a query parameter.
501
502- `near` `(string: "")` - Specifies to sort the resulting list in ascending
503  order based on the estimated round trip time from that node. Passing
504  `?near=_agent` will use the agent's node for the sort. Passing `?near=_ip`
505  will use the source IP of the request or the value of the X-Forwarded-For
506  header to lookup the node to use for the sort. If this is not present,
507  the default behavior will shuffle the nodes randomly each time the query is
508  executed.
509
510- `limit` `(int: 0)` - Limit the size of the list to the given number of nodes.
511  This is applied after any sorting or shuffling.
512
513- `connect` `(bool: false)` - If true, limit results to nodes that are
514  Connect-capable only. This can also be specified directly on the template
515  itself to force all executions of a query to be Connect-only. See the
516  template documentation for more information.
517
518### Sample Request
519
520```text
521$ curl \
522    http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05/execute?near=_agent
523```
524
525### Sample Response
526
527```json
528{
529  "Service": "redis",
530  "Nodes": [
531    {
532      "Node": {
533        "ID": "40e4a748-2192-161a-0510-9bf59fe950b5",
534        "Node": "foobar",
535        "Address": "10.1.10.12",
536        "Datacenter": "dc1",
537        "TaggedAddresses": {
538          "lan": "10.1.10.12",
539          "wan": "10.1.10.12"
540        },
541        "NodeMeta": {"instance_type": "m3.large"}
542      },
543      "Service": {
544        "ID": "redis",
545        "Service": "redis",
546        "Tags": null,
547        "Meta": {"redis_version": "4.0"},
548        "Port": 8000
549      },
550      "Checks": [
551        {
552          "Node": "foobar",
553          "CheckID": "service:redis",
554          "Name": "Service 'redis' check",
555          "Status": "passing",
556          "Notes": "",
557          "Output": "",
558          "ServiceID": "redis",
559          "ServiceName": "redis"
560        },
561        {
562          "Node": "foobar",
563          "CheckID": "serfHealth",
564          "Name": "Serf Health Status",
565          "Status": "passing",
566          "Notes": "",
567          "Output": "",
568          "ServiceID": "",
569          "ServiceName": ""
570        }
571      ],
572    "DNS": {
573      "TTL": "10s"
574    },
575    "Datacenter": "dc3",
576    "Failovers": 2
577  }]
578}
579```
580
581- `Nodes` contains the list of healthy nodes providing the given service, as
582  specified by the constraints of the prepared query.
583
584- `Service` has the service name that the query was selecting. This is useful
585  for context in case an empty list of nodes is returned.
586
587- `DNS` has information used when serving the results over DNS. This is just a
588  copy of the structure given when the prepared query was created.
589
590- `Datacenter` has the datacenter that ultimately provided the list of nodes and
591  `Failovers` has the number of remote datacenters that were queried while
592  executing the query. This provides some insight into where the data came from.
593  This will be zero during non-failover operations where there were healthy
594  nodes found in the local datacenter.
595
596## Explain Prepared Query
597
598This endpoint generates a fully-rendered query for a given name, post
599interpolation.
600
601| Method | Path                         | Produces                   |
602| ------ | ---------------------------- | -------------------------- |
603| `GET`  | `/query/:uuid/explain`       | `application/json`         |
604
605The table below shows this endpoint's support for
606[blocking queries](/api/index.html#blocking-queries),
607[consistency modes](/api/index.html#consistency-modes),
608[agent caching](/api/index.html#agent-caching), and
609[required ACLs](/api/index.html#acls).
610
611| Blocking Queries | Consistency Modes | Agent Caching | ACL Required |
612| ---------------- | ----------------- | ------------- | ------------ |
613| `NO`             | `none`            | `none`        | `query:read` |
614
615### Parameters
616
617- `uuid` `(string: <required>)` - Specifies the UUID of the query to explain.
618  This is required and is specified as part of the URL path. This can also be
619  the name of an existing prepared query, or a name that matches a prefix name
620  for a prepared query template.
621
622- `dc` `(string: "")` - Specifies the datacenter to query. This will default to
623  the datacenter of the agent being queried. This is specified as part of the
624  URL as a query parameter.
625
626### Sample Request
627
628```text
629$ curl \
630    http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05/explain
631```
632
633### Sample Response
634
635```json
636{
637  "Query": {
638    "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05",
639    "Name": "my-query",
640    "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
641    "Token": "<hidden>",
642    "Name": "geo-db",
643    "Template": {
644      "Type": "name_prefix_match",
645      "Regexp": "^geo-db-(.*?)-([^\\-]+?)$"
646    },
647    "Service": {
648      "Service": "mysql-customer",
649      "Failover": {
650        "NearestN": 3,
651        "Datacenters": ["dc1", "dc2"]
652      },
653      "OnlyPassing": true,
654      "Tags": ["primary"],
655      "Meta": { "mysql_version": "5.7.20" },
656      "NodeMeta": {"instance_type": "m3.large"}
657    }
658  }
659}
660```
661