2.5 HTTP Headers

2.5.1 Request Headers

Request headers are supplied by the consuming application and must include the following elements:

  • Accept
  • Content Type
  • Authorization

Header definitions can be found in RFC2616

2.5.1.1 Accept

REQUIRED

An Accept header is required to indicate what format the consuming application wants the information to be returned as (e.g. JSON or XML). It is preferable for the consuming application to specify the response content type that they expect, however it is acceptable to use the ‘q’ parameter to specify the quality of support.

Examples

#Accept JSON and latest version

Accept: application/json,version=*

#Prefer JSON, Accept XML and latest version 1 release

Accept: application/json;q=1.0,application/xml;q=0.8,version=1.*

#Accept XML only and version 1.2 only

Accept: application/xml;q=1.0,application/json;q=0.0,version=1.2

If the client has specified via the Accept header that it doesn’t support any formats provided by the API, the server should return an HTTP 406 Not Acceptable response. The response should also include a Link header with a link to documentation or help on supported formats. The body of the representation should include an error message in human readable plain text or HTML.

Example Response

# Response that indicates the request failed due to the client not

# supporting any response formats provided by the API

HTTP/1.1 406 Not Acceptable

Content-Type: text/plain

 

This API does not support any of the requested content types specified in the HTTP Accept header. Please see http://www.example.com/api/documentation/widgetservice for details on the supported content types.

The Accept header is required, however the ‘version’ and ‘q’ are recommended as this will depend on a provider’s implementation and in some cases technology choice.

2.5.1.2 Content-Type

REQUIRED

The Content-Type header is required for all requests that include a request body i.e. POST, PUT, DELETE.

Example

#PUT https://api.example.govt.nz/v2/learners/33245

 

Accept: application/json,version=1.*

Content-Type: application/json

Authorization: Bearer x6TLB4JaomezC5rJ3CIl3KxxNinq

{

         "id": "33245",

         "names":

         {

                 "firstName": "John",

                 "middleName": "Howard",

                 "lastName": "Doe",

                 "salutation": "Mr John Doe",

                 "title": "Mr"

                 },

         "addresses": [

                 {

                          "type": "home",

                          "address1": "1 Some Street",

                          "address2": "Some Suburb",

                          "address3": "Some City",

                          "address4": null,

                          "country": "New Zealand",

                          "postcode": 1111

                 },

                 {

                          "type": "business",

                          "address1": "2 Work Street",

                          "address2": "Work Suburb",

                          "address3": "Work City",

                          "address4": null,

                          "country": "New Zealand",

                          "postcode": 2222

                 }

         ],

         "qualifications":[

                 {

                          "id": "1a4rf54ee345",

                          "type": "Some type",

                          "provider": "University of life",

                          "providerId": "0o9i8u7y6tt"

                 },

                 {

                          "id": "8u7y6t5r4ee",

                          "type": "Another type",

                          "provider": "School xyz",

                          "providerId": "1q2w3e4r5tt"

                 }

         ]

}

 

2.5.1.3 Authorization

REQUIRED

Most API requests will be authorised. The Authorization header should be used for this purpose and no other. Note that the Authorization header is not the best place for an API Key.

The Authorization header is comprised of a type and a token depending on the authorization type.

Example

#OAuth Access Token

Authorization: Bearer x6TLB4JaomezC5rJ3CIl3KxxNinq

 

#HTTP Basic

Authorization: Basic c29tZXVzZXI6c29tZSBwYXNzd29yZA==

 

2.5.1.4 Accept-Encoding

RECOMMENDED

In some cases, especially where API responses are very large, it may be worth compressing HTTP responses. (Note: where possible it is best to avoid large payloads in API responses; however, this may not always be possible.) An Accept-Encoding value of gzip instructs a provider that supports HTTP compression that the consuming application supports compressed responses.

Example

Accept-Encoding: gzip,deflate

 

2.5.1.5 API Key Header

REQUIRED

An API key issued to a consuming application should be sent with every request made to the API. The name of the header is up to the agency, but it should not be an X- prefixed header as this use is deprecated (see 2.5.3). Sometimes API keys are passed in URIs; however, this is not considered best practice and should be avoided.

Example

KeyID: pX680LyiKasUBWLuZJ8AVBHVQK03Ghtr

 

2.5.1.6 If-Modified-Since/If-None-Match

RECOMMENDED

The If-Modified header is a pre-condition header used to instruct a client on the validity of the resource requested. Note that pre-condition handling is not required, but where appropriate should be considered. Pre-condition control can be a complex topic so in some cases the complexity may eclipse the value.

Conditional header standards are available in Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests RFC7232.

A consuming application can specify an If-Modified-Since header with a date and time. The server checks the resource to see the last modified time. If the last modification was before the date/time specified in the header, the server will respond with an HTTP 304 status code telling the consuming application that the resource they requested has not changed and therefore there is no need to return the full payload in the response.

When using If-Modified headers you should also implement ETag as discussed in the response headers section (2.5.2.6).

Example

# Request with If-Modified-Since and If-None-Match headers

If-Modified-Since: Wed, 18 Jun 2016 22:00:00 GMT

If-None-Match: "686897696a7c876b7e"

The If-None-Match header indicates to the provider the ETag for the resource that it currently holds for that resource.

Example Response

# Response that indicates the client’s current representation is still

# valid

HTTP/1.1 304 Not Modified

ETag: "686897696a7c876b7e"

Content-Length: 0

 

