API Design

The Atlar API is a resource-based JSON API, following RESTful standards.

What is considered a Non-Breaking change

Endpoints, Fields and Request parameters will not be removed or changed without a change of version. However non-breaking changes to the API may be introduced without a version change. This includes new fields to JSON objects and new parameters to requests. In practice, this means that your clients need to handle unknown/unmapped fields and parameters. Introduction of new fields/parameters will not impact behavior of existing fields/parameters.

Structure

The Atlar API is resource-oriented and follows REST/CRUD practices.

Method & PathDescription
GET /{namespace}/v#/{resource}List/Query resources in a resource collection.
POST /{namespace}/v#/{resource}Create a new resource.
GET /{namespace}/v#/{resource}/{id}Get the identified resource.
PATCH /{namespace}/v#/{resource}/{id}Update specific fields of the identified resource. JSON Patch format is used.
DELETE /{namespace}/v#/{resource}/{id}Delete the identified resource.

Namespaces

Atlar API endpoints are grouped in to product namespaces:

  • financial-data — Your bank accounts, account transactions, account balances etc.
  • payments — Credit transfers, direct debits, counterparties etc.

📘

No trailing slashes, and all paths have pluralized resource names

Authentication

The Atlar API supports both OAuth 2.0 access tokens and HTTP Basic authentication.

It is recommended to use the OAuth 2.0 access token flow.

OAuth 2.0 access token

The Atlar API support OAuth 2.0 access tokens using the client credentials grant type. Use the OAuth 2.0 access token endpoint to acquire an access token. Use the ACCESS_KEY and SECRET that you retrieve when creating programmatic access users as OAuth 2.0 client credentials (ACCESS_KEY as client_id and SECRET as client_secret).

Example

Step 1. Acquire an access token.

curl -s -d 'grant_type=client_credentials' -u '<ACCESS_KEY>:<SECRET>' https://api.atlar.com/iam/v2beta/oauth2/token

This will give a OAuth 2.0 access token response on the form:

{"access_token":"<ACCESS_TOKEN>","token_type":"Bearer","expires_in":300}

ℹ️ The access token will have a limited lifetime given by the property "expires_in" (time-to-live in seconds).

Step 2. Use the access token as a Bearer token authentication.

Use the ACCESS_TOKEN value from the token response as Bearer token authentication, i.e. pass HTTP header Authorization: Bearer <ACCESS_TOKEN>.

E.g. listing Accounts using curl would be done with:

curl 'https://api.atlar.com/financial-data/v2/accounts' --oauth2-bearer '<ACCESS_TOKEN>'

HTTP Basic authentication

Use HTTP Basic auth with the ACCESS_KEY and SECRET that you retrieve when creating programmatic access users.

Listing Accounts using curl would be done with:

curl 'https://api.atlar.com/financial-data/v2/accounts' -u '<ACCESS_KEY>:<SECRET>'

Pagination

Pagination works the same on all List endpoints. This includes GET endpoints for resource collections, e.g. GET /financial-data/v2/transactions or GET /payments/v2/credit-transfers.

The request has two common query parameters that can be used: limit and token. Limit, if included, must be between 1 and 500, if it is less or more than those values it will be coerced down or up to the respective limit. If limit is not included it will default to 100.

E.g.

  • GET /financial-data/v2/transactions?limit=20 will give 20 transactions (or up to 20 if there are less than 20 total transactions)

  • GET /financial-data/v2/transactions?limit=20&token={TOKEN} will give 20 transactions, starting from {TOKEN}.

The list response object will, no matter the resource, have the same shape. It will carry four fields:

  • items - An array containing the resource items. This field is required, but may be an empty array.
  • nextToken (required) - Token which should be used to continue pagination. Empty if it is known to not exist any more items on the server at the point of the request.
  • token (required) - Indicating what token was used for the request. Empty if no token was specified in the request.
  • limit (required) - Indicating the (effective) limit was used to process the request.

❗️

Never use the length of the items list in comparison to the limit to determine whether more pages exists.

There may be cases where the number of items returned, is lower than the limit that was asked for, even though more items exists on the server.

