Developer docsAPI version 2026-11-01
https://api.neofin.tech/v1StatusGet sandbox keys

Quickstart: issue your first IBAN

Issue a virtual IBAN, simulate a transfer to it and receive the webhook, in about ten minutes.

1. Create a sandbox key

Request sandbox access from the contact page. You will receive console access by email. In the console go to Developers → API keys and create a key; it starts with sk_test_. Export it in your shell:

Shell
export NEO_API_KEY=sk_test_...

2. Create a collection account

Every account needs a verified holder. In the sandbox, the holder kyb_31QZ is pre-verified for you.

cURL
curl https://sandbox.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" }
  }'
Node
import { NeoCollect } from "@neofin/collect";

const neo = new NeoCollect(process.env.NEO_API_KEY, { environment: "sandbox" });

const account = await neo.collectionAccounts.create({
  currency: "EUR",
  holder: { type: "business", legal_name: "Helios Merchants B.V.", kyb_id: "kyb_31QZ" },
  external_ref: "mch_8F2K91",
  rules: { first_party_only: true },
}, { idempotencyKey: "7f1c2e4a-9b0d-4c55-a1e3-2d6f0b9c8e11" });

console.log(account.iban); // FR7630004012773091526107
Python
from neofin import NeoCollect

neo = NeoCollect(api_key=os.environ["NEO_API_KEY"], environment="sandbox")

account = neo.collection_accounts.create(
    currency="EUR",
    holder={"type": "business", "legal_name": "Helios Merchants B.V.", "kyb_id": "kyb_31QZ"},
    external_ref="mch_8F2K91",
    rules={"first_party_only": True},
    idempotency_key="7f1c2e4a-9b0d-4c55-a1e3-2d6f0b9c8e11",
)
print(account.iban)  # FR7630004012773091526107

The response is synchronous and includes the IBAN:

201 Created
{
  "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"
}

3. Register a webhook endpoint

Run a tunnel to your local server (for example ngrok http 3000) and register the public URL. Keep the returned secret; you will use it to verify signatures.

cURL
curl https://sandbox.api.neofin.tech/v1/webhook-endpoints \
  -H "Authorization: Bearer $NEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://your-tunnel.example/neo/webhooks", "events": ["credit.*"] }'

4. Simulate a credit

In the sandbox you can create an inbound transfer directly. Use the IBAN from step 2.

cURL
curl https://sandbox.api.neofin.tech/v1/sandbox/credits \
  -H "Authorization: Bearer $NEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "iban": "FR7630004012773091526107",
    "amount": 125000,
    "currency": "EUR",
    "payer_name": "Helios Merchants B.V.",
    "payer_iban": "DE89370400440532013000",
    "remittance_info": "INV-2291"
  }'

5. Receive credit.settled

Within a few seconds your endpoint receives the event. Verify the NEO-Signature header before trusting it (see Verifying signatures).

Webhook body
{
  "id": "ev_5Tq81",
  "type": "credit.settled",
  "created_at": "2026-11-05T14:02:13Z",
  "data": {
    "id": "cr_2Kd9xZ",
    "collection_account": "ca_9Hc2LmQ",
    "external_ref": "mch_8F2K91",
    "amount": 1240000,
    "currency": "EUR",
    "rail": "sepa",
    "payer": {
      "name": "Kestrel Logistics GmbH",
      "iban": "DE89 •••• •••• •••• 3000 00",
      "country": "DE"
    },
    "shield": {
      "name_match": "exact",
      "score": 1.0,
      "screening": "clear",
      "decision": "accept"
    },
    "remittance_info": "INV-2291",
    "settled_at": "2026-11-05T14:02:13Z"
  }
}

6. Fetch the balance

cURL
curl https://sandbox.api.neofin.tech/v1/balances/ca_9Hc2LmQ \
  -H "Authorization: Bearer $NEO_API_KEY"

{ "account": "ca_9Hc2LmQ", "currency": "EUR", "available": 125000, "held": 0, "in_review": 0 }

7. Simulate a mismatch

Send another credit with "payer_name": "J. Marsh". Because the account has first_party_only: true, Shield returns it and you receive credit.returned:

Webhook body
{
  "id": "ev_5Tq94",
  "type": "credit.returned",
  "created_at": "2026-11-05T15:41:07Z",
  "data": {
    "id": "cr_7Pq1nW",
    "collection_account": "ca_4Rt8KpL",
    "external_ref": "mch_2A7D55",
    "amount": 480000,
    "currency": "EUR",
    "rail": "sepa",
    "payer": { "name": "J. Marsh", "iban": "FR14 •••• •••• •••• 0606 10", "country": "FR" },
    "shield": {
      "name_match": "no_match",
      "score": 0.08,
      "screening": "clear",
      "decision": "return"
    },
    "return_reason": "third_party_funds",
    "returned_at": "2026-11-05T15:41:07Z"
  }
}
Next: read the Collect guide for rules, freezing and statements, or the going-live checklist.