sandbox.bankconnector.com API Reference

API versioning & compatibility

BankConnector's HTTP API is versioned by date, via the BankConnector-Version header, never a /v1 path prefix.

BankConnector-Version: 2026-06-01

How versioning works

How the header is read:

  • Every response echoes back the version it was served under, error responses and 401 included, so you can confirm what you are pinned to at a glance.
  • With no header you get 2026-06-01, the oldest version we serve, not the newest. That is deliberate: an integration that never pinned anything must not be moved underneath. Send the header.
  • A date resolves to the newest version published at or before it. A date before 2026-06-01 resolves to 2026-06-01; a date after the newest resolves to the newest.
  • A header that is not a YYYY-MM-DD date is 400 validation_failed.

What a pinned version covers

The header changes one thing: how a refused request is answered, which status and code (the versions below). Every other change to the API applies to every version at once, whichever you pin.

  • A removed or renamed path, field or code, and a changed status, are announced in Contract changes below under the month they ship. We do not promise that a pinned version stays unchanged beyond the refusals, so watch that page.
  • Additive changes (new optional request fields, new response fields, new endpoints, new enum values) may appear without notice. Build tolerant clients: ignore unknown fields, handle a status or enum value you have not seen, and branch on code, not message.

Current version: 2026-10-21

  • A connection request refused for the connection's state is 409 invalid_state, not validation_failed: the request was fine, and the connection needs another step first. See 2026-10-21 below.
  • A request body we read but cannot use is 422, not 400, on every route, with each problem on its field in error.details.issues, and a field the route does not read is refused rather than dropped. See 2026-10-20 below.
  • A payment we cannot process is 422, not 400. 400 means we could not read your request at all (not JSON, a bad header); 422 means the request was fine and the payment inside it is not something we can accept, with the reasons in error.details.issues. See 2026-08-25 below, and Errors & Retries.
  • Canonical input schema 1.1 (additive over 1.0: structured postalAddress, regulatoryReporting, and purposeCode / localInstrument / categoryPurpose overrides; see Core Concepts).
  • Object error envelope: { error: { code, message, details? } } on every non-2xx response (see Errors & Retries).
  • Standard list envelope: { items, nextCursor?, total? } across all list endpoints (see Pagination).
  • One word for "you have pulled this document": collected. On the journal read surfaces (GET /journal/list and GET /journal/documents) each item carries collected / collectedAt, the /journal/list envelope carries an uncollected count, and the filters are ?uncollectedOnly=true and ?collected=true|false. See Receiving Results.

Versions

Four versions can be pinned with BankConnector-Version. They differ only in the refusals described here; every other change on this page applies to all of them.

2026-10-21

Pin this version to tell a refused request apart from a connection that is not ready. A connection request can be refused because of what it sends, or because the connection is not at a point that allows it yet: a setup step or field not done, keys not sent, live when the action needs it deactivated, or a channel the action does not apply to. On this version the second is 409 invalid_state.

Refusal2026-06-01, 2026-08-252026-10-202026-10-21
the connection is not ready for the request400 validation_failed422 validation_failed409 invalid_state
a value cannot be used: missing or malformed in the request, or stored but malformed400 validation_failed422 validation_failed422 validation_failed (unchanged)

The message is the same on every version and names the step to take first. The routes are POST /connections, the connection setup actions under /connections/{id}, the certificate and credential uploads, and GET /connections/{id}/ebics-letter. On POST /connections/{id}/ws-certificate, a connection that does not use Web Services is 409 invalid_state and a family that is not the connection's own is 422 on this version; both stay 400 on every earlier version.

What to do:

  • If you branch on the status of a connection action, handle 409 invalid_state: show the message, and do not retry the same request until the step it names is done.
  • Nothing forces you to move. Keep sending 2026-10-20 and you keep 422.

2026-10-20

Pin this version to get the same line for every other request body. A body that is valid JSON but not what the route takes (a wrong type, a value out of range) is 422 validation_failed, and a field the route does not read is refused with 422 instead of being dropped, so a misspelt field is an answer rather than a success that changed nothing.

