Skip to content

Document structure

# Document Structure

This section describes the structure of a JSON:API document, which is identified by the media type application/vnd.api+json. JSON:API documents are defined in JavaScript Object Notation (JSON) [RFC7159].

Although the same media type is used for both request and response documents, certain aspects are only applicable to one or the other. These differences are called out below.

Unless otherwise noted, objects defined by this specification MUST NOT contain any additional members. Client and server implementations MAY ignore members not recognized by this specification (if they are not ignored, the behaviour MUST be documented).

Note: These conditions allow this specification to evolve through additive changes.

# Top Level

A JSON object MUST be at the root of every JSON:API request and response containing data. This object defines a document's "top level".

A document MUST contain at least one of the following top-level members:

  • data: the document's "primary data"
  • errors: an array of error objects
  • meta: a meta object that contains non-standard meta-information.

The members data and errors MUST NOT coexist in the same document.

A document MAY contain any of these top-level members:

  • jsonapi: an object describing the server's implementation
  • links: a links object related to the primary data.
  • included: an array of resource objects that are related to the primary data and/or each other ("included resources").

If a document does not contain a top-level data key, the included member MUST NOT be present either.

The top-level links object MAY contain the following members:

  • self: the link that generated the current response document.
  • related: a related resource link when the primary data represents a resource relationship.
  • pagination links for the primary data.

The document's "primary data" is a representation of the resource or collection of resources targeted by a request.

Primary data MUST be either:

A single resource object MAY be represented by an array of size 1. For example, the following primary data is a single resource object:

{
  "data": {
    "type": "orders",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "attributes": {
      // ... this order's attributes
    },
    "relationships": {
      // ... this order's relationships
    }
  }
}

The following primary data is a single resource identifier object that references the same resource:

{
  "data": {
    "type": "orders",
    "id": "123e4567-e89b-12d3-a456-426614174000"
  }
}

A logical collection of resources MUST be represented as an array, even if it only contains one item or is empty.

{
  "data": [
    {
      "type": "orders",
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "attributes": {
        // ... this first order's attributes
      },
      "relationships": {
        // ... this first order's relationships
      }
    },
    {
      "type": "orders",
      "id": "1ecb023e-7ec0-6d5c-a477-0242ac170007",
      "attributes": {
        // ... this second order's attributes
      },
      "relationships": {
        // ... this second order's relationships
      }
    }
  ]
}

# Resource Objects

"Resource objects" appear in a JSON:API document to represent resources.

A resource object MUST contain at least the following top-level members:

  • id
  • type

Exception: The id member is not required when the resource object originates at the client and represents a new resource to be created on the server.

In addition, a resource object MAY contain any of these top-level members:

  • attributes: an attributes object representing some of the resource's data.
  • relationships: a relationships object describing relationships between the resource and other JSON:API resources.
  • links: a links object containing links related to the resource.
  • meta: a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.

Here's how an order (i.e. a resource of type "orders") might appear in a document:

// ...
{
  "type": "orders",
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "attributes": {
    "status": "invoiced",
    "shippedAt": "2022-03-17T15:05:19+00:00",
    "createdAt": "2022-03-13T16:36:24+00:00",
    "updatedAt": "2022-03-31T11:57:13+00:00",
    "shippingMethod": "ankorstore",
    [...]
  },
  "relationships": {
    "retailer": {
      "links": {
        "self": "/orders/123e4567-e89b-12d3-a456-426614174000/relationships/retailer",
        "related": "/retailers/1ecba0f4-adf0-6fbe-badf-9eb2e4c4d56c"
      },
      "data": { 
        "type": "retailer",
        "id": "1ecba0f4-adf0-6fbe-badf-9eb2e4c4d56c"
      }
    }
  }
}
// ...

# Identification

Every resource object MUST contain an id member and a type member.