2.5.1.7 Request tracking headers

RECOMMENDED

To support the tracking of API requests it is a good idea to apply a transaction ID header that will enable analysts to trace a request throughout its lifecycle. Note: there is no set naming standard for a transaction ID header.

There are two common approaches to this: one is to request that the consuming application generate a unique transaction ID and the provider will capture it and respond with a corresponding correlation ID; the second is to allow the provider to generate the transaction ID as close to the edge of its domain as possible, and respond to the consuming application with that transaction ID. In this case a consuming application administrator or developer should capture and log that transaction ID for audit purposes so that it can be relayed to agency analysts if required.

Example Request

#Request that includes a consuming application generated transaction

#ID

Request-Transaction-Id: c188cb0e-1a09-4184-890c-0f0bb2255425

Example Response

#Response to a consuming application that provided a client generated #transaction ID

Request-Transaction-Id: c188cb0e-1a09-4184-890c-0f0bb2255425

Response-Correlation-Id: 514dbf50-4475-4e4d-86ee-e2001f158026

#Response to a consuming application where there was no client #generated transaction ID

#Note that the server has generated the transaction ID

Response-Correlation-Id: c188cb0e-1a09-4184-890c-0f0bb2255425

 

2.5.2 Response Headers

Response headers are supplied by the provider and must contain Content-Type.

2.5.2.1 Content-Type

REQUIRED

The Content-Type must be returned in the response, and indicate the format type the response content is in e.g. Content-Type: application/json. The Content-Type header should also include the version of the API that processed the request e.g. Content-Type: application/json,version=1.1

2.5.2.2 Location

RECOMMENDED

Where a new resource item has been created (POST), the server should respond with a 201 Created HTTP header and a Location header indicating the URI of the newly created resource item e.g. Location: https://api.example.govt.nz/v1/crown-property/198373

A location header should also be returned by a server when it sends a 3** HTTP response, indicating a temporary or permanent redirection.

A location header can be, as recommended by this standard, absolute e.g. Location: https://api.example.govt.nz/v1/crown-property/198373 or relative e.g. Location: /v1/crown-property/198373 

2.5.2.3       Content-Location

RECOMMEDED

The Content-Location header indicates the location of the requested resource. It should be an absolute and not a relative link.

Example

#GET https://api.example.govt.nz/v1/crown-property/198373

Content-Type: application/json

Content-Location: https://api.example.govt.nz/v1/crown-property/198373

{

  "propertyid": 12345,

  "address1": "1 Some Street",

  "address2": "Some Suburb",

  "address3": "Some City",

  "address4": null,

  "country": "New Zealand",

  "postcode": 1111,

  "type": "commercial"

}

2.5.2.4 Cache-Control

RECOMMENDED

It is important to consider caching when designing APIs, to ensure that the APIs you build can perform at scale. The Cache-Control header is only concerned with caching that occurs externally to the API layer. Common examples may be client side caching or caching within a Content Delivery Network (CDN). This header should not be concerned with caching mechanisms within the API layer such as response caches or object caches, which require a different caching strategy (see section 2.11).

The Cache-Control header is comprised of the following

private|public: This indicates if the cache is specific to the consumer or not – a setting of private will prevent the cache from being persisted in a public cache.

no-cache: This instructs a cache to revalidate the resource every time.

no-store: This instructs a cache not to store the response. It also ensures that no part of the request is stored too.

max-age: This instructs the cache on expiry time. This can be used but it makes more sense to use the Expires header discussed below.

s-max-age: Similar to the above, however it refers to a shared cache hence only relevant to CDNs and other intermediary caches.

must-revalidate: This instructs the client to resend request headers and receive confirmation that the resource has not changed.

proxy-revalidate: Similar to the above, however specific to shared caches.

Example

# Example caching response

HTTP/1.1 200 OK

Date: Wed, 06 Jul 2016 21:14:52 GMT

Expires: Wed, 06 Jul 2016 22:14:52 GMT

Cache-Control: private,max-age=14400,must-revalidate

Content-Type: application/json

Care should be taken when using caches, especially shared or public caches. In some cases it may be more prudent to use the no-cache directive to ensure that content is not cached outside your network. This does not rule out caching within your API layer. For more information on API caching please see section 2.11.

HTTP Cache Control standards can be found in Hypertext Transfer Protocol (HTTP/1.1): Caching RFC7234[9]

2.5.2.5 Expires

RECOMMENDED

When using Cache-Control you should include an Expires header in the response for backward compatibility.

2.5.2.6 ETag (Entity Tag)

RECOMMNEDED

The ETag header is a concurrency control header, and when in a response it is a tag that the consuming application can use when making a subsequent request to a resource. Note that pre-condition handling is not required, but where appropriate should be considered. Pre-condition control can be a complex topic so in some cases the complexity may eclipse the value.

# Response with ETag Header

# Consuming application would send this ETag in an If-None-Match #request header

ETag: "686897696a7c876b7e"

2.5.3 Custom X- HTTP Headers

X- notation headers have been deprecated as per RFC6648[10] and should not be used. This is because the X- name often became a standard, making the X-notation inaccurate (e.g. x-gzip became gzip) and requiring support for both the X- and the non-X- notation. Common uses of the X- headers are examples such as the X-HTTP-Method-Override header or the X-Forwarded-For header.

Where an agency feels that a custom HTTP header is required that is not available within the current HTTP standard they can use a custom header without the X- prefix.

Page last updated: 18/12/2016