sandbox.bankconnector.com API Reference

Getting Started

Audience: 🔌 Integration Client · 🏗️ Platform Operator

This page takes you from nothing to an executed payment in a sandbox — provision, send, read — with no signup.

🚀 Prefer to watch it first? The interactive playground provisions a sandbox in one click and animates the round-trip. This guide is the same flow in curl, with the detail behind each step.

What you'll have after Step 1

Nothing to install, no account to create. POST /sandbox/provision mints an isolated sandbox for you — your own platform, a company, an admin login, an API key, and an already-active demo bank connection. From there, two credentials matter (see Authentication for the full model):

  • API key (X-API-Key: key_…) — the machine credential for the data plane: submitting payments, reading results, webhooks. It identifies your platform, so you pass only companyId, never platformId.
  • Admin session (from the dashboardLogin creds) — the control plane, for creating companies/users and setting up bank connections. You don't need it for the payment loop below; see Managing companies & users.

Sandbox tenants are auto-deleted after 30 days of inactivity. Provision a fresh one any time — it's a single unauthenticated call.

Environments at a glance

BankConnector is multi-tenant SaaS: you connect to the vendor-run platform at bankconnector.com — your company gets a branded subdomain (https://<company>.bankconnector.com), and there's no infrastructure to run yourself.

Whichever host you're on, it runs in one of two postures:

PostureDemo bankAuthUse for
production❌ offclosedlive payments
sandbox✅ onclosed, real keys, TLSintegration testing

The public sandbox.bankconnector.com turns every bank into a simulated Demo Bank (default danske-dk), and real-money sends are off engine-wide. Separately, each bank connection carries its own environment: test | production flag — a production posture refuses a production connection pointed at a bank's test host, and vice-versa.

⚠️ A sandbox posture alone does not guarantee no real money can move. The hard boundary is your company's sandboxOnly flag — a sandboxOnly company (which is what provisioning creates) can never deliver a production-environment payment, on any posture. See Going Live for the full picture.

Step 1 — Provision a sandbox

No auth, no body required:

curl -X POST https://sandbox.bankconnector.com/sandbox/provision

You get back a 201 with everything you need:

{
  "apiKey":     "key_…",               // data-plane credential (X-API-Key)
  "companyId":  "comp_…",              // the company to act as
  "platformId": "plat_…",
  "baseUrl":    "https://sandbox.bankconnector.com",
  "subdomain":  "sb-…",
  "bank":       { "key": "danske-dk", "name": "Danske Bank", "country": "DK" },
  "dashboardLogin": { "url": "…", "subdomain": "sb-…", "email": "…", "password": "…" },
  "firstPayment":   { /* a copy-paste-ready first request */ }
}

Export the key so the snippets below can use it:

export BC_KEY="key_…"
export BC_COMPANY="comp_…"

The response's firstPayment object is a ready-to-send request for exactly this bank — you can POST it as-is. Want a different bank? Pass {"bankKey":"nordea-dk"} in the provision body (list them with GET /profiles).

Step 2 — (Optional) Preview a conversion

Before you commit anything to the journal, you can validate + convert a canonical payment to XML with no state change and no delivery:

curl -X POST https://sandbox.bankconnector.com/journal/payments/preview \
  -H "X-API-Key: $BC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "companyId": "'"$BC_COMPANY"'",
    "bankKey":   "danske-dk",
    "payment":   { ... see Core Concepts for the full object ... }
  }'
# 200 { ..., "xml": "<Document>...</Document>" }

A 200 means the payment is structurally valid and converts cleanly; a 422 returns the exact issues in error.details.issues. This is the cheapest way to iterate on your payload. (Note: no platformId — the key implies your platform.)

Step 3 — Submit a payment

Send it for real. In sandbox this exercises the full pipeline — validation → conversion → approval planning → async delivery to the demo bank — without moving money:

curl -X POST https://sandbox.bankconnector.com/journal/payments \
  -H "X-API-Key: $BC_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 2f9a1c7e-order-10432" \
  -d '{
    "companyId":   "'"$BC_COMPANY"'",
    "bankKey":     "danske-dk",
    "environment": "test",
    "payment":     { ... }
  }'
# 201 { "id": "...", "journalNo": "...", "status": "...", "xml": "...", "deliveryMode": "..." }

A 201 means accepted and converted — not sent. The bank send happens asynchronously, and the journal-document fields (id, journalNo, status, …) come back at the top level alongside xml and deliveryMode — there's no "document" wrapper.

Step 4 — Read the result

The demo bank replies after ~5 seconds with a real-format pain.002 + camt.053 that flow through the actual inbound parsers. Read the reconciled state:

curl -H "X-API-Key: $BC_KEY" \
  "https://sandbox.bankconnector.com/journal/reconciliation?companyId=$BC_COMPANY"
# status "executed", state "cleared"

GET /journal/list?companyId=$BC_COMPANY gives the same as a paged list. See Receiving Results for webhooks + polling in depth.

Where to go next