The id member MUST be one of: - UUID v6, v7 or v8 (ordered time algorithm) - UUID v3 if the Id is uniquely derived from other properties of the entity. In this case ordering MUST be done on a different property than Id - a unique identifier that is part of a defined standard such as: Country code (ISO 3166-1 alpha-2), Language code (ISO 639-1) or Currency code (ISO 4217) etc.

The type member MUST be a string.

Within a given API, each resource object's type and id pair MUST identify a single, unique resource. (The set of URIs controlled by a server, or multiple servers acting as one, constitute an API.)

The type member is used to describe resource objects that share common attributes and relationships.

The values of type members MUST adhere to the same constraints as member names.

Note: This spec is agnostic about inflection rules, so the value of type can be either plural or singular. However, the same value should be used consistently throughout an implementation.

# Fields

A resource object's attributes and its relationships are collectively called its "fields".

Fields for a resource object MUST share a common namespace with each other and with type and id. In other words, a resource can not have an attribute and relationship with the same name, nor can it have an attribute or relationship named type or id.

# Attributes

The value of the attributes key MUST be an object (an "attributes object"). Members of the attributes object ("attributes") represent information about the resource object in which it's defined.

Attributes may contain any valid JSON value.

Complex data structures involving JSON objects and arrays are allowed as attribute values. However, any object that constitutes or is contained in an attribute MUST NOT contain a relationships or links member, as those members are reserved by this specification for future use.

Although has-one foreign keys (e.g. order_id) are often stored internally alongside other information to be represented in a resource object, these keys SHOULD NOT appear as attributes.

Note: See fields and member names for more restrictions on this container.

# Relationships

The value of the relationships key MUST be an object (a "relationships object"). Members of the relationships object ("relationships") represent references from the resource object in which it's defined to other resource objects.

Relationships may be to-one or to-many.

# A "relationship object" MUST contain at least one of the following:

  • links: a links object containing at least one of the following:
    • self: a link for the relationship itself (a "relationship link"). This link allows the client to directly manipulate the relationship. For example, removing a retailer through an order's relationship URL would disconnect the person from the order without deleting the retailer resource itself. When fetched successfully, this link returns the linkage for the related resources as its primary data. (See Fetching Relationships.)
    • related: a related resource link
  • data: resource linkage
  • meta: a meta object that contains non-standard meta-information about the relationship.

A relationship object that represents a to-many relationship MAY also contain pagination links under the links member, as described below. Any pagination links in a relationship object MUST paginate the relationship data, not the related resources.

Note: See fields and member names for more restrictions on this container.

A "related resource link" provides access to resource objects linked in a relationship. When fetched, the related resource object(s) are returned as the response's primary data.

For example, a retailer's orders relationship could specify a link that returns a collection of order resource objects when retrieved through a GET request.

If present, a related resource link MUST reference a valid URL, even if the relationship isn't currently associated with any target resources. Additionally, a related resource link MUST NOT change because its relationship's content changes.

# Resource Linkage

Resource linkage in a compound document allows a client to link together all of the included resource objects without having to GET any URLs via links.

Resource linkage MUST be represented as one of the following:

Note: The spec does not impart meaning to order of resource identifier objects in linkage arrays of to-many relationships, although implementations may do that. Arrays of resource identifier objects may represent ordered or unordered relationships, and both types can be mixed in one response object.

For example, the following order is associated with a retailer:

// ...
{
  "type": "orders",
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "attributes": {
    "status": "invoiced"
  },
  "relationships": {
    "retailer": {
      "links": {
        "self": "/orders/123e4567-e89b-12d3-a456-426614174000/relationships/retailer",
        "related": "/orders/123e4567-e89b-12d3-a456-426614174000/retailer"
      },
      "data": { 
        "type": "retailers",
        "id": "1ecba0f4-adf0-6fbe-badf-9eb2e4c4d56c"
      }
    }
  },
  "links": {
    "self": "/orders/123e4567-e89b-12d3-a456-426614174000"
  }
}
// ...

