Overslaan naar inhoud

Atlas Partner API

One gate for the partners Atlas works with. Send us invoices, fee specifications and operational events for the merchants Atlas manages — Atlas consolidates everything and bills each merchant once a month, under the Atlas brand.

What it is

The Atlas Partner API is a single intake gate. Partners push three kinds of data to Atlas:

  • Invoices — what a partner charges Atlas for the merchants Atlas manages.
  • Fee statements — the transaction-level breakdown behind those invoice lines.
  • Events — operational signals, such as a failed direct debit or a terminal swap.

Atlas reviews, maps every line to the correct merchant, and issues one monthly invoice per merchant under the Atlas brand. Nothing a partner submits is paid or booked automatically — every submission is stored immutably, acknowledged with an intake id, and reviewed by Atlas before anything is recorded in accounting.

Who it's for

  • Payment providers
  • POS vendors
  • Hardware suppliers

In short: anyone Atlas manages a merchant relationship through, who needs to bill Atlas for that merchant's terminals, subscriptions, transaction fees or hardware.

How onboarding works

  • Request partner access via info@atlascorporation.org.
  • Receive a sandbox key (atp_test_…) and a webhook signing secret.
  • Send a test invoice against the sandbox to confirm your integration maps merchants and totals correctly.
  • Atlas verifies your sandbox submissions.
  • Atlas issues a live key (atp_live_…).

info@atlascorporation.org

Quickstart

Three calls to get oriented: who you are, submitting an invoice, and checking what happened to it.

1. Identify your key

bash

curl https://atlascorporation.org/api/partner/v1/me \
  -H "Authorization: Bearer atp_test_xxxxxxxxxxxxxxxx"

json response

{
  "partner": "example-partner",
  "mode": "test",
  "scopes": ["invoices", "fee_statements", "events", "merchants.read"]
}

2. Submit an invoice (JSON)

Itemize per merchant: each line carries atlas_merchant_ref (or your own partner_merchant_ref / terminal_id), a VAT rate, and a line total. Transaction-fee lines also carry transaction_count.

bash

curl -X POST https://atlascorporation.org/api/partner/v1/invoices \
  -H "Authorization: Bearer atp_test_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: INV-2026-00042" \
  -d '{
    "document_type": "invoice",
    "number": "INV-2026-00042",
    "issue_date": "2026-09-01",
    "due_date": "2026-09-30",
    "currency": "EUR",
    "supplier": {
      "name": "Example Partner B.V.",
      "vat_number": "NL000099998B01",
      "kvk": "12345678"
    },
    "payment": { "method": "direct_debit", "reference": "INV-2026-00042" },
    "lines": [
      {
        "atlas_merchant_ref": "am_7K2QH9",
        "terminal_id": "50330000",
        "category": "terminal_rental",
        "description": "Terminal rental - Voorbeeld Restaurant",
        "quantity": "1",
        "unit_price": "29.00",
        "vat_rate": "21",
        "line_total": "29.00",
        "period_start": "2026-09-01",
        "period_end": "2026-09-30"
      },
      {
        "atlas_merchant_ref": "am_7K2QH9",
        "terminal_id": "50330000",
        "category": "transaction_fee",
        "description": "Debit consumer domestic - transaction fee",
        "quantity": "412",
        "unit_price": "0.02900",
        "vat_rate": "21",
        "line_total": "11.95",
        "period_start": "2026-09-01",
        "period_end": "2026-09-30",
        "transaction_count": 412
      }
    ],
    "totals": { "net": "40.95", "vat": "8.60", "gross": "49.55" }
  }'

json response · 202

{
  "intake_id": "itk_01J9Z8Q4K2V7",
  "kind": "invoice",
  "mode": "test",
  "status": "received",
  "received_at": "2026-09-01T10:03:00Z",
  "sha256": "…"
}

3. Check intake status

bash

curl https://atlascorporation.org/api/partner/v1/intake/itk_01J9Z8Q4K2V7 \
  -H "Authorization: Bearer atp_test_xxxxxxxxxxxxxxxx"

Authentication

Every request (except /health) carries a bearer key:

Keys are issued by Atlas per partner, shown once, and stored hashed on our side — Atlas cannot show you a key again after issuance. If a key is lost or compromised, request a rotation from Atlas; the old key is revoked once the new one is confirmed working.

Idempotency

Every write (POST /invoices, POST /fee-statements, POST /events) requires an Idempotency-Key header — up to 128 characters, retained for 30 days. Reuse the same key with the same body and you get back the original result. Reuse the same key with a different body and Atlas returns 409 Conflict. A natural choice is your own document or event id.

Merchant references

