A
Atlar API Guide
Step 10 — Beyond the Basics
10Step 10 of 10

Beyond the Basics

Direct debits, batch payments, idempotency, and more.

You have completed the core API flow. Here are additional capabilities to explore as you build your integration.

Direct Debits & Mandates

Direct debits let you collect money from a counterparty's account. They require a mandate — a pre-authorization from the payer.

Step 1: Create a mandate

POST
/payments/v2/mandates

Create a SEPA Direct Debit mandate for an external account.

curl -X POST 'https://api.atlar.com/payments/v2/mandates' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "CORE",
    "externalAccountId": "<external-account-id>",
    "signatureDate": "2025-12-01",
    "reference": "MANDATE-001"
  }'

Step 2: Create a direct debit

POST
/payments/v2/direct-debits

Collect funds from a counterparty using an active mandate.

curl -X POST 'https://api.atlar.com/payments/v2/direct-debits' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "amount": {
      "currency": "EUR",
      "value": 5000
    },
    "date": "2025-12-15",
    "scheme": "SDD_CORE",
    "source": {
      "type": "ACCOUNT",
      "id": "<your-account-id>"
    },
    "mandateId": "<mandate-id>",
    "reference": "collection-001"
  }'
đŸ–Ĩī¸

Dashboard: Direct Debits

View and manage direct debit collections. Mandates are managed under the counterparty detail view.

app.atlar.com/direct-debits

Idempotency

Network failures can leave you unsure whether a request succeeded. The Idempotency-Key header lets you safely retry creation requests without risking duplicates. Keys are scoped to your organization and endpoint, and expire after 24 hours.

# Use Idempotency-Key to safely retry requests
curl -X POST 'https://api.atlar.com/payments/v2/credit-transfers' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: my-unique-key-12345' \
  -d '{ ... }'

# Retrying with the same key returns the original response
# (no duplicate payment created)
â„šī¸

425 Too Early

If you retry while the original request is still processing, Atlar responds with 425 Too Early. This status is always safe to retry after a short backoff.

Safe updates with ETags

Updates use PATCH with JSON Patch format. The If-Match header with the resource's etag prevents lost updates from concurrent modifications.

# 1. Get the resource and note its etag
curl 'https://api.atlar.com/payments/v2/counterparties/COUNTERPARTY_ID' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

# Response includes: "etag": "version:3"

# 2. Update using If-Match header
curl -X PATCH 'https://api.atlar.com/payments/v2/counterparties/COUNTERPARTY_ID' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'If-Match: version:3' \
  -d '[
    { "op": "replace", "path": "/alias", "value": "Updated Alias" }
  ]'
âš ī¸

ETag format

The etag value from the JSON response (e.g. version:3) should be sent as-is in the If-Match header — do not wrap it in double quotes.

External IDs

Many resources support an externalId field that lets you reference them by your own identifier. Valid format: ^[a-zA-Z0-9._\-+=]{1,64}$

# Create a counterparty with an externalId
curl -X POST 'https://api.atlar.com/payments/v2/counterparties' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "legalName": "Acme Corp",
    "partyType": "ORGANIZATION",
    "externalId": "acme-corp-123",
    "accounts": [...]
  }'

# Later, look it up by external ID
curl 'https://api.atlar.com/payments/v2/counterparties/external:acme-corp-123' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Pagination patterns

Here is a reusable pagination helper that works with any Atlar list endpoint:

def paginate_all(session, url, params=None):
    """Generic paginator for any Atlar list endpoint."""
    all_items = []
    token = ""
    base_params = params or {}

    while True:
        p = {**base_params, "limit": 500}
        if token:
            p["token"] = token

        resp = session.get(url, params=p)
        resp.raise_for_status()
        data = resp.json()

        all_items.extend(data["items"])

        if not data["nextToken"]:
            break
        token = data["nextToken"]

    return all_items

# Usage
all_txns = paginate_all(
    session,
    "https://api.atlar.com/financial-data/v2/transactions",
    {"accountId": "..."},
)

Error codes reference

CodeStatusMeaning
400Bad RequestInvalid request body or parameters
401UnauthorizedMissing or invalid authentication
403ForbiddenInsufficient role permissions
404Not FoundResource does not exist
410GoneResource was deleted
425Too EarlyIdempotent request still processing (retry)
429Too Many RequestsRate limit exceeded
500Server ErrorUnexpected server-side issue
💡

Request IDs

Every API response includes a request-id header. If you need to contact Atlar support about a request, include this ID for quick resolution.

Further reading

Finished with the guide?

No credentials are currently connected, but you may still have saved IDs from previous steps.