The ledger, as an API.
Predictable REST resources, idempotent writes, signed webhooks with retries, and daily statements per virtual account. Build against the sandbox before you touch live money.
Available to verified businesses only.
Webhook inspector
Sample dataBank APIs were not designed for platforms.
- Bank statements arrive as files, not events.
- Retries without idempotency create duplicate accounts and duplicate payouts.
- Unsigned callbacks cannot be trusted with money.
Four steps, no manual matching.
Authenticate
Use a scoped API key or OAuth 2.0 client credentials.
Create resources
Issue accounts, sessions, wallets and payouts with idempotent POSTs.
Listen
Receive signed webhooks for every state change, with retries for 3 days.
Reconcile
Pull daily CAMT.053, CSV or JSON statements per account.
Everything you need, nothing you have to build.
REST + JSON
Resource-oriented URLs, standard HTTP verbs, cursor pagination.
Idempotency
Idempotency-Key header on every POST; safe retries for 24 h.
Signed webhooks
HMAC-SHA256 signatures with timestamp; exponential retry for 3 days.
Sandbox
Simulate credits, returns, recalls and name mismatches with test endpoints.
Statements
CAMT.053, CSV and JSON per account, daily.
OAuth 2.0 & API keys
Client-credentials for server-to-server; scoped, rotatable keys.
Versioning
Date-based API versions pinned per key; breaking changes never silent.
SDKs
Official Node and Python SDKs available; PHP SDK in beta.
Create a collection account
Idempotent POST, synchronous response, signed webhook. Full details in the API reference.
API keys are scoped per product and per environment. Every request is logged with its request ID and retained for audit.
curl https://api.neofin.tech/v1/collection-accounts \
-H "Authorization: Bearer $NEO_API_KEY" \
-H "Idempotency-Key: 7f1c2e4a-9b0d-4c55-a1e3-2d6f0b9c8e11" \
-H "Content-Type: application/json" \
-d '{
"currency": "EUR",
"holder": {
"type": "business",
"legal_name": "Helios Merchants B.V.",
"kyb_id": "kyb_31QZ"
},
"external_ref": "mch_8F2K91",
"rules": {
"first_party_only": true,
"max_credit_amount": 5000000
},
"labels": { "region": "NL" }
}'
{
"id": "ca_9Hc2LmQ",
"object": "collection_account",
"status": "active",
"currency": "EUR",
"iban": "FR7630004012773091526107",
"bic": "NEOFFRP1",
"holder": {
"type": "business",
"legal_name": "Helios Merchants B.V.",
"kyb_id": "kyb_31QZ"
},
"external_ref": "mch_8F2K91",
"rules": { "first_party_only": true, "max_credit_amount": 5000000 },
"labels": { "region": "NL" },
"created_at": "2026-11-05T14:02:11Z"
}
import crypto from "node:crypto";
export function verifyNeoSignature(body, header, secret) {
const parts = Object.fromEntries(
header.split(",").map((p) => p.split("="))
);
const signed = `${parts.t}.${body}`;
const expected = crypto
.createHmac("sha256", secret)
.update(signed)
.digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return (
fresh &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))
);
}
Questions we get about Reconcile API.
Is there a sandbox?
Yes. Sandbox access is immediate on request and mirrors the live API, with test endpoints to simulate credits, returns and recalls.
How do I verify webhooks?
Each delivery carries a NEO-Signature header with a timestamp and an HMAC-SHA256 of the timestamp and body using your endpoint secret. Reject anything older than five minutes.
Are webhooks ordered?
Events may arrive out of order after retries. Use created_at and the resource's current state rather than event order.
What are the rate limits?
Default limits are 600 requests per minute per key. A Retry-After header is returned on 429 responses. Higher limits are available on Institutional plans.
How are breaking changes handled?
Versions are date-based and pinned per key. New versions are announced in the changelog at least 90 days before any older version is retired.
Issue your first virtual IBAN this week.
Sandbox access is immediate. Live accounts follow KYB review of your business.