Synthesio API Format
Introduction
Synthesio API is a specification for how a client should request that resources be fetched or modified, and how a server should respond to those requests.
Conventions
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 [RFC2119].
Content Negotiation
Client Responsibilities
Clients MUST send all API data in request documents with the header
Content-Type: application/json
without any media type parameters.
Clients MUST ignore any parameters for the application/json
media type received in the Content-Type
header of response documents.
Server Responsibilities
Servers MUST send all API data in response documents with the header
Content-Type: application/json
without any media type parameters.
Servers MUST respond with a 415 Unsupported Media Type
status code if
a request specifies the header Content-Type: application/json
with any media
type parameters.
Document Structure
Synthesio API documents are defined in JavaScript Object Notation (JSON) [RFC7159].
Top Level
A JSON object MUST be at the root of every Synthesio 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 objectsmeta
: a meta object that contains non-standard meta-information.
The members data
and errors
MAY coexist in the same document. In this case,
errors can refer to only a part of the requested operation or be warnings.
A document MAY also contain this top-level member:
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 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 or
null
, for requests that target single resourcestan array of resource objects, an array of resource identifier, or an empty array (
[]
), for requests that target resource collections
A logical collection of resources MUST be represented as an array, even if it only contains one item or is empty.
Resource Identifiers
A “resource identifier” is an unique resource identifier for a given object type. It MUST be a JSON string.
Resource Objects
“Resource objects” appear in a Synthesio API document to represent resources.
A resource object MUST contain at least the following top-level member:
id
, the resource identifier
Exceptions
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.The
id
member is not required when the response data is the result of an action, as it does not represent a resource object.
In addition, a resource object MAY contain any additional attributes as top-level members.
Relationships can be either expanded as an object in the attributes or a reference to a resource
identifier. If so the attribute name MUST have the _id
suffix. API documentation must
explicitly define if relationships are given by references or directly expanded.
For one-to-many relationships, the attribute name MUST not change from singular to plural and
MUST use the suffix _list
. An attribute with this suffix SHOULD be an array of objects.
An attribute with the suffix _list_id
SHOULD be an array of strings containing
resource identifiers.
Attributes
Attributes may contain any valid JSON value.
Complex data structures involving JSON objects and arrays are allowed as attribute values.
Special suffixes:
_id
can be used to reference related resources identifiers, if so, it must be considered as foreign key._list
can be used to indicate a one-to-many (or a many-to-many) relationship, if so value MUST be an array of objects._list_id
can be used to reference related resources identifiers, if so, it MUST be an array of strings._id_list
SHOULD NOT be used to avoid confusion.
These _id
references MAY or MAY NOT be included as related resources.
Resource Linkage
Resource linkage in a compound document allows a client to link together all of the included resource objects without having to request any other URLs.
Resource linkage MUST be represented as one of the following:
null
for empty to-one relationships.an empty array (
[]
) for empty to-many relationships.a single resource identifier for non-empty to-one relationships.
an array of resource identifier for non-empty to-many relationships.
For example, the following dashboard is associated with a client
, and various report
s, but is
not associated with any workspace
.
// ...
{
"id": "1",
"title": "Synthesio Dashboard",
"client": {
"id": "1",
"name": "Synthesio"
},
"workspace_id": null,
"report_list_id": [
"1",
"2"
]
}
// ...
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 named by the resource type in
the top-level included
object.
Resource array type MUST be named with the same name without _list
and _id
suffixes.
Compound documents require “full linkage”, meaning that every included resource MUST be identified by at least one resource identifier in the same document. These resource identifiers 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 or included resources limitations.
A complete example document with multiple included relationships, for an URI that return objects of the
dashboard
type:
{
"data": [{
"id": "1",
"title": "Synthesio Dashboard",
"client": {
"id": "1",
"name": "Synthesio"
},
"workspace_id": "50",
"report_list_id": [
"2",
"3"
]
}],
"included": {
"report": [
{
"id": "2",
"name": "Synthesio main report"
},
{
"id": "3",
"name": "Synthesio other report"
}
],
"workspace": [
{
"id": "50",
"name": "Synthesio workspace"
}
]
}
}
A compound document MUST NOT include more than one resource object for
an id
for a given type.
Meta Information
Where specified, API responses can have a meta
member 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": {
"copyright": "Copyright 2015 Example Corp.",
},
"data": {
// ...
}
}
Member Names
All member names used in a Synthesio 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+0030 to U+0039, “0-9”
U+0080 and above (non-ASCII Unicode characters; not recommended, not URL safe)
Additionally, the following characters are allowed in member names, except as the first or last character:
U+002D HYPHEN-MINUS, “-”
U+005F LOW LINE, “_”
U+0020 SPACE, “ “ (not recommended, not URL safe)
Reserved Characters
The following characters MUST NOT be used in member names:
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)
U+0021 EXCLAMATION MARK, “!”
U+0022 QUOTATION MARK, ‘”’
U+0023 NUMBER SIGN, “#”
U+0024 DOLLAR SIGN, “$”
U+0025 PERCENT SIGN, “%”
U+0026 AMPERSAND, “&”
U+0027 APOSTROPHE, “’”
U+0028 LEFT PARENTHESIS, “(”
U+0029 RIGHT PARENTHESIS, “)”
U+002A ASTERISK, “*”
U+002F SOLIDUS, “/”
U+003A COLON, “:”
U+003B SEMICOLON, “;”
U+003C LESS-THAN SIGN, “<”
U+003D EQUALS SIGN, “=”
U+003E GREATER-THAN SIGN, “>”
U+003F QUESTION MARK, “?”
U+0040 COMMERCIAL AT, “@”
U+005C REVERSE SOLIDUS, “”
U+005E CIRCUMFLEX ACCENT, “^”
U+0060 GRAVE ACCENT, “`”
U+007B LEFT CURLY BRACKET, “{”
U+007C VERTICAL LINE, “|”
U+007D RIGHT CURLY BRACKET, “}”
U+007E TILDE, “~”
U+007F DELETE
U+0000 to U+001F (C0 Controls)
Fetching Data
Fetching resources
Standard resources data, including relationships, can be fetched by sending a
GET
request to an endpoint.
Responses can be further refined with the optional features described in responses section.
POST fallback for long URLs
GET
endpoints MUST accept request as a POST
, specifying in the payload at
top level a _method
attribute with value GET
and a _parameters
attribute
with the url encoded query string. This allow to avoid potential problems
when reaching URL length limits with optional parameters.
When sending a POST
request without the method
attribute, the server will understand
the request as a POST
.
For example these two requests MUST give the same result:
GET /dashboards/1 HTTP/1.1
POST /dashboards/1 HTTP/1.1
Content-Type: application/json
{
"_method": "GET",
"_parameters": "size=10&some_parameter=value"
}
Fetching action’s results
Data produced as the result of an action MUST be fetched by sending a POST
request. Action routes MUST use the _
prefix in their last URL component
name.
Example:
POST /mention/v2/reports/15/_search HTTP/1.1
Content-Type: application/json
Responses
200 OK
A server MUST respond to a successful request to fetch an individual
resource or resource collection with a 200 OK
response.
A server MUST respond to a successful request to fetch a resource
collection with an array of resource objects or an empty array ([]
) as
the response document’s primary data.
For example, a GET
request to a collection of articles could return:
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": [{
"id": "1",
"title": "Synthesio API paints my bikeshed!"
},
{
"id": "2",
"title": "Rails is Omakase"
}]
}
A similar response representing an empty collection would be:
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": []
}
A server MUST respond to a successful request to fetch an individual
resource with a resource object or null
provided as
the response document’s primary data.
null
is only an appropriate response when the requested URL is one that
might correspond to a single resource, but doesn’t currently.
For example, a GET
request to an individual article could return:
Request: /articles/1
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"id": "1",
"title": "Synthesio API paints my bikeshed!",
"author_id": "1"
}
}
If the above article’s author is missing, then a GET
request to that related
resource would return:
Request: /articles/1/author
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": null
}
404 Not Found
A server MUST respond with 404 Not Found
when processing a request to
fetch a single resource that does not exist, except when the request warrants a
200 OK
response with null
as the primary data (as described above).
Other Responses
A server MAY respond with other HTTP status codes.
A server MAY include error details with error responses.
A server MUST prepare responses, and a client MUST interpret
responses, in accordance with
HTTP semantics
.
Sparse Fieldsets
A client MAY request that an endpoint return only specific fields in the
response on a per-type basis by including a fields[TYPE]
parameter.
The value of the fields
parameter MUST be a comma-separated (U+002C
COMMA, “,”) list that refers to the name(s) of the fields to be returned.
If a client requests a restricted set of fields for a given resource type, an endpoint MUST NOT include additional fields in resource objects of that type in its response.
POST /reports/1/_search?fields[mention]=title,content&fields[author]=full_name HTTP/1.1
Accept: application/json
Errors
Processing Errors
A server MAY choose to stop processing as soon as a problem is encountered, or it MAY continue processing and encounter multiple problems. For instance, a server might process multiple attributes and then return multiple validation problems in a single response.
When a server encounters multiple problems for a single request, the most
generally applicable HTTP error code SHOULD be used in the response. For
instance, 400 Bad Request
might be appropriate for multiple 4xx errors
or 500 Internal Server Error
might be appropriate for multiple 5xx errors.
Error Objects
Error objects provide additional information about problems encountered while
performing an operation. Error objects MUST be returned as an array
keyed by errors
in the top level of a Synthesio API document.
An error object MAY have the following members:
id
: a unique identifier for this particular occurrence of the problem.status
: the HTTP status code applicable to this problem, expressed as a string value.code
: an application-specific error code, expressed as a string value.title
: a short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.detail
: a human-readable explanation specific to this occurrence of the problem. Liketitle
, this field’s value can be localized.meta
: a meta object containing non-standard meta-information about the error.