Request2026-06-01, 2026-08-252026-10-20
a body that fails the route's schema400422
a body with a field the route does not readaccepted, the field dropped422, the field named
a body that is not JSON400400 (unchanged)

On every version, each refusal lists its problems in error.details.issues, one { "path", "message" } per problem, where path names the field (rules[0].amountFrom). companyId is accepted on every body; a platformId is refused 400 invalid_parameter on every version on a route that needs a credential (see October 2026). A public route (/auth/login, /signup and the like) refuses it like any other unknown body field. POST /payment-types/suggest keeps reading a whole payment and ignoring the fields it does not use.

What to do:

  • Send only the fields each route documents before you move your pin.
  • If you branch on the status, handle 422 wherever you handle a refused write.
  • Nothing forces you to move. Keep sending 2026-08-25 and you keep the 400 and the dropped field.

2026-08-25

Pin this version to get a clear line between the two client errors. A payment body that arrives as valid JSON but is not a valid canonical payment (a missing required field, a wrong type, a null where an object belongs) is 422 validation_failed, with every problem listed in error.details.issues. On 2026-06-01 the same defect is 400 on some routes and 422 on others.

Request2026-06-012026-08-25
POST /journal/payments, a transaction with no creditor account400422
POST /journal/payments/preview, same body400422
POST /convert/{bank}, body null, 42, [] or {"payments":[null]}400422
POST /convert-async/{bank}, same bodies400422
POST /validate/{bank}, same bodies400200, valid: false
a payment that parses but breaks a rule422422 (unchanged)
a body that is not JSON at all400400 (unchanged)

The boundary is one sentence: 400 means we could not read your request, and 422 means we read it and the payment is not one we can process. Neither is retryable as sent.

POST /validate/{bank} is a report endpoint, so it reports a schema failure inside its 200, as { "valid": false, "issues": [...] }, the same way it reports every other problem. That lets it tell you in advance what POST /convert/{bank} will answer.

What to do:

  • If you branch on the status, handle 422 wherever you handle a rejected payment, and read 400 as "my request was malformed" only.
  • If you read error.details.issues, nothing changes: it is in the same place under both statuses and both versions.
  • If you treat a non-200 from POST /validate/{bank} as "could not validate", read valid instead. This is the one change that could make a rejection look like a success, so it is the one to search your code for.
  • Nothing forces you to move. Keep sending 2026-06-01 and you keep the 400 answers.

2026-06-01

The baseline, and the version you get when you send no header. A payment that fails the schema check is 400 on POST /convert and POST /convert-async, for every shape of failure.

Contract changes

This page lists the changes to the HTTP contract that you might need to act on or would want to use, one overview per month. A breaking change takes effect for every version, so watch this page whichever version you pin. A removal, a rename or a changed status is marked as such in the month's overview. Small additions, such as a new optional field, appear in the API Reference and are not repeated here.

November 2026

November so far tightens one approval-policy rule and retires the sandbox's one-call provisioning.

  • Removed: POST /sandbox/provision and POST /sandbox/provision/verify, on every version; both answer 404. Get a sandbox by signing up at https://sandbox.bankconnector.com/signup and create an API key under Company settings › API keys. See Getting started.
  • Changed: POST /approvals/policies and POST /approvals/policies/{id} refuse a custom policy with orderedApproval: true unless at least two entries of groups each have a name and an approver, with validation_failed on groups. Send a second named step, or orderedApproval: false for a policy one approver may release.
  • Changed: on POST /journal/payments, a retry that arrives while the same Idempotency-Key or payment.messageId is still being processed answers 409 request_in_progress, not 409 conflict, on every version. Retry it unchanged after a short wait. 409 conflict now means only that the key or messageId was used with a different body: never retry that as it is. Branch on code; the message text is no longer needed to tell them apart. See Errors & retries.
  • Changed: on the sandbox, a payment waits for approval as it does in production once your company has an active approval policy for the bank: POST /journal/payments answers pending-approval and POST /journal/payments/preview says approval.required: true when that policy requires it. While no policy is active, the sandbox still releases payments without approval. Production is unchanged.
  • Changed: POST /journal/documents/{id}/signer-release releases or cancels a held payment only for an approver the approval policy governing the payment's bank names, in the browser and the ERP add-on. Anyone else, an Approver invited from the ERP and not yet named included, is 409 approver_not_designated, and GET offers them no act, with that code in refusal.