📘

Keep filter query parameters while paginating through the data

If you are using resource-specific filtering parameters when querying, those should stay the same throughout the pagination. If query parameters change, always restart pagination (by not setting token value in the request)

Response

{
  "nextToken": "The token that should be used to get the next page, empty if no more",
  "token": "The token used for this query",
  "limit": 20,
  "items": []
}
{
  "token": "",
  "nextToken": ""
  "limit": 100,
  "items": []
}

Errors

In general the Atlar API uses the following standard error codes

CodeDescription
400 Bad RequestThe request is invalid.
401 UnauthorizedThe authentication is wrong or non-existent.
403 ForbiddenThe used API key does not have permission to view/modify the resource.
404  Not FoundThe identified resource could not be found.
405  Method Not AllowedThe accessed method is not valid.
410  GoneThe identified resource does not exist anymore.
425Too EarlyIf same idempotency key is used for multiple requests, but the server is not done with previous request. Client is supposed to retry this status. See more about Idempotency below.
429  Too Many RequestsThe amount of requests made for the past minute exceeds our rate limit.
500  Internal Server ErrorSome unexpected server-side issue has occurred.
503  Service UnavailableTemporarily offline for maintenance.

Request IDs

Each API request will be assigned a unique request identifier. This identifier will be included in the API response in the HTTP header request-id. If you need to contact us about a particular request, please provide the request identifier.

Idempotency

The Atlar API has built-in support for idempotency. Idempotency makes it possible to safely retry requests without risking to perform the same intended operation twice. This is in particular useful, or even needed, when an API request is disrupted, or in some way failing in transit, which renders the client without a response from the server. The problem in the scenario is that the client that didn't receive the response cannot know if the server actually performed the request or not. Which, without Idempotency, for a creation of a resource could lead to the multiple created resources if the request is retried. To solve this, Idempotency Keys are implemented and, if supplied, the same request can be retried multiple times, without the risk of multiple resources being created.

To make, an otherwise non-idempotent request, idempotent; supply the optional HTTP header Idempotency-Key. The key is ignored for GET and DELETE requests and will expire automatically after 24h of first use. The uniqueness of a key is bound to the organization and endpoint (method and path). If a client would make a second request - with the same idempotency key - before the first request is done server-side, the server will respond with a 425 Too Early status. This error code is always safe to retry.

If one wants to test how idempotency works on the Atlar API, an endpoint with the sole purpose of testing has been created on: POST /v1/idempotency-test. It does not take any request body, but one can supply the two optional integer query-parameters status and sleep. The former will dictate which status the response will have, and the latter will make the server sleep for this amount of milliseconds. The server will, after any potential sleep, respond with the supplied idempotency key, a random uuid, as well as the requested status.

With this endpoint one can test how the API will behave when supplying an idempotency key.

Safe Updates using If-Match and ETag

Many Atlar API resources support update operations, primarily using the PATCH method. To avoid conflicting updates and preventing the lost update problem all endpoints support and require specifying an ETag value as a If-Match HTTP header value.

All resources will have property named etag. When performing a PATCH, take the etag value as-is and use as value for the If-Match HTTP header.

Example:

Partial JSON response from previous GET request for a given resource:

{
  "id": "a2072298-4c27-40d6-a4ff-050006e63415",
  "etag": "version:3",
  ...
}

HTTP header to use in subsequent PATCH request:

If-Match: version:3

(NOTE: that when the ETag value comes from a JSON response property like etag, it will by-design not be a double-quoted string as per https://datatracker.ietf.org/doc/html/rfc9110#section-8.8.3 but just a plain string value, and should not be sent as a double-quoted string in terms of the HTTP header value. The value from the etag property should be sent as-is.)

External IDs

Many API resources support being identified by an ID value you provide. The resources that support this have a property externalId that can be specified when the resource is created. The resource can then be accessed by GET /{namespace}/{version}/resource/external:{externalId}. See the API Reference for details on which resources support this. Values for externalId must match the regexp ^[a-zA-Z0-9._\-+=]{1,64}$ to be considered valid.