The retailer relationship includes a link for the relationship itself (which allows the client to change the related retailer directly), a related resource link to fetch the resource objects, and linkage information.

The optional links member within each resource object contains links related to the resource.

If present, this links object MAY contain a self link that identifies the resource represented by the resource object.

// ...
{
  "type": "orders",
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "attributes": {
    "status": "invoiced"
  },
  "links": {
    "self": "/orders/123e4567-e89b-12d3-a456-426614174000"
  }
}
// ...

A server MUST respond to a GET request to the specified URL with a response that includes the resource as the primary data.

# Resource Identifier Objects

A "resource identifier object" is an object that identifies an individual resource.

A "resource identifier object" MUST contain type and id members.

A "resource identifier object" MAY also include a meta member, whose value is a meta object that contains non-standard meta-information.

# Compound Documents

To reduce the number of HTTP requests, servers MAY allow responses that include related resources along with the requested primary resources. Such responses are called "compound documents".

In a compound document, all included resources MUST be represented as an array of resource objects in a top-level included member.

Compound documents require "full linkage", meaning that every included resource MUST be identified by at least one resource identifier object in the same document. These resource identifier objects could either be primary data or represent resource linkage contained within primary or included resources.

The only exception to the full linkage requirement is when relationship fields that would otherwise contain linkage data are excluded via sparse fieldsets.

Note: Full linkage ensures that included resources are related to either the primary data (which could be resource objects or resource identifier objects) or to each other.

An example document with one included relationship:

{
  "jsonapi": {
    "version": "1.0"
  },
  "data": {
    "type": "orders",
    "id": "1ecb023e-7ec0-6d5c-a477-0242ac170009",
    "attributes": {
      "status": "invoiced"
    },
    "links": {
      "self": "/orders/1ecb023e-7ec0-6d5c-a477-0242ac170009"
    },
    "relationships": {
      "retailer": {
        "links": {
          "self": "/orders/1ecb023e-7ec0-6d5c-a477-0242ac170009/relationships/retailer",
          "related": "/retailers/3b656e82-0260-1ecb-9e4c-0242ac170007"
        },
        "data": { "type": "retailer", "id": "3b656e82-0260-1ecb-9e4c-0242ac170007" }
      }
    }
  },
  "included": [
    {
      "type": "retailer",
      "id": "3b656e82-0260-1ecb-9e4c-0242ac170007",
      "attributes": {
        "storeName": "TEST RETAILER"
      }
    }
  ]
}

A complete example document with multiple included relationships:

{
  "jsonapi": {
    "version": "1.0"
  },
  "data": [
    {
      "type": "orders",
      "id": "1ecb023e-7ec0-6d5c-a477-0242ac170009",
      "attributes": {
        "status": "invoiced"
      },
      "links": {
        "self": "/orders/1ecb023e-7ec0-6d5c-a477-0242ac170009"
      },
      "relationships": {
        "retailer": {
          "links": {
            "self": "/orders/1ecb023e-7ec0-6d5c-a477-0242ac170009/relationships/retailer",
            "related": "/retailers/3b656e82-0260-1ecb-9e4c-0242ac170007"
          },
          "data": { "type": "retailer", "id": "3b656e82-0260-1ecb-9e4c-0242ac170007" }
        }
      }
    },
    {
      "type": "orders",
      "id": "1596910c-94be-445d-8623-cc033b7bff0a",
      "attributes": {
        "status": "invoiced"
      },
      "links": {
        "self": "/orders/1596910c-94be-445d-8623-cc033b7bff0a"
      },
      "relationships": {
        "retailer": {
          "links": {
            "self": "/orders/1596910c-94be-445d-8623-cc033b7bff0a/relationships/retailer",
            "related": "/retailers/fd8710ec-22e4-11ed-861d-0242ac120002"
          },
          "data": { "type": "retailer", "id": "fd8710ec-22e4-11ed-861d-0242ac120002" }
        }
      }
    }
  ]
  "included": [
    {
      "type": "retailer",
      "id": "3b656e82-0260-1ecb-9e4c-0242ac170007",
      "attributes": {
        "storeName": "TEST RETAILER 1"
      }
    },
    {
      "type": "retailer",
      "id": "fd8710ec-22e4-11ed-861d-0242ac120002",
      "attributes": {
        "storeName": "TEST RETAILER 2"
      }
    }
  ]
}