October 2026

October added follow-up for payments the bank has not settled, a verification-only file for checking payees, and signup that waits for approval. A client that matches on a removed path, field or code must change; the rows say what to do.

KindEndpointWhat to do
ChangedPOST /usersAn email address whose login belongs to another organisation answers the same 201 as a new invitation, not 409 conflict. No login is made: the person is listed in GET /users as invited, and a second invite of the address is 409 conflict. An address already in your own organisation is still 409 conflict.
ChangedPOST /signup, POST /partners/registerAn email address that already has a BankConnector login answers the same 202 as a new address, not 409 conflict; its owner is emailed how to sign in. POST /partners/register no longer answers 502 email_send_failed: resend a link that did not arrive with POST /partners/register/resend.
New statusPOST /signup/verify, every authenticated requestA self-service signup waits for BankConnector to approve it. POST /signup/verify answers 200 with awaitingApproval: true and no API key; until the approval email arrives, POST /auth/login and every authenticated request of that organisation answer 403 forbidden. Treat awaitingApproval as "no credential yet".
NewPOST /users/{id}/sign-outAn Admin ends every live session of a colleague. Answers 200 with revoked, the sessions ended.
ChangedDELETE /me/sessions, DELETE /me/sessions/{id}Signing out another of your sessions asks for a fresh factor in the JSON body: a current 2FA code (or backupCode) when you have two-factor authentication, otherwise your current password. Without it the answer is 422 (totp_required, totp_enrollment_required or reauth_required). Signing out the calling session needs nothing.
RemovedGET /bank-coverage-requests/demand, PATCH /bank-coverage-requests/{id}Both refused every caller with 403 and now answer 404. GET and POST /bank-coverage-requests are unchanged.
Removedpassword on POST /usersThe route only invites; the person sets their own password from the emailed link. On 2026-10-20 and later a password is refused as an unknown field (422); on an older pin it is ignored. Stop sending it.
ChangedSandboxEvery pain.001 file is built in pain.001.001.09 whatever the bank, and ?painVersion= on the conversion routes is ignored. A bank's payment types are listed only once your organisation has a connection to that bank: GET /profiles leaves paymentTypes out for the others, and GET /banks/{bankKey}/payment-types answers 403 forbidden. Production is unchanged.
ChangedBank setup guidesWebhooks can subscribe to a new event, bank-guide.access-revoked: we withdrew an approved bank guide request, and the bank's guide is locked again unless your organisation has a connection to it. Danske, Bank Connect, Nordea Corporate Access and OP banks stay open to every organisation.
ChangedPOST /journal/documents/{id}/signer-releaseReleases or cancels a payment a German or Austrian bank holds after its payee check (awaiting-signer-release) on an EBICS connection with authorisationMode: "at-upload", the default. An Approver reads the result and decides, and the company's EBICS subscriber signs. It answered 422 ebics_signer_missing there.
AddedGET /journal/list, GET /journal/documentsEach row carries environment ("test" or "production"). A bank's test system can send statements for a real account; an integration that books statements skips the "test" rows.
Changedfile.received eventNo longer raised for an EBICS customer protocol (HAC) that finally refused no order; every poll fetches one. The document is still stored. A protocol that did refuse an order still raises it. If you counted file.received as proof of a successful poll, count something else.
AddedPOST /webhookstransport: "teams" posts each event into a Microsoft Teams chat or channel as a card; see Webhooks. A webhook's transport can now read "teams".
ChangedPOST /webhookseventTypes refuses with 400 validation_failed an event name only our own staff chain writes (partner.created, bankkey.imported and the like), as it refuses an unknown name. No customer endpoint ever received these. GET /webhooks reports one an endpoint already holds in unknownEventTypes; remove it to clear the warning.
Changed"*" webhook subscriptionA "*" subscription (or one created without eventTypes) receives the events in the event catalog and no others. To keep receiving an event the catalog does not list, name it in eventTypes.
ChangedEvery route that needs a credentialA request that states platformId, in the query string or the JSON body, answers 400 invalid_parameter naming the parameter, on every version. A public route refuses it like any other unknown body field. Name the organisation with companyId alone, and send no platformId, not even an empty one.
ChangedPOST /connections/{id}/ebics-hev, ebics-send-ini, ebics-fetch-hpb and the other EBICS setup stepsA call to the bank that fails, including a host name that does not exist, answers 502 bank_unavailable with error.details.nextSteps. It answered 500 internal_error.
ChangedPOST /approver-identityA fødselsnummer that is not valid, or a District user ID that is empty or over 35 characters, is validation_failed (422 on 2026-10-20, 400 before it). It answered 422 on every version.
ChangedPOST /company/require-2faA body without enabled is validation_failed (422 on 2026-10-20, 400 before it). It read a missing enabled as false and turned the requirement off. Send "enabled": false to turn it off.
ChangedPOST /connections/{id}/approversAn approval-governance refusal has its own code (409 policy_change_in_flight, 422 policy_quorum_shortfall, 400 policy_roster_invalid), as on POST /approvals/bank-rosters. It answered 500 internal_error.
NewGET /banks/{bankKey}/sftp-namingAnswers the server, logins, folders and payment file name a TietoEvry bank's agreement gives (SpareBank 1, Eika and the other savings banks on TietoEvry's shared SFTP), before anything is saved. A bank whose setup guide your organisation has not been given answers 403 bank_guide_access_required, as POST /connections does.
NewGET /profiles/membersLists the Sparkassen and cooperative banks (Volksbanken, Raiffeisenbanken) the German group profiles serve, each with its town, BIC, bank codes and bankKey. Match a customer's bank name, BIC, bank code or IBAN against it, and save the member with memberBankCode on PATCH /banks/{bankKey}/settings.
ChangedPATCH /banks/{bankKey}/settingsA memberBankCode that would change the member bank of a group profile the company has a connection on, or a setup in progress for another member, answers 409 member_bank_locked. The first choice, and sending the stored member again, pass.
New versionAll routes2026-10-21: a connection request refused because the connection is not ready is 409 invalid_state; a value that cannot be used stays 422 validation_failed. See 2026-10-21.
New versionAll routes2026-10-20: a request body that fails its route's schema is 422, and a field the route does not read is refused, naming the field. See 2026-10-20.
ChangedPOST /users, connection routesA refusal carries one code wherever it is raised. POST /users answers 409 conflict for an email address already registered (it was 400 bad_request). A connection route naming an unknown or deleted connection answers 404 connection_not_found (some answered 400 validation_failed or 404 not_found). On 2026-10-20 a connection's validation_failed refusal is 422.
ChangedGET /connections/{id}/ebics-letterBefore the subscriber keys exist: 409 invalid_state on 2026-10-21, 400 validation_failed on earlier versions (it was 404).
ChangedPOST /connections/{id}/ebics-paramsA new signatureVersion once the EBICS connection's keys went to the bank is refused and saves nothing: 409 invalid_state on 2026-10-21, 400 validation_failed before. It saved the version before, and the next upload was signed in a version the bank had not registered. Set the version before you send the keys.
ChangedPOST /connections/{id}/server-infoAn SFTP host-key pin that is not a SHA-256 fingerprint (hostFingerprint, downloadHostFingerprint) is refused and nothing is saved: 422 validation_failed on 2026-10-20, 400 before. Send SHA256: plus base64 or 64 hex characters; either is stored as SHA256: plus unpadded base64.
ChangedGET /webhooks/{id}/deliveries, POST /webhooks/{id}/redeliver-failedA different nextCursor (still opaque), a malformed cursor is 400 invalid_cursor, and the last page ends with nextCursor: null, even when exactly full. A cursor issued before this change, or built from a delivery's id, is malformed: pass nextCursor back as it came. redeliver-failed refuses a since that is not a real ISO-8601 date or time with 400 invalid_since.
ChangedGET /accounts, GET /company/api-keys, GET /me/organisations, GET /approvals/pending, GET /approvals/oversightA different nextCursor (still opaque), and a malformed cursor is 400 invalid_cursor. A cursor issued before this change, or built from an item's id, is malformed: pass nextCursor back as it came. The two approval lists end with nextCursor: null on the last page, even when it holds exactly limit requests.
ChangedGET /journal/documents, /journal/list, /journal/events, /journal/reconciliation, GET /bank-coverage-requestsA list's last page carries nextCursor: null even when it holds exactly limit items. GET /bank-coverage-requests refuses a malformed cursor with 400 invalid_cursor; a cursor it issued before this change is malformed.
RenamedRemittance warning codesFour warnings carry one code each, whatever bank or standard raises them, on every version: BANK_REMITTANCE_DOCUMENTS_AS_TEXT, BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT, BANK_REMITTANCE_TEXT_NOT_SENT and BANK_REMITTANCE_TEXT_JOINED. The old spellings had a bank or standard in the prefix (BANK_SE_, BANK_SEPA_, BANK_NPC_, BANK_NL_). Message, path and severity are unchanged. If you match on an old code, match on the new one.
RenamedValidation issue codes64 codes take their level's prefix, BANK_ on a bank issue and PAYMENT_TYPE_ on a payment-type issue, on every version, and only the prefixed spelling is sent (NEMKONTO_DKK_ONLY is BANK_NEMKONTO_DKK_ONLY). If you match on any of them, match on the prefixed code. The list is at the end of this month.
ChangedmessageId, paymentId, endToEndId, instructionIdAn id made only of whitespace or invisible characters (the zero width space, the soft hyphen), or only of emoji or control characters, is refused as a schema failure naming the field, because the payment file would carry an id that reads as empty. /convert answered 200 with an empty id element before. Such characters beside other characters are accepted, and emoji are written without the emoji.
ChangedEvery list routeA value that is not allowed (type, direction or status outside its set) or a limit that is not a number answers 400 invalid_parameter, naming the parameter, instead of an empty or unfiltered page. GET /approvals/pending and GET /approvals/oversight page with cursor, as every other list does; after still works. To poll for documents use GET /journal/list?uncollectedOnly=true.
New statusPOST /connections/{id}/ws-certificateWith action: "renew", answers 409 renewal_in_progress while another renewal of the same connection is running. Nothing reached the bank; read the connection again after a minute for the new expiry.
AddedReferenceAlready served, now in the API reference: GET /approvals/policy, GET /journal/documents/{id}/raw-pain002 (the bank's original pain.002 status report) and POST /payment-types/suggest.
RemovedThe twelve Web Services certificate pathsPOST /connections/{id}/activate-danske, /activate-nordea, /activate-op, /activate-samlink, /activate-crosskey, /activate-bankconnect and the six /renew-* paths now return 404. Use POST /connections/{id}/ws-certificate with action (activate or renew) and family, the kind that GET /banks/{bankKey}/setup-info serves for the bank. Fields and errors are the same, except that an unknown connection answers 404 connection_not_found and a family that is not the connection's own is 400 validation_failed. Only a signed-in Admin calls it.
ChangedGET /accounts/statementsOne page of the list envelope: items replaces statements, and nextCursor (pass it back as ?cursor=, ?limit= up to 500) points at the next older page. account and gaps stay; each page's gaps are the ones whose later statement is on that page. Follow nextCursor until it is null.
RemovedGET /versionAnswers as any unknown path does. The API reference's version is the contract date you send in BankConnector-Version.
ChangedPATCH /company/name, GET /company/legal-identityAn Admin renames their own organisation with PATCH /company/name. GET /company/legal-identity needs a signed-in Admin; an API key gets 403. To erase an organisation or hold its data, ask us.
Removedguide.fieldCopy, bankConnect.fieldCopy on GET /banks/{bankKey}/setup-infoEach entry of fields[] carries the same label, placeholder and help, in the order the enrolment form asks for them.
Removedapproval.limitEquivalence on the POST /journal/payments responseThe response's approval is the request as GET /approvals/pending shows it.
RemovedgrantsRevoked on DELETE /connections/{id}; the granted value of reachableBanks[].access on GET /dashboard; the event connection.grant-withdrawnA bank connection belongs to one organisation and is not shared with another.
RemovedplatformIdGone from every response and from the webhook envelope, on every version. Key on companyId. A request that states it is refused (see the platformId row above).
RenamedPOST /connections/{id}/platform-bank-keyNow POST /connections/{id}/registry-bank-key (the old path returns 404); a connection's usePlatformBankKey is useRegistryBankKey and platformBankKey on GET /connections/{id} is registryBankKey. Each still means BankConnector's copy of the bank's PGP key, and each connection keeps its choice.
RemovedApproval policy versionsA policy keeps one id and is changed in place, so version, predecessorId and supersededById are gone and status is draft or active. POST /approvals/policies/{id}/propose and POST /approvals/changes/{changeId}/submit return 404; a pending policy change is the kind policy-edit with its proposed rule in proposed; the error code policy_superseded is retired.
New statusPOST /signupThe company register must find the company. A number it does not know, or lists as inactive, is 422 on registrationNumber; a register that gives no answer is 503 service_unavailable naming the number's field, and the same signup can be sent again in a moment. A country with no register lookup signs up with the name and address as sent. Send the lookup's registerAnswer back with the signup.
New statusPOST /journal/ingest, POST /inbound/statementA statement file stating an amount or credit/debit indicator we cannot read is 422 incomplete_statement, and error.details.parseIssues names each field. Nothing from the file is stored. A file of this kind fetched from the bank sends no statement.imported; we keep it and deliver it once we can read it.
New stateReconciliationState unconfirmed appears once a bank report is 5 banking days overdue. Check with the bank before paying again; see Receiving Results.
NewGET /journal/payments/batch?messageId=Shows what BankConnector holds for a batch you sent and got no answer for. Only not-found means you may send it again, under a new messageId.
AddedresendOf on a paymentLink a re-issued payment to the refused one; the original batch's GET /journal/documents/{id}/payments then reports refusals.
NewPOST /journal/payee-verificationsChecks payees with a verification-only file; the results arrive as a file.received event.
New valuecompany.inactiveReasons in a company register lookupCan read insolvency. A UK company number is looked up in Companies House on POST /signup/register-lookup and POST /partners/register/lookup.
NewGET /banks/liveLists the banks your organisation has an active connection to, per environment.
ChangedGET /journal/documentsWithout limit returns up to 1000 documents a page with a nextCursor to follow; a malformed cursor is 400 invalid_cursor with or without limit.
NewGET /journal/documents/{id}/export.camt053Returns a bank statement as camt.053.001.02 for an ERP's own statement import, whatever format the bank sent and after its original file has expired.
NewPOST /connections/{id}/intraday-reportFetches the bank's intraday account report (camt.052) now. A connection asks its bank at most once per 15 minutes: a request inside them gets the last report again, with reused: true and its fetchedAt.
ChangedNorwegian savings banksThe SpareBank 1 and Eika banks are each listed under their own key and name (for example jaeren-sparebank-no), and eika-alliance-no and sparebank-1-alliance-no are removed. Connect to the customer's own bank; its setup takes the bank ID from knownServer.bankId on GET /banks/{bankKey}/setup-info.
ChangedPOST /connections/{id}/activate, DNB NorwayRefused for a dnb-no connection until its customer number, division number and the certificate that signs its payment files are on it; asks for no PGP keys. PUT /connections/{id}/asic-signing-material answers 400 validation_failed for a certificate and key that could not sign a payment file.
ChangedPOST /connections/{id}/activate, SpareBank 1 and EikaRefused for a connection that runs through TietoEvry until its PGP key pair is generated, TietoEvry's PGP public key is added and the SFTP password TietoEvry issued is stored. Setup asks for all three (GET /banks/{bankKey}/setup-info).
ChangedSpareBank 1 company settingsA company's noApproverCodesEnabled starts true on its first settings save at a SpareBank 1 bank (for example sr-bank-no), as at Nordea Norge, Danske Bank Norge and DNB. If the company approves in the bank's netbank, send false on that first save. Companies already connected keep their answer.
ChangedPOST /connections/{id}/ebics-fetch-hpb, POST /connections/{id}/activateOnce the EBICS connection has gone live, ebics-fetch-hpb is refused before it contacts the bank (409 invalid_state on 2026-10-21, 400 validation_failed before), and activate refuses a deactivated EBICS connection the same way. Fetch a live connection's bank keys with POST /connections/{id}/ebics-refetch-hpb, which shows changed fingerprints and stores new keys only when you accept them.
New statusPOST /connections/{id}/ebics-fetch-hpb409 ebics_bank_keys_untrusted when the bank's EBICS keys are refused: a published fingerprint that does not match, a key-management mode the bank publishes no fingerprints for, or an answer naming another Host ID. details.reason says which. These answered 500 before; nothing is saved either way.
ChangedPOST /connections/{id}/ebics-fingerprints-confirmed409 ebics_bank_keys_untrusted (details.reason: fingerprint_mismatch) when the connection's bank keys differ from a fingerprint the bank publishes. It recorded a confirmation before; now nothing is recorded, and the next step is to fetch the bank's keys again.
Renamed validation issue codes

36 codes take their level's prefix. Each keeps its old spelling after the prefix (ACH_ROUTING_REQUIRED is PAYMENT_TYPE_ACH_ROUTING_REQUIRED): ACH_ROUTING_FORMAT, ACH_ROUTING_REQUIRED, CH_QR_REFERENCE_CHECKDIGIT_INVALID, CH_QR_REFERENCE_REQUIRED, EFT_CAD_ONLY, EFT_CREDITOR_ACCOUNT_REQUIRED, EFT_ROUTING_REQUIRED, BANK_OFFERS_NO_PAYMENT_TYPES, ING_NL_CTGYPURP_IGNORED, NVB_INITIATING_PARTY_NAME_OR_ID, TRUIST_LCLINSTRM_REQUIRED, USBANK_DEBTOR_AGENT_ID_REQUIRED, BANKCONNECT_BEC_NON_BANKING_DAY_REJECTED, CREDITOR_REFERENCE_TYPE_MISSING, DE_AXZ_LOCAL_INSTRUMENT_DROPPED, DE_CCU_CHARGE_BEARER_SUBSTITUTED, DE_CCU_LOCAL_INSTRUMENT_PROPRIETARY_DROPPED, DK_ADDRESS_COUNTRY_ONLY_DROPPED, DK_ADDRESS_ULTIMATE_PARTY_DROPPED, DK_ADDRESS_ULTIMATE_PARTY_OMITTED, DK_FIK_KORTART_NOT_OFFERED, FIXED_CREDITOR_AGENT_COUNTRY_OVERRIDDEN, FI_ADDRESS_HYBRID_TOO_MANY_LINES, FI_INVOICES_WITHOUT_CREDIT_NOTE_NOT_ERI, FR_ADDRESS_LINES_ONLY, NEMKONTO_DKK_ONLY, NEMKONTO_DOMESTIC_ONLY, NL_ADDRESS_LINES_ONLY, PROFILE_HMRC_RTI_REFERENCE_NOT_SENT, PROFILE_SERVICE_USER_NUMBER_CONFLICT, PROFILE_SERVICE_USER_NUMBER_NOT_SENT, PROFILE_SERVICE_USER_NUMBER_OVERRIDDEN_BY_ULTIMATE_DEBTOR, SEPA_INSTANT_PAIN_VERSION_UNSUPPORTED, SEPA_NON_EEA_DEBTOR_ADDRESS_INCOMPLETE, SEPA_NON_EEA_DEBTOR_COUNTRY_REQUIRED, SEPA_REMITTANCE_TEXT_NOT_SENT.

28 more take the BANK_ prefix the same way: ADDRESS_DERIVATION_COUNTRY_MISSING, ADDRESS_DERIVATION_COUNTRY_UNSUPPORTED, ADDRESS_DERIVATION_POSTCODE_CONFLICT, ADDRESS_DERIVATION_TOO_MANY_LINES, ADDRESS_DERIVATION_TOWN_AMBIGUOUS, ADDRESS_DERIVATION_TOWN_NOT_FOUND, ADDRESS_DERIVATION_TOWN_TOO_LONG, ADDRESS_DERIVATION_VERSION_UNSUPPORTED, DEBTOR_ADDRESS_NOT_FILLED_COUNTRY_CONFLICT, DEBTOR_ADDRESS_NOT_FILLED_NO_REGISTERED_ADDRESS, DEBTOR_ADDRESS_NOT_FILLED_OTHER_PARTY, DENMARK_ADDRESS_COUNTRY_REQUIRED, DENMARK_ADDRESS_HYBRID_TOO_MANY_LINES, DENMARK_ADDRESS_TOWN_REQUIRED, DK_ADDRESS_COUNTRY_REQUIRED, DK_ADDRESS_LINE_TOO_LONG, DK_ADDRESS_TOO_MANY_LINES, DK_ADDRESS_TOWN_REQUIRED, FI_ADDRESS_COUNTRY_REQUIRED, FI_ADDRESS_TOWN_REQUIRED, FI_URGENT_LOCAL_INSTRUMENT_CONFLICT, FI_URGENT_SALARY_NOT_INSTANT, FI_URGENT_SEPA_INSTANT_UNAVAILABLE, SEPA_REMITTANCE_ADDITIONAL_INFO_NOT_SENT, SEPA_REMITTANCE_ADDITIONAL_INFO_UNSUPPORTED, SEPA_REMITTANCE_DOCUMENTS_AS_TEXT, SEPA_REMITTANCE_TEXT_AND_REFERENCE, SEPA_REMITTANCE_UNSTRUCTURED_REPEATED.

September 2026

September added payment states to handle, a banking-day lookup and the bank's payee check for German and Austrian SEPA files.

  • Removed fields: approverUserIds on connections (read GET /approvals/bank-rosters), payload.rawXml on GET /journal/documents/{id} (fetch GET /journal/documents/{id}/file, see Receiving Results). The approver's masked ID is ssnFirst6, not ssnLast4.
  • New states to handle: payment status awaiting-signer-release (at the bank, waiting for your signers), payment status rejected-by-approver (final, never sent), reconciliation state not-sent (the bank never received it) and statement status unknown (an entry code we do not recognise, never treated as settled money). See Receiving Results.
  • Changed: GET /profiles lists each bank's paymentTypes as codes, and one-time links carry their token after #.
  • Submitting payments: a messageId is one payment, so re-sending one returns the original, or 409 message_id_already_used when that payment was rejected or cancelled; send a corrected payment under a new messageId. From 30 days past due, POST /journal/payments answers 402 billing_past_due, and an unpaid invoice adds a BankConnector-Billing-Warning header to every response.
  • GET /banking-days/adjust returns the banking day on or next to a date. A SEPA file to a German or Austrian EBICS bank goes out with the bank's payee check, set for multi-payment files by GET/PATCH /company/payee-verification.

August 2026

Show the August changes

August introduced dated versions and made the journal's names consistent.

  • Removed: /bank-requests is now /bank-coverage-requests, and the old path returns 404.
  • Removed and renamed fields: whole-document responses no longer return slaAlertSentAt or sideEffectsCompleted, and retrieved, retrievedAt, unretrieved and wasAlreadyRetrieved are collected, collectedAt, uncollected and wasAlreadyCollected, with matching filters.
  • New version 2026-08-25: a payment we cannot process is 422, not 400. See 2026-08-25.