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  [![Nomad Data Model](/img/nomad-data-model.png)](/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.