Getting started

Environments

The Issuer API is available on the following demo and productions environments:

Demo:

  • Authentication: https://demo.cashlink.de/api/external

  • API: https://demo.cashlink.de/api/external/issuer

Production:

  • Authentication: https://connect.cashlink.de/api/external

  • API: https://connect.cashlink.de/api/external/issuer

Authentication

Every call to the API must be authenticated via OAuth client credentials. More information.

During setup, your point of contact will provide you with your client ID and client secret. You use those credentials to retrieve an authentication token that you can use in subsequent requests.

Example:

r = requests.post(f'{URL}/oauth/token', data={
    'grant_type': 'client_credentials',
    'scope': 'products:read products:write issuers:read issuers:write documents:write investments:read',
    'client_id': CLIENT_ID,
    'client_secret': CLIENT_SECRET
})
assert r.status_code == 200, r.content
access_token = r.json()['access_token']

Access to resources via the Issuer API can be managed using the following scopes:

Scope
Description

documents:write

Upload documents via POST /documents

issuers:read

Retrieve issuer information via GET /issuers

issuers:write

Create and patch issuers via POST+PATCH /issuers

products:read

Retrieve information about products via GET /products, about listings via GET /listings and distribution platforms via GET /distribution-platforms

products:write

Create and patch products via POST+PATCH /products and create listings via POST /listings

investments:read

Retrieve transfer and investment information via GET /investments

Idempotency

For certain POST endpoints, the API uses client-supplied idempotency keys to ensure that requests can be retried safely without performing the same operation twice. Repeated calls to those endpoints with the same idempotency key will return the cached response from the first call. Keys are expected to be set as header parameters with "X-Idempotency-Key".

The recommended approach for interacting with such endpoints is as follows:

  1. Create a unique, random key, such as a UUIDv4.

  2. Store the intent to call an endpoint along with the generated key in the client database.

  3. Flush to disk (e.g. commit an SQL transaction).

  4. Perform the call to the endpoint.

This ensures that even if the response from the API to a client gets lost, or the client experiences any sort of outage between steps 3 and 4, the client can always safely retry the same action.

If you already have objects corresponding to tasks in the API in your client-side database, you can use their internal IDs as idempotency keys!

Pagination

Endpoints that list objects will return a paginated response in the following format

{
    'count': 20, 
    'next': 'https://...', 
    'previous': 'https://...', 
    'results': [...]
}

The response will always be sorted by the creation date of the object with the oldest first. Using the next and previous URLs you can move through the different pages. The results array will hold the objects on the current page.

Monetary values

Monetary values are represented as a combination of amount, decimals & currency.

For example the following response is to be understood as "EUR 40,000.000"

{
    "amount": "40000000", 
    "decimals": 3, 
    "currency": "EUR"
}

Handling documents

The document endpoint can be used to upload documents. Files are uploaded via HTTP multipart. The endpoint will return a document ID that can be used in other requests to refer to that document.

Example:

r = requests.post(
    f'{URL}/v2/documents/',
    files={'file': ('protocol.pdf', b'ASD', 'application/pdf')},
    headers={**headers, 'X-Idempotency-Key': '...'}
)
assert r.status_code < 300, r.content
doc_id = r.json()['id']

Last updated

Was this helpful?