The Developers' Guide is targeted at developers and people with technical background who are already a partner of OTTO Market or are interested in becoming a partner. The aim is to help you as a partner of OTTO Market to connect to and to work with the OTTO Partner API. It describes some common implementation patterns and helps you to understand how processes work. Detailed information about the concrete interfaces can be accessed by clicking onto the single tabs.
The following documentation describes how to use the API in technical terms.
In order to fetch an authorization token you must have an API user with a password.
You can use the following cURL command to receive your token. Make sure you include your
username and password in the command (without leading and trailing < >).
curl -X POST \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'cache-control: no-cache' \
The response of the request will look like the following example.
The token itself can be extracted from the
"scope": "pumba-roles-app-portal partner email profile"
When you decode the access token you will see information including your email, name and roles as well as usual token metadata:
"scope": "openid pumba-roles-app-portal partner email profile",
"name": "Example User",
All endpoints are secured via authorization. You add the HTTP
-Header with value
Bearer ey... and will get access.
curl -X GET \
The expected result has an HTTP 200 code with a probably empty list.
Requests are limited to 10 requests per second and client.
|request timeout||25s||The maximum HTTP request timeout for all interfaces|
|limit||128||The default for limit query parameter. See Paging. The default limit can be overwritten in specific interfaces.|
Our REST interface definitions are basically using swagger.io. All interface definitions can be automatically used by you to generate necessary API objects and similar in your chosen implementation language. In order to remain technically extensible and up-to-date, individual interfaces may have been described in new or different definition schemes. We are constantly trying to keep all interfaces technically up to date.
The OTTO Partner API uses different versions for the single endpoints. The version number is included in the URL path. Semantic versioning scheme is used, but only the major version. Breaking changes are only introduced in new major versions. API version is required in all urls.
Endpoints may introduce new optional fields at any time in the request and any new fields in the response. The client must skip all unknown fields.
For every endpoint, a changelog exists which displays the latest released changes and the upcoming unreleased changes. Additionally, an overall Changelog exists with the most exciting changes about the API in general.
The OTTO Partner API would continue to support the old version of the API for 6 months from the time of public announcement for the new version of a given API.
Some common headers should be set by clients:
X-Request-Timestampheader within pattern:
Acceptto the desired response format e.g.
Content-Typeheader to define the used format in the request body, only applicable if you send a request body
The interfaces describe which HTTP methods are allowed and how to use them.
Our basic concern is that basically all HTTP Methods are allowed in the standardized way.
Note that these methods should behave as specified by their
standardized meaning (idempotency).
The following is a description of a few special features, relevant facts or ways to use some of the HTTP methods.
Click to expand for details
POST will update specific fields and returns the result like a GET would do (error response is independent).
PUT will create or replace the whole entity independent of an existing entity.
PATCH will update specific fields and not return data like a GET would do (error response is independent). PATCH body is structured in the same way as PUT and POST (entity body). All fields added into your body will be updated, other fields will not be affected.
"username" : "myusername",
"email" : null
We are using standardized HTTP status code with a body only if needed (it also just can be empty), but details about that you can find at the concrete interface implementation.
|HEAD||Can be issued against any resource to get just the HTTP header info.|
|GET||Used for retrieving resources.|
|POST||Used for creating resources.|
|PATCH||Used for updating resources with partial JSON data. For instance, an Issue resource has title and body attributes. A PATCH request may accept one or more of the attributes to update the resource. PATCH is a relatively new and uncommon HTTP verb, so resource endpoints also accept POST requests.|
|PUT||Used for replacing resources or collections. For PUT requests with no body attribute, be sure to set the Content-Length header to zero.|
|DELETE||Used for deleting resources.|
Error messages are returned as content type "application/json;charset=utf-8" in the following format:
"title": "Invalid Attribute",
"detail": "First name must contain at least three characters.",
"logref": "key to find in the log"
"title": "Warning Attribute",
"detail": "Last name should start with big letter.",
"logref": "key to find in the log"
|path||yes||called REST path|
|title||yes||short description of the error|
|code||no||internal error code (number or enum) of your application / domain (do not use the HTTP status codes)|
|detail||no||long description of the error, perhaps technical details|
|detail-structured||no||technical details in JSON structure|
|jsonpath||no||JSON field in request which caused the error|
|logref||no||reference key to find more stuff in the log (as example traceId)|
All interfaces return a list with resources (orders, shipments...) and a next link if more entries exist. Use the next link to retrieve more entries.
For pagination, the basic query parameter "limit" (e.g.
?limit=10) can be used
to define the maximum amount of resulting entities returned per call.
The interface itself can reduce the limit lower than your client limit.
An example entity would be:
...data of the entity if all or some information will be provided directly...,
href: "/v1/orders/1234", <--- Link to single partner order
href: "/v1/orders?idGt=1234", <--- Link to next list of ressources. If not present, no more records exist, currently
If you send a bulk request for an API endpoint, it will be processed asynchronously at the backend.
Synchronously will be delivered an endpoint to check the asynchronous processing state.
HTTP STATUS 202 (Accepted)
The client can follow the
href to check the state of processing.
An example entity would be:
"message": "is running boy",
Clients don't have to know the filetype that will be returned from a resource. Resources serving files will have the appropriate file extension in the URL as shown in the example below.
GET /SomeInvoice.pdf HTTP/1.1
Clients can find out the mime-type from the Content-Type header that will be sent in the response (e.g. application/pdf for PDF files and application/csv for CSV files).
HTTP/1.1 200 OK