Three identifiers can appear on a line, and at least one is required so Atlas can route the cost to the right merchant (omit all three only for Atlas's own costs):

If you don't know your Atlas-side reference yet, call GET /merchants with your own identifiers and Atlas returns the mapping.

FieldMeaning
atlas_merchant_refAtlas's own reference for the merchant, e.g. am_7K2QH9. Preferred — use it whene
partner_merchant_refYour own merchant identifier, e.g. m_12345. Atlas maps this to an atlas_merchant
terminal_idThe physical terminal's serial, e.g. 50330000. Useful when billing is per-device

Invoices

POST /invoices accepts three transports:

  • JSON (Atlas schema) — shown in the quickstart above.
  • UBL 2.1 / Peppol BIS Billing 3.0 XML — the preferred format, sent as application/xml.
  • multipart/form-data — a document part (UBL XML or Atlas JSON) plus an optional pdf part (max 10 MB) for a human-readable copy.

Every line should carry a merchant reference (see above). Totals (net, vat, gross) must reconcile with the sum of the lines, or the submission lands in needs_review with a totals_mismatch issue.

Line totals & VAT, precisely

line.line_total is the NET (excl. VAT) amount for that line: quantity × unit_price, rounded half-up to 2 decimals. It is the authoritative figure Atlas validates against — Atlas does not re-derive it from quantity and unit_price, because a displayed unit_price may itself be rounded (e.g. a per-transaction fee shown at 2 decimals but actually billed at a finer precision). Send the exact net amount in line_total.

VAT is calculated per rate, on the sum of line_total for every line that shares that vat_rate — never line-by-line. That per-rate VAT is compared to totals.vat within a 0.01 tolerance (vat_mismatch if it doesn't reconcile).

Optionally, submit totals.vat_breakdown — one {rate, base, vat} row per VAT rate present on the invoice:

Each row is checked against the lines: base must equal the sum of line_total for lines at that rate, and vat must equal base × rate / 100 (rounded half-up, 0 for exempt/reverse_charge/0). A mismatch never rejects the submission — it's stored with issue code vat_breakdown_mismatch and status needs_review.

Credit notes (document_type: "credit_note") must include credits_invoice_number — the number of the invoice being credited. Without it, the credit note is stored but flagged needs_review with issue code missing_credits_reference, since Atlas can't apply it automatically. Credit note lines and totals carry negative amounts; a mixed sign between the lines and totals.gross is flagged as sign_mismatch.

UBL / multipart example

Fee statements

POST /fee-statements submits the per-merchant, per-segment transaction breakdown behind an invoice's transaction-fee lines — informational, not a payment instruction. Segments look like:

Known segments: debit_consumer_domestic, debit_consumer_non_domestic, credit_consumer_eu, credit_consumer_non_eu, commercial, other.

Events & signature verification

POST /events is how Atlas receives your webhook calls once you've registered a target URL with us. Every event you send must include an Atlas-Signature header:

The signature is HMAC-SHA256 of the string "{t}.{body}" (timestamp, a literal dot, then the raw request body), computed with your webhook secret. Atlas rejects signatures where t is more than 300 seconds from current time, to guard against replay.

Verify in Python

Verify in Node

Known event types: merchant.onboarded, merchant.ended, terminal.activated, terminal.deactivated, terminal.swapped, payment.direct_debit_failed, invoice.reminder, chargeback.created, settlement.paid. Other types are accepted and stored.

Intake statuses

Every submission (invoice, fee statement or event) returns an intake_id and moves through one status:

Poll GET /intake/{intake_id} to follow a submission through these states.

Errors

Errors follow RFC 9457 (problem+json):

StatusMeaning
401Missing, invalid or revoked key, or a bad event signature.
403Authenticated, but the key lacks the scope this endpoint requires (e.g. a mercha
409Same Idempotency-Key with a different body (idempotency-conflict); an invoice nu
413Payload too large (e.g. a PDF over 10 MB).
422Invalid request shape (schema validation failed) — see errors[] for the offendin
429Rate limited — default 60 requests/min per key. Respect Retry-After.

RFC 9457 (problem+json)

Sandbox vs. live

Sandbox submissions are fully isolated — nothing you send with an atp_test_ key is ever booked, mixed with live data, or seen by a merchant.

SandboxLive
Key prefixatp_test_atp_live_
Reaches Atlas accountingNeverYes, after Atlas review
IssuedStep 2 of onboardingAfter Atlas verifies your sandbox submissions

Versioning & changelog

The API is versioned in the URL path (/api/partner/v1/...). Breaking changes get a new path version; additive changes (new optional fields, new event or error types) land in place and are listed here.

VersionDateNotes
v1.0.12026-09-17Additive: optional totals.vat_breakdown (per-rate reconciliation, issue code vat
v1.0.02026-09-17Initial public release: invoices (JSON / UBL 2.1 Peppol BIS 3 / multipart), fee

Security & data

  • EU-hosted. Atlas's infrastructure runs in the EU.
  • TLS in transit. All API traffic is over HTTPS.
  • Keys stored hashed. Atlas cannot retrieve or display a partner key after it is issued.
  • Nothing is auto-paid. A submission being validated or booked_draft is not a payment instruction — Atlas reviews before anything is booked or paid.

We don't publish uptime figures or service-level commitments on this page, and we don't describe this integration as "certified" by any scheme — if you need contractual terms, raise it with your Atlas contact.