Introduction
The Ditto HTTP API follows a RESTful pattern and is organized into several resources. API Resources typically map to the key elements of the Ditto Data Model. Applications may contain one or more Collection
s of Documents
or TimeSeries
of Event
s. JSON is used as the default representation for individual resources, and will be indicated by the Content-Type
HTTP Header. Resources which are best represented by a sequence or stream of items are represented by JSONlines, that is new line delimited JSON. This will be indicated by the MIME type application/json-l
. UTF-8 encoding is used and required unless otherwise indicated. Binary data should be Base64 encoded. Where alternative representations are desired, the API Client may use the Accept
HTTP Header to indicate this in the Request.
Introduction
For simple examples for using the HTTP API for document storage, see the corresponding sections in the Concepts section for querying, writing, and remove. Ditto Big Peer also provides HTTP APIs for querying timeseries data. See the timeseries section for more information.
Endpoint
The Ditto HTTP API provides a programmatic interface for interactions with
Ditto-powered Apps which expose an HTTP Server Interface. A primary use case for
the HTTP API is external systems which integrate with cloud.ditto.live
.
The canonical root URL for the HTTP API can be found in your app's page on the Ditto Portal. The standard port 443 is used.
curl https://{app_id}.cloud.ditto.live/api/v4
Authorization
Access to the Ditto HTTP API is mediated by an Authorization: Bearer
HTTP
Header. There are two ways to authorize access: via a JWT (JSON Web Token) or a static API Key.
API Key
Long-lived API tokens are great for server-side hydration, which are not owned by a particular user. These API keys can be obtained and managed through the portal in the "API Key" section.
You can give each API key its own read and write permissions, scoped to particular collections or document ids.
info
Currently, you can only specify a permission query on the _id field of a document. Mutable properties are currently not supported. We are working on adding this feature.
Once you have your API Key, you can use it as part of the Authorization: Bearer
HTTP header in subsequent HTTP requests.
curl --location --request POST 'https://{YOUR_APP_ID}.cloud.ditto.live/api/v4/store/write' \--header 'Authorization: Bearer {YOUR_API_KEY}' \--header 'Content-Type: application/json' \--data-raw '{ "commands": [{ "method": "upsert", "collection": "people", "value": { "name": "Susan", "age": 31 } }] }'
Security
The API key is formed by three parts: randomly generated prefix, fixed prefix and randomly generated suffix.
The value is generated through cryptographically secure PRNG. The suffix is hashed using scrypt
before
being stored in database along with the prefix. The unhashed API key will only be shown once in the portal and
will be inaccessible after creation.
Apart from that, an approximate of the timestamp when the API key is last used is tracked and is available in the portal.
JWT (JSON Web Token)
There are specific cases where a broad, long-lived HTTP API key is not the right authorization mechanism. For user-scoped credentials, you can use a JWT retrieved from Online With Authentication to secure your HTTP endpoint. To retrieve a JWT for a particular user, send a POST request to the Big Peer with the given provider and the user's token.
- First, set your application to enable Authentication using OnlineWithAuthentication. This involves deploying an authentication server on a publicly-accessible URL by following the tutorial.
- Send a POST request to the
/_ditto/auth/login
endpoint. This is the same endpoint used to authorize small peers access, used by theOnlineWithAuthentication
identity.
curl --location \ --request POST '{YOUR_APP_ID}.cloud.ditto.live/_ditto/auth/login' \ --data-raw 'appId={YOUR_APP_ID}&provider={YOUR_PROVIDER}&token={USER_TOKEN}&siteId=1'
- The following payload will be returned. Extract the
accessToken
value. You can use theaccessExpiry
value in your application code to handle the expiration date and refresh of the token.
{ "result": "success", "userId": "...", "identityB64": "..." "accessToken": "MY_ACCESS_TOKEN" "accessExpiry": "YYYY-MM-DDT00:00:00.0000000Z", "refreshToken": null, "refreshExpiry": null, "audiences": [ "sync" ], "clientInfo": null}
- Once you have this token, you can use it as part of the
Authorization: Bearer
HTTP header in subsequent requests (as seen in the previous section).
Errors
Ditto HTTP API errors are indicated with an HTTP Status Code and with a JSON response body containing an object with a single "error" key. This Error object contains the following fields:
- error.code - The HTTP Status Code for
- error.message - A short description of the error
- error.data - An optional object which contains further elaboration about the error
In some cases such as a Bad Gateway or Request Timeout only a plain text error
or {"message": "Request Timeout"}
JSON object is returned.
Transactions
A successful response to POST or DELETE requests will include a Transaction ID, which can be used on subsequent GET requests. This type of insertion is non-blocking and so is very performant.
Each HTTP API write request represents a distinct transaction which may be one
or many operations (e.g., upsert or remove). Because Ditto is also a distributed
system, Transaction ID
s are used to represent the order in which transactions
should be applied. Each write request returns its associated Transaction ID
.
GET requests can optionally specify a Transaction ID in an HTTP
HEADER called X-DITTO-TXN-ID
. This header will instruct the
server to wait until the given transaction is applied before executing the
query. The newly inserted events may still be replicating through the Ditto mesh
between the time of the write and the time of the find request. If you don't supply this header, the default behavior is to use the
most recent version common to all Ditto nodes. If the Ditto node
servicing the Request can't supply the version of the data requested, an error
will be returned.
For example, you write data using the HTTP API and get back Transaction 17. If
you want to ensure that the values included in Transaction included in our
subsequent query, we would include the header X-DITTO-TXN-ID: 17
in the next request.
Note: the HTTP API will return an error when the requested DITTO-TXN-ID is not yet available on the server.