A compound document SHOULD NOT include more than one resource object for each type and id pair.

Note: In a single document, you can think of the type and id as a composite key that uniquely references resource objects in another part of the document.

Note: This approach ensures that a single canonical resource object is returned with each response, even when the same resource is referenced multiple times.

# Meta Information

Where specified, a meta member can be used to include non-standard meta-information. The value of each meta member MUST be an object (a "meta object").

Any members MAY be specified within meta objects.

For example:

{
  "meta": {
    "page": {
      "from": "123e4567-e89b-12d3-a456-426614174000",
      "hasMore": true,
      "perPage": 2,
      "to": "1ecb023e-7ec0-6d5c-a477-0242ac170008"
    }
  },
  "data": {
    // ...
  }
}

Where specified, a links member can be used to represent links. The value of each links member MUST be an object (a "links object").

Each member of a links object is a "link". A link MUST be represented as either:

  • a string containing the link's URL.
  • an object ("link object") which can contain the following members:
    • href: a string containing the link's URL.
    • meta: a meta object containing non-standard meta-information about the link.

The following self link is simply a URL:

"links": {
  "self": "http://example.com/posts"
}

The following related link includes a URL as well as meta-information about a related resource collection:

"links": {
  "related": {
    "href": "http://example.com/orders/1/comments",
    "meta": {
      "count": 10
    }
  }
}

Note: Additional members may be specified for links objects and link objects in the future. It is also possible that the allowed values of additional members will be expanded (e.g. a collection link may support an array of values, whereas a self link does not).

# JSON:API Object

A JSON:API document MAY include information about its implementation under a top level jsonapi member. If present, the value of the jsonapi member MUST be an object (a "jsonapi object"). The jsonapi object MAY contain a version member whose value is a string indicating the highest JSON API version supported. This object MAY also contain a meta member, whose value is a meta object that contains non-standard meta-information.

{
  "jsonapi": {
    "version": "1.0"
  }
}

If the version member is not present, clients should assume the server implements at least version 1.0 of the specification.

Note: Because JSON:API is committed to making additive changes only, the version string primarily indicates which new features a server may support.

# Member Names

All member names used in a JSON:API document MUST be treated as case sensitive by clients and servers, and they MUST meet all of the following conditions:

  • Member names MUST contain at least one character.
  • Member names MUST contain only the allowed characters listed below.
  • Member names MUST start and end with a "globally allowed character", as defined below.

To enable an easy mapping of member names to URLs, it is RECOMMENDED that member names use only non-reserved, URL safe characters specified in RFC 3986.

# Allowed Characters

The following "globally allowed characters" MAY be used anywhere in a member name:

  • U+0061 to U+007A, "a-z"
  • U+0041 to U+005A, "A-Z"
  • U+0030 to U+0039, "0-9"

Additionally, the following characters are allowed in member names, except as the first or last character:

  • U+002D HYPHEN-MINUS, "-"
  • U+005F LOW LINE, "_"

# Reserved Characters

All characters not specified in allow-list above MUST NOT be used in member names. This includes e.g.:

  • U+002B PLUS SIGN, "+" (used for ordering)
  • U+002C COMMA, "," (used as a separator between relationship paths)
  • U+002E PERIOD, "." (used as a separator within relationship paths)
  • U+005B LEFT SQUARE BRACKET, "[" (used in sparse fieldsets)
  • U+005D RIGHT SQUARE BRACKET, "]" (used in sparse fieldsets)