github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/website/content/api-docs/index.mdx (about) 1 --- 2 layout: api 3 page_title: HTTP API 4 description: |- 5 Nomad exposes a RESTful HTTP API to control almost every aspect of the 6 Nomad agent. 7 --- 8 9 # HTTP API 10 11 The main interface to Nomad is a RESTful HTTP API. The API can query the current 12 state of the system as well as modify the state of the system. The Nomad CLI 13 actually invokes Nomad's HTTP for many commands. 14 15 ## Version Prefix 16 17 All API routes are prefixed with `/v1/`. 18 19 ## Addressing and Ports 20 21 Nomad binds to a specific set of addresses and ports. The HTTP API is served via 22 the `http` address and port. This `address:port` must be accessible locally. If 23 you bind to `127.0.0.1:4646`, the API is only available _from that host_. If you 24 bind to a private internal IP, the API will be available from within that 25 network. If you bind to a public IP, the API will be available from the public 26 Internet (not recommended). 27 28 The default port for the Nomad HTTP API is `4646`. This can be overridden via 29 the Nomad configuration block. Here is an example curl request to query a Nomad 30 server with the default configuration: 31 32 ```shell-session 33 $ curl http://127.0.0.1:4646/v1/agent/members 34 ``` 35 36 The conventions used in the API documentation do not list a port and use the 37 standard URL `localhost:4646`. Be sure to replace this with your Nomad agent URL 38 when using the examples. 39 40 ## Data Model and Layout 41 42 There are five primary nouns in Nomad: 43 44 - jobs 45 - nodes 46 - allocations 47 - deployments 48 - evaluations 49 50 [](/img/nomad-data-model.png) 51 52 Jobs are submitted by users and represent a _desired state_. A job is a 53 declarative description of tasks to run which are bounded by constraints and 54 require resources. Jobs can also have affinities which are used to express placement 55 preferences. Nodes are the servers in the clusters that tasks can be 56 scheduled on. The mapping of tasks in a job to nodes is done using allocations. 57 An allocation is used to declare that a set of tasks in a job should be run on a 58 particular node. Scheduling is the process of determining the appropriate 59 allocations and is done as part of an evaluation. Deployments are objects to 60 track a rolling update of allocations between two versions of a job. 61 62 The API is modeled closely on the underlying data model. Use the links to the 63 left for documentation about specific endpoints. There are also "Agent" APIs 64 which interact with a specific agent and not the broader cluster used for 65 administration. 66 67 ## ACLs 68 69 Several endpoints in Nomad use or require ACL tokens to operate. The token are used to authenticate the request and determine if the request is allowed based on the associated authorizations. Tokens are specified per-request by using the `X-Nomad-Token` request header or with the Bearer scheme in the authorization header set to the `SecretID` of an ACL Token. 70 71 For more details about ACLs, please see the [ACL Guide](https://learn.hashicorp.com/collections/nomad/access-control). 72 73 ## Authentication 74 75 When ACLs are enabled, a Nomad token should be provided to API requests using the `X-Nomad-Token` header or with the Bearer scheme in the authorization header. When using authentication, clients should communicate via TLS. 76 77 Here is an example using curl with `X-Nomad-Token`: 78 79 ```shell-session 80 $ curl \ 81 --header "X-Nomad-Token: aa534e09-6a07-0a45-2295-a7f77063d429" \ 82 https://localhost:4646/v1/jobs 83 ``` 84 85 Below is an example using `curl` with a [RFC6750](https://tools.ietf.org/html/rfc6750) Bearer token: 86 87 ```shell-session 88 $ curl \ 89 --header "Authorization: Bearer <token>" \ 90 http://localhost:4646/v1/jobs 91 ``` 92 93 ## Namespaces 94 95 Nomad has support for namespaces, which allow jobs and their associated objects 96 to be segmented from each other and other users of the cluster. When using 97 non-default namespace, the API request must pass the target namespace as an API 98 query parameter. Prior to Nomad 1.0 namespaces were Enterprise-only. 99 100 Here is an example using curl: 101 102 ```shell-session 103 $ curl https://localhost:4646/v1/jobs?namespace=qa 104 ``` 105 106 ## Filtering 107 108 Filter expressions refine data queries for some API listing endpoints, as 109 notated in the individual API endpoints documentation. 110 111 To create a filter expression, you will write one or more expressions. Each 112 expression has matching operators composed of selectors and values. 113 114 Filtering is executed on the Nomad server, before data is returned, reducing 115 the network load. To pass a filter expression to Nomad, use the `filter` query 116 parameter with the URL encoded expression when sending requests to HTTP API 117 endpoints that support it. 118 119 ```shell-session 120 $ curl --get https://localhost:4646/v1/<path> --data-urlencode 'filter=<filter expression>' 121 ``` 122 123 Some endpoints may have other query parameters that are used for filtering, but 124 they can't be used with the `filter` query parameter. Doing so will result in a 125 `400` status error response. These query parameters are usually backed by a 126 database index, so they may be prefereable over an equivalent simple `filter` 127 expression due to better resource usage and performance. 128 129 ### Creating Expressions 130 131 A single expression is a matching operator with a selector and value and they 132 are written in plain text format. Boolean logic and parenthesization are 133 supported. In general, whitespace is ignored, except within literal strings. 134 135 #### Matching Operators 136 137 All matching operators use a selector or value to choose what data should be 138 matched. Each endpoint that supports filtering accepts a potentially 139 different list of selectors and is detailed in the API documentation for 140 those endpoints. 141 142 ```hcl 143 // Equality & Inequality checks 144 <Selector> == "<Value>" 145 <Selector> != "<Value>" 146 147 // Emptiness checks 148 <Selector> is empty 149 <Selector> is not empty 150 151 // Contains checks or Substring Matching 152 "<Value>" in <Selector> 153 "<Value>" not in <Selector> 154 <Selector> contains "<Value>" 155 <Selector> not contains "<Value>" 156 157 // Regular Expression Matching 158 <Selector> matches "<Value>" 159 <Selector> not matches "<Value>" 160 ``` 161 162 #### Selectors 163 164 Selectors are used by matching operators to create an expression. They are 165 defined by a `.` separated list of names. Each name must start with an ASCII 166 letter and can contain ASCII letters, numbers, and underscores. When part of 167 the selector references a map value it may be expressed using the form 168 `["<map key name>"]` instead of `.<map key name>`. This allows the possibility 169 of using map keys that are not valid selectors in and of themselves. 170 171 ```hcl 172 // selects the `cache` key within the `TaskGroups` mapping for the 173 // /v1/deployments endpoint 174 TaskGroups.cache 175 176 // Also selects the `cache` key for the same endpoint 177 TaskGroups["cache"] 178 ``` 179 180 #### Values 181 182 Values are used by matching operators to create an expression. Values can be 183 any valid selector, a number, or a string. It is best practice to quote values. 184 Numbers can be base 10 integers or floating point numbers. 185 186 When quoting strings, they may either be enclosed in double quotes or 187 backticks. When enclosed in backticks they are treated as raw strings and 188 escape sequences such as `\n` will not be expanded. 189 190 ### Connecting Expressions 191 192 There are several methods for connecting expressions, including: 193 194 - logical `or` 195 - logical `and` 196 - logical `not` 197 - grouping with parenthesis 198 - matching expressions 199 200 ```hcl 201 // Logical Or - evaluates to true if either sub-expression does 202 <Expression 1> or <Expression 2> 203 204 // Logical And - evaluates to true if both sub-expressions do 205 <Expression 1 > and <Expression 2> 206 207 // Logical Not - evaluates to true if the sub-expression does not 208 not <Expression 1> 209 210 // Grouping - Overrides normal precedence rules 211 ( <Expression 1> ) 212 213 // Inspects data to check for a match 214 <Matching Expression 1> 215 ``` 216 217 Standard operator precedence can be expected for the various forms. For 218 example, the following two expressions would be equivalent. 219 220 ```hcl 221 <Expression 1> and not <Expression 2> or <Expression 3> 222 223 ( <Expression 1> and (not <Expression 2> )) or <Expression 3> 224 ``` 225 226 ### Filter Utilization 227 228 Generally, only the main object is filtered. When filtering for an item within 229 an array that is not at the top level, the entire array that contains the item 230 will be returned. This is usually the outermost object of a response, but in 231 some cases the filtering is performed on a object embedded within the results. 232 233 #### Performance 234 235 Filters are executed on the servers and therefore will consume some amount 236 of CPU time on the server. For non-stale queries this means that the filter 237 is executed on the leader. 238 239 #### Filtering Examples 240 241 ##### Jobs API 242 243 Command (Unfiltered) 244 245 ```shell-session 246 $ curl --request GET https://localhost:4646/v1/jobs 247 ``` 248 249 Response (Unfiltered) 250 251 ```json 252 [ 253 { 254 "CreateIndex": 52, 255 "Datacenters": [ 256 "dc1", 257 "dc2" 258 ], 259 "ID": "countdash", 260 "JobModifyIndex": 56, 261 "JobSummary": { 262 "Children": { 263 "Dead": 0, 264 "Pending": 0, 265 "Running": 0 266 }, 267 "CreateIndex": 52, 268 "JobID": "countdash", 269 "ModifyIndex": 55, 270 "Namespace": "default", 271 "Summary": { 272 "api": { 273 "Complete": 0, 274 "Failed": 0, 275 "Lost": 0, 276 "Queued": 1, 277 "Running": 0, 278 "Starting": 0 279 }, 280 "dashboard": { 281 "Complete": 0, 282 "Failed": 0, 283 "Lost": 0, 284 "Queued": 1, 285 "Running": 0, 286 "Starting": 0 287 } 288 } 289 }, 290 "ModifyIndex": 56, 291 "Multiregion": null, 292 "Name": "countdash", 293 "Namespace": "default", 294 "ParameterizedJob": false, 295 "ParentID": "", 296 "Periodic": false, 297 "Priority": 50, 298 "Status": "pending", 299 "StatusDescription": "", 300 "Stop": false, 301 "SubmitTime": 1645230445788556000, 302 "Type": "service" 303 }, 304 { 305 "CreateIndex": 42, 306 "Datacenters": [ 307 "dc1" 308 ], 309 "ID": "example", 310 "JobModifyIndex": 42, 311 "JobSummary": { 312 "Children": { 313 "Dead": 0, 314 "Pending": 0, 315 "Running": 0 316 }, 317 "CreateIndex": 42, 318 "JobID": "example", 319 "ModifyIndex": 46, 320 "Namespace": "default", 321 "Summary": { 322 "cache": { 323 "Complete": 0, 324 "Failed": 0, 325 "Lost": 0, 326 "Queued": 0, 327 "Running": 1, 328 "Starting": 0 329 } 330 } 331 }, 332 "ModifyIndex": 49, 333 "Multiregion": null, 334 "Name": "example", 335 "Namespace": "default", 336 "ParameterizedJob": false, 337 "ParentID": "", 338 "Periodic": false, 339 "Priority": 50, 340 "Status": "running", 341 "StatusDescription": "", 342 "Stop": false, 343 "SubmitTime": 1645230403921889000, 344 "Type": "service" 345 } 346 ] 347 ``` 348 349 Command (Filtered) 350 351 ```shell 352 curl --get https://localhost:4646/v1/jobs \ 353 --data-urlencode 'filter=Datacenters contains "dc2"' 354 ``` 355 356 Response (Filtered) 357 358 ```json 359 [ 360 { 361 "CreateIndex": 52, 362 "Datacenters": [ 363 "dc1", 364 "dc2" 365 ], 366 "ID": "countdash", 367 "JobModifyIndex": 56, 368 "JobSummary": { 369 "Children": { 370 "Dead": 0, 371 "Pending": 0, 372 "Running": 0 373 }, 374 "CreateIndex": 52, 375 "JobID": "countdash", 376 "ModifyIndex": 55, 377 "Namespace": "default", 378 "Summary": { 379 "api": { 380 "Complete": 0, 381 "Failed": 0, 382 "Lost": 0, 383 "Queued": 1, 384 "Running": 0, 385 "Starting": 0 386 }, 387 "dashboard": { 388 "Complete": 0, 389 "Failed": 0, 390 "Lost": 0, 391 "Queued": 1, 392 "Running": 0, 393 "Starting": 0 394 } 395 } 396 }, 397 "ModifyIndex": 56, 398 "Multiregion": null, 399 "Name": "countdash", 400 "Namespace": "default", 401 "ParameterizedJob": false, 402 "ParentID": "", 403 "Periodic": false, 404 "Priority": 50, 405 "Status": "pending", 406 "StatusDescription": "", 407 "Stop": false, 408 "SubmitTime": 1645230445788556000, 409 "Type": "service" 410 } 411 ] 412 ``` 413 414 ##### Deployments API 415 416 Command (Unfiltered) 417 418 ```shell-session 419 $ curl --request GET https://localhost:4646/v1/deployments 420 ``` 421 422 Response (Unfiltered) 423 424 ```json 425 [ 426 { 427 "CreateIndex": 54, 428 "EvalPriority": 50, 429 "ID": "58fd0616-ce64-d14b-6917-03d0ab5af67e", 430 "IsMultiregion": false, 431 "JobCreateIndex": 52, 432 "JobID": "countdash", 433 "JobModifyIndex": 52, 434 "JobSpecModifyIndex": 52, 435 "JobVersion": 0, 436 "ModifyIndex": 59, 437 "Namespace": "default", 438 "Status": "cancelled", 439 "StatusDescription": "Cancelled due to newer version of job", 440 "TaskGroups": { 441 "dashboard": { 442 "AutoPromote": false, 443 "AutoRevert": false, 444 "DesiredCanaries": 0, 445 "DesiredTotal": 1, 446 "HealthyAllocs": 0, 447 "PlacedAllocs": 0, 448 "PlacedCanaries": null, 449 "ProgressDeadline": 600000000000, 450 "Promoted": false, 451 "RequireProgressBy": null, 452 "UnhealthyAllocs": 0 453 }, 454 "api": { 455 "AutoPromote": false, 456 "AutoRevert": false, 457 "DesiredCanaries": 0, 458 "DesiredTotal": 1, 459 "HealthyAllocs": 0, 460 "PlacedAllocs": 0, 461 "PlacedCanaries": null, 462 "ProgressDeadline": 600000000000, 463 "Promoted": false, 464 "RequireProgressBy": null, 465 "UnhealthyAllocs": 0 466 } 467 } 468 }, 469 { 470 "CreateIndex": 43, 471 "EvalPriority": 50, 472 "ID": "1f18b48c-b33b-8e96-5640-71e3f3000242", 473 "IsMultiregion": false, 474 "JobCreateIndex": 42, 475 "JobID": "example", 476 "JobModifyIndex": 42, 477 "JobSpecModifyIndex": 42, 478 "JobVersion": 0, 479 "ModifyIndex": 49, 480 "Namespace": "default", 481 "Status": "successful", 482 "StatusDescription": "Deployment completed successfully", 483 "TaskGroups": { 484 "cache": { 485 "AutoPromote": false, 486 "AutoRevert": false, 487 "DesiredCanaries": 0, 488 "DesiredTotal": 1, 489 "HealthyAllocs": 1, 490 "PlacedAllocs": 1, 491 "PlacedCanaries": null, 492 "ProgressDeadline": 600000000000, 493 "Promoted": false, 494 "RequireProgressBy": "2022-02-18T19:36:54.421823-05:00", 495 "UnhealthyAllocs": 0 496 } 497 } 498 } 499 ] 500 ``` 501 502 Command (Filtered) 503 504 ```shell 505 curl --get https://localhost:4646/v1/deployments \ 506 --data-urlencode 'filter=Status != "successful"' 507 ``` 508 509 Response (Filtered) 510 511 ```json 512 [ 513 { 514 "CreateIndex": 54, 515 "EvalPriority": 50, 516 "ID": "58fd0616-ce64-d14b-6917-03d0ab5af67e", 517 "IsMultiregion": false, 518 "JobCreateIndex": 52, 519 "JobID": "countdash", 520 "JobModifyIndex": 52, 521 "JobSpecModifyIndex": 52, 522 "JobVersion": 0, 523 "ModifyIndex": 59, 524 "Namespace": "default", 525 "Status": "cancelled", 526 "StatusDescription": "Cancelled due to newer version of job", 527 "TaskGroups": { 528 "dashboard": { 529 "AutoPromote": false, 530 "AutoRevert": false, 531 "DesiredCanaries": 0, 532 "DesiredTotal": 1, 533 "HealthyAllocs": 0, 534 "PlacedAllocs": 0, 535 "PlacedCanaries": null, 536 "ProgressDeadline": 600000000000, 537 "Promoted": false, 538 "RequireProgressBy": null, 539 "UnhealthyAllocs": 0 540 }, 541 "api": { 542 "AutoPromote": false, 543 "AutoRevert": false, 544 "DesiredCanaries": 0, 545 "DesiredTotal": 1, 546 "HealthyAllocs": 0, 547 "PlacedAllocs": 0, 548 "PlacedCanaries": null, 549 "ProgressDeadline": 600000000000, 550 "Promoted": false, 551 "RequireProgressBy": null, 552 "UnhealthyAllocs": 0 553 } 554 } 555 } 556 ] 557 ``` 558 559 ## Pagination 560 561 Some list endpoints support partial results to limit the amount of data 562 retrieved. The returned list is split into pages and the page size can be set 563 using the `per_page` query parameter with a positive integer value. 564 565 If more data is available past the page requested, the response will contain an 566 HTTP header named `X-Nomad-Nexttoken` with the value of the next item to be 567 retrieved. This value can then be set as a query parameter called `next_token` 568 in a follow-up request to retrieve the next page. 569 570 When the last page is reached, the `X-Nomad-Nexttoken` HTTP header will not 571 be present in the response, indicating that there is nothing more to return. 572 573 ## Ordering 574 575 List results are usually returned in ascending order by their internal key, 576 such as their `ID`. Some endpoints may return data sorted by their 577 `CreateIndex` value, which roughly corelates to their creation order. The 578 result order may be reversed using the `reverse=true` query parameter when 579 supported by the endpoint. 580 581 ## Blocking Queries 582 583 Many endpoints in Nomad support a feature known as "blocking queries". A 584 blocking query is used to wait for a potential change using long polling. Not 585 all endpoints support blocking, but each endpoint uniquely documents its support 586 for blocking queries in the documentation. 587 588 Endpoints that support blocking queries return an HTTP header named 589 `X-Nomad-Index`. This is a unique identifier representing the current state of 590 the requested resource. On a new Nomad cluster the value of this index starts at 1. 591 592 On subsequent requests for this resource, the client can set the `index` query 593 string parameter to the value of `X-Nomad-Index`, indicating that the client 594 wishes to wait for any changes subsequent to that index. 595 596 When this is provided, the HTTP request will "hang" until a change in the system 597 occurs, or the maximum timeout is reached. A critical note is that the return of 598 a blocking request is **no guarantee** of a change. It is possible that the 599 timeout was reached or that there was an idempotent write that does not affect 600 the result of the query. 601 602 In addition to `index`, endpoints that support blocking will also honor a `wait` 603 parameter specifying a maximum duration for the blocking request. This is 604 limited to 10 minutes. If not set, the wait time defaults to 5 minutes. This 605 value can be specified in the form of "10s" or "5m" (i.e., 10 seconds or 5 606 minutes, respectively). A small random amount of additional wait time is added 607 to the supplied maximum `wait` time to spread out the wake up time of any 608 concurrent requests. This adds up to `wait / 16` additional time to the maximum 609 duration. 610 611 ## Consistency Modes 612 613 Most of the read query endpoints support multiple levels of consistency. Since 614 no policy will suit all clients' needs, these consistency modes allow the user 615 to have the ultimate say in how to balance the trade-offs inherent in a 616 distributed system. 617 618 The two read modes are: 619 620 - `default` - If not specified, the default is strongly consistent in almost all 621 cases. However, there is a small window in which a new leader may be elected 622 during which the old leader may service stale values. The trade-off is fast 623 reads but potentially stale values. The condition resulting in stale reads is 624 hard to trigger, and most clients should not need to worry about this case. 625 Also, note that this race condition only applies to reads, not writes. 626 627 - `stale` - This mode allows any server to service the read regardless of 628 whether it is the leader. This means reads can be arbitrarily stale; however, 629 results are generally consistent to within 50 milliseconds of the leader. The 630 trade-off is very fast and scalable reads with a higher likelihood of stale 631 values. Since this mode allows reads without a leader, a cluster that is 632 unavailable will still be able to respond to queries. 633 634 To switch these modes, use the `stale` query parameter on requests. 635 636 To support bounding the acceptable staleness of data, responses provide the 637 `X-Nomad-LastContact` header containing the time in milliseconds that a server 638 was last contacted by the leader node. The `X-Nomad-KnownLeader` header also 639 indicates if there is a known leader. These can be used by clients to gauge the 640 staleness of a result and take appropriate action. 641 642 ## Cross-Region Requests 643 644 By default, any request to the HTTP API will default to the region on which the 645 machine is servicing the request. If the agent runs in "region1", the request 646 will query the region "region1". A target region can be explicitly request using 647 the `?region` query parameter. The request will be transparently forwarded and 648 serviced by a server in the requested region. 649 650 ## Compressed Responses 651 652 The HTTP API will gzip the response if the HTTP request denotes that the client 653 accepts gzip compression. This is achieved by passing the accept encoding: 654 655 ```shell-session 656 $ curl \ 657 --header "Accept-Encoding: gzip" \ 658 https://localhost:4646/v1/... 659 ``` 660 661 ## Formatted JSON Output 662 663 By default, the output of all HTTP API requests is minimized JSON. If the client 664 passes `pretty` on the query string, formatted JSON will be returned. 665 666 In general, clients should prefer a client-side parser like `jq` instead of 667 server-formatted data. Asking the server to format the data takes away 668 processing cycles from more important tasks. 669 670 ```shell-session 671 $ curl https://localhost:4646/v1/page?pretty 672 ``` 673 674 ## HTTP Methods 675 676 Nomad's API aims to be RESTful, although there are some exceptions. The API 677 responds to the standard HTTP verbs GET, PUT, and DELETE. Each API method will 678 clearly document the verb(s) it responds to and the generated response. The same 679 path with different verbs may trigger different behavior. For example: 680 681 ```text 682 PUT /v1/jobs 683 GET /v1/jobs 684 ``` 685 686 Even though these share a path, the `PUT` operation creates a new job whereas 687 the `GET` operation reads all jobs. 688 689 ## HTTP Response Codes 690 691 Individual API's will contain further documentation in the case that more 692 specific response codes are returned but all clients should handle the following: 693 694 - 200 and 204 as success codes. 695 - 400 indicates a validation failure and if a parameter is modified in the 696 request, it could potentially succeed. 697 - 403 marks that the client isn't authenticated for the request. 698 - 404 indicates an unknown resource. 699 - 5xx means that the client should not expect the request to succeed if retried.