sandbox.bankconnector.com API Reference

Validation reference

Audience: 🔌 Integration Client

When a payment is rejected, the reasons come back as a list of issues in error.details.issues, under 422 and under 400 alike, so one parse handles both. Each issue looks like:

{
  "code": "PAYMENT_TYPE_SEPA_EUR_ONLY",
  "level": "payment-type",
  "severity": "error",
  "message": "SEPA payments must be in EUR.",
  "path": "payments[0].transactions[0].currency"
}
  • severity is error (blocks) or warning (informational: the payment still proceeds). It's omitted when it would be error (the default); check valid / the absence of error-severity issues to know if a payment can proceed.
  • level tells you which stage raised it: generic, bank, or payment-type.

Validation runs in four levels, and stops at the first structural failure:

  1. Structural (schema): if the JSON doesn't match the canonical schema, you get only GENERIC_SCHEMA_* issues and nothing else runs. On BankConnector-Version: 2026-08-25 this returns 422, the same as a payment that fails a semantic rule (levels 2–4 below). Both mean "we read your request and cannot process this payment". A body that is not JSON at all is a 400. ⚠️ On 2026-06-01 (and with no version header) a schema failure is a 400 instead; see the changelog.
  2. Generic rules: currency, amount, dates, references (below).
  3. Bank rules: per-bank requirements (BIC required, national account checksums, etc.).
  4. Payment-type rules: per scheme (SEPA EUR-only, KID checksum, etc.).

Generic rules (apply to every payment)

CodeSeverityMeaning
GENERIC_SCHEMA_*errorJSON failed the canonical schema (per-field codes, e.g. GENERIC_SCHEMA_AMOUNT_REQUIRED)
GENERIC_AMOUNT_POSITIVEerroramount ≤ 0 (so "0.00" fails here)
GENERIC_AMOUNT_PRECISIONerrora non-zero sub-unit the currency can't represent (e.g. "1000.50" JPY). Trailing zeros ("1000.00") are fine; the engine converts precision for you
GENERIC_CURRENCY_CODE_INVALIDerrornot an active ISO 4217 code
GENERIC_COUNTRY_CODE_INVALIDerrora country on any party (debtor, creditor, their agents, ultimate parties, regulatory reporting) is not an assigned ISO 3166-1 alpha-2 code. UK is accepted and sent as GB
GENERIC_PAYMENT_ID_DUPLICATEerrorpaymentId reused across payments
GENERIC_END_TO_END_ID_DUPLICATEerrorendToEndId reused in the batch
GENERIC_INSTRUCTION_ID_DUPLICATEerrorinstructionId reused in the batch. InstrId is a point-to-point de-duplication reference, so a repeat can silently drop a real payment
GENERIC_CREDITOR_REFERENCE_RF_INVALIDerrorRF reference fails ISO 11649 mod-97
GENERIC_CREDITOR_REFERENCE_KID_INVALIDerrorKID fails MOD10/MOD11
GENERIC_CREDITOR_REFERENCE_OCR_INVALIDerrora reference typed ocr is not a Swedish OCR reference: 2–25 digits with a valid modulus-10 check digit
GENERIC_CREDITOR_REFERENCE_OGM_INVALIDerrorBelgian structured communication (OGM/VCS) is not 12 digits or fails its mod-97 check
GENERIC_CREDITOR_REFERENCE_VIITE_INVALIDerrora reference typed viite is not a Finnish creditor reference: 4–20 digits with a 7-3-1 check digit
GENERIC_CREDITOR_REFERENCE_KENMERK_INVALIDerrora reference typed kenmerk is not a Dutch payment reference: 7–16 digits, a 16-digit one with a valid modulus-11 check digit first
GENERIC_FIK_CREDITOR_ACCOUNT_NEEDS_FIK_TYPEerrorthe creditor account is a Danish FIK/giro creditor number (scheme FIK, or OCR at a DK/GL/FO bank) on a payment whose type is not fik, only a FIK payment can pay it
GENERIC_IBAN_FR_BBAN_FORMAT_INVALIDerrora French IBAN whose BBAN is not 5 digits (bank), 5 digits (branch), 11 digits or letters (account), 2 digits (clé RIB)
GENERIC_IBAN_FR_RIB_KEY_INVALIDerrora French IBAN whose clé RIB does not match its bank code, branch code and account number
GENERIC_IBAN_NL_BANK_CODE_INVALIDerrora Dutch IBAN without the 4-letter bank code (then 10 digits) in positions 5-18
GENERIC_IBAN_NL_BANK_CODE_UNKNOWNwarninga well-formed Dutch IBAN whose 4-letter bank code is not on the Betaalvereniging BIC list; it is sent as given
GENERIC_IBAN_DE_BANK_CODE_UNKNOWNwarninga well-formed German IBAN whose bank code is not a live code in the Bundesbank Bankleitzahlendatei, or is one it lists as deleted; it is sent as given
GENERIC_IBAN_BE_BBAN_FORMAT_INVALIDerrora Belgian IBAN whose BBAN is not 12 digits
GENERIC_IBAN_BE_ACCOUNT_KEY_INVALIDerrora Belgian IBAN whose last 2 digits are not the first 10 mod 97 (97 for a remainder of 0)
GENERIC_BE_ENTERPRISE_NUMBER_INVALIDwarninga Belgian enterprise number (scheme KBO / KBO-BCE) that is not 10 digits with valid check digits; it is sent as given
GENERIC_PURPOSE_CODE_NOT_PLACEABLEerrora purposeCode override longer than the ISO Purp/Cd limit (4 chars) with no corridor rule to place it. Use a 4-char ISO code, or supply regulatoryReporting explicitly
GENERIC_BIC_IBAN_COUNTRY_MISMATCHwarningBIC country ≠ IBAN country
GENERIC_CREDITOR_REFERENCE_VIITE_CHECK_FAILEDwarningan untyped or scor all-digit reference to a Finnish account fails the viitenumero 7-3-1 check; it is sent as given
GENERIC_CREDITOR_REFERENCE_KENMERK_CHECK_FAILEDwarningan untyped or scor 16-digit reference to a Dutch account fails the betalingskenmerk modulus-11 check; it is sent as given
GENERIC_EXECUTION_DATE_PASTwarningdate is in the past
GENERIC_EXECUTION_DATE_FAR_FUTUREwarningmore than a year ahead
GENERIC_EXECUTION_DATE_NON_BANKINGwarningweekend/holiday; suggests next banking day
GENERIC_EXECUTION_DATE_INTL_TOO_SOONwarninga cross-border payment to a country whose banking calendar isn't modelled, with little lead time. International settlement usually needs a few business days
GENERIC_EXECUTION_DATE_AFTER_CUTOFFwarningthe execution date is today and the bank's published cut-off has passed, so the bank will usually value-date it the next banking day. Only for a bank whose cut-off we hold
GENERIC_EXECUTION_DATE_BACS_LEAD_TIMEwarninga Bacs payment's execution date gives fewer than 2 GB working days of lead time (Bacs' own Translation Guide §4.9), counted from the next GB banking day when today is a weekend
GENERIC_MIXED_CURRENCY_BATCHwarningmore than one currency in one payment

The duplicate-id errors matter: banks de-duplicate on paymentId, endToEndId and instructionId and may silently drop repeats, so BankConnector blocks them up front. Keep them unique within a batch.

Cut-off times

A bank stops accepting orders for same-day execution at a deadline it publishes itself, its _cut-off_. Submit a payment dated today after that time and the bank will usually value-date it on the next banking day, so an urgent-rail fee buys a next-day execution. GENERIC_EXECUTION_DATE_AFTER_CUTOFF tells you before you send it, and names the deadline and the current time in the bank's zone:

executionDate 2026-09-22 is today, and Postbank's published cut-off for this payment
(15:30 Europe/Berlin) has passed (it is 17:00 there). The bank will usually value-date
the payment on the next banking day. (Not rejected: send it anyway, or set the next
banking day as the execution date.)

It is a warning and never a rejection: a cut-off is the bank's operational deadline, not a scheme rule, and it varies per rail, channel and agreement. The payment stays your decision.

Which deadline applies depends on the rail your payment rides. A bank may publish separate times for SEPA credit transfers, urgent (TARGET2 / priority: "urgent") payments, foreign payments and even per currency, or a single blanket time for everything. SEPA instant is never flagged: it settles in seconds on any calendar day.

⚠️ Absence of this warning does not mean you are inside a cut-off. The engine only carries times it has read out of a bank's own price list or EBICS sheet; a time is never copied from a sibling institute or guessed. For a bank whose document we do not hold, or whose document names no time, the engine says nothing. Check the deadline with your bank.

Profile warnings (character set / truncation)

CodeSeverityMeaning
PROFILE_NAME_TRUNCATEDwarninga name was shortened to the bank's limit
PROFILE_REMITTANCE_TRUNCATEDwarningremittance text was shortened
PROFILE_CHARSET_TRANSLITERATEDwarningcharacters were transliterated to the rail's character set (the SEPA set; a German SEPA file keeps umlauts, ß and &)
PROFILE_NAME_CHARS_DROPPEDwarninga mixed-script name survives transliteration but loses characters that have no Latin rendering ("王伟 Ltd" → "Ltd"). The bank receives a materially different name (Confirmation-of-Payee mismatch risk). Supply the Latin form of the full name
PROFILE_ID_CHARSET_INVALIDwarningan identifier (messageId, paymentId, instructionId, endToEndId) has characters outside the SEPA set. Unlike names, ids are sent exactly as given, unchanged (to keep pain.002/camt correlation), so the bank may reject the batch or transcode the id and break correlation. Use only A–Z a–z 0–9 and / - ? : ( ) . , ' + and space
SEPA_ID_SLASH_INVALIDerroron a SEPA rail, an identifier (messageId, paymentId, instructionId, endToEndId) starts or ends with / or contains //, forbidden by the EPC SCT C2PSP Implementation Guidelines, CFONB and the German DK, and the bank rejects the batch. A single internal / stays legal (e.g. a Belgian OGM reference used as an id)
PROFILE_NAME_UNREPRESENTABLEerrora required name transliterates to empty (e.g. CJK-only)
PROFILE_NATIVE_CHARSET_UNSUPPORTEDwarninga bank that keeps text exactly as entered (no transliteration) has its own MIG-documented character set, and a name or remittance line carries characters outside it (e.g. Ω/中 sent to a bank whose MIG states Windows-1252, ISO-8859-1 or the SWIFT set). Nothing is filtered, the bank may substitute a look-alike, reject the file, or degrade the name. Only fires for the handful of banks whose own MIG states a set (one, jpmorgan-us, only on the one rail its MIG names it for); most non-transliterating banks have none on file

Transliteration runs before truncation, and it can expand text (ä→ae, ß→ss), so a name that looks short can still truncate.

Note the split between the two "lossy name" codes: PROFILE_CHARSET_TRANSLITERATED fires on any change (é→e counts); PROFILE_NAME_CHARS_DROPPED fires only when characters are removed outright, which is the one that actually changes who the bank thinks is being paid.

Bank-rule examples

Banks require different things. Common ones are below. Four remittance warnings carry one code whatever bank or standard raises them, and the message names the bank's rule: BANK_REMITTANCE_DOCUMENTS_AS_TEXT (the documents go out as one line of text), BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT (additionalInfo is left out), BANK_REMITTANCE_TEXT_NOT_SENT (text or documents beside the one remittance sent are left out) and BANK_REMITTANCE_TEXT_JOINED (two or more unstructured lines go as one).

  • BANK_BIC_REQUIRED: this bank requires the debtor BIC.
  • BANK_BIC_VALUE_INVALID: the debtor BIC doesn't match the expected institution.
  • BANK_DEBTOR_BIC_SUPERSEDED (warning): the debtor BIC belongs to a bank that merged into this one (Spar Nord Bank's SPNODK22 on Nykredit Bank). The payment is sent, and the file names the bank's current BIC.
  • BANK_INITIATING_PARTY_ID_REQUIRED: an initiatingParty.organisationId is required.
  • BANK_DEBTOR_COUNTRY_REQUIRED / BANK_DEBTOR_ACCOUNT_CURRENCY_REQUIRED.
  • BANK_BBAN_FORMAT_INVALID / BANK_BBAN_CHECKSUM_INVALID: national account number checks (Norwegian MOD-11, Danish structure, Polish NRB mod-97, Swedish clearing number + account length against the Bankgirot/Bankinfrastruktur register).
  • BANK_BBAN_CHECKSUM_UNCERTAIN (warning): a Swedish account under Swedbank's 5-digit clearing range (8000-8999) fails the modulus-10 check that range's source states applies only "as a rule". It is worth a second look and is not refused outright.
  • BANK_AE_REGULATORY_COUNTRY_UNKNOWN (warning): a UAE payment carries a purposeCode, which the engine reports as RgltryRptg/Dtls/Cd, but states no creditor.country (and no creditor IBAN to take one from). The sibling Ctry holds the beneficiary's residence country, so it is left out rather than guessed, and the UAE high-value rail requires it. Set creditor.country, or supply regulatoryReporting yourself.
  • BANK_CNY_CNAPS_MISSING (warning): a Société Générale France CNY payment names a creditor bank in mainland China (agent country or BIC country CN) but no CNAPS code. The French CFONB guide makes the CNAPS code mandatory there. Set creditor.agent.clearing to { "system": "CNAPS", "memberId": "<12 characters>" } and creditor.agent.name. It is a warning because the bank has accepted BIC-only files.
  • BANK_FOREIGN_CURRENCY_PURPOSE_OF_PAYMENT_REQUIRED (error): an HSBC Indonesia payment in a currency other than IDR lacks part of the purpose of payment the bank requires on it: the beneficiary's country (creditor.country, written as Cdtr/CtryOfRes), the beneficiary category and affiliation (regulatoryReporting.details[0].type) or the purpose of transfer (regulatoryReporting.details[0].code). One issue per missing part, at that field.
  • BANK_USTRD_SLASH_POSITION_REJECTED (error): an HSBC Indonesia remittance line has / at character 1, 36 or 71, which the bank's guideline says rejects the file. Move or remove the /.
  • BANK_EG_PURPOSE_OF_PAYMENT_REQUIRED (error): an HSBC Egypt payment states no purpose of payment. The Central Bank of Egypt requires one and HSBC rejects the payment without it, so the engine refuses it first. Set purposeCode, or send the description as regulatoryReporting.details[0].info[0] (bare, because choosing the /BENEFRES/EG// or /ORDERRES/EG// wrapper is the engine's job). Two siblings: BANK_EG_PURPOSE_OF_PAYMENT_TOO_LONG (error: the field leaves 21 characters for the description) and BANK_EG_RELATIONSHIP_EXPECTED (warning: an Egypt-to-Egypt foreign-currency payment owes the payer↔beneficiary relationship too, in remittance).
  • BANK_EG_PURPOSE_OF_PAYMENT_OTHER_NEEDS_DESCRIPTION (error): the purpose of payment is HSBC Egypt's published "Other" and nothing says what the payment is for. "Other" is one entry of the bank's own list and names nothing by itself, so send the meaningful purpose in regulatoryReporting.details[0].info[0] beside it.
  • BANK_CNY_BUSINESS_PURPOSE_REQUIRED (error): a cross-border CNY payment from an HSBC bank carries none of the five phrases HSBC accepts in RgltryRptg/Dtls/Inf: /BUSINESS/GOODS TRADE, /BUSINESS/SERVICE TRADE, /BUSINESS/CHARITY DONATION, /BUSINESS/CURRENT ACC TXN, /BUSINESS/CAPITAL TRF. Set purposeCode to GDDS, SCVE, CHAR, INTC or CAPX and the engine writes the phrase, or put the phrase itself in regulatoryReporting.details[0].info. A regulatoryReporting you send replaces the engine's line, so it must carry the phrase. A CNY payment to a creditor in the bank's own country owes nothing (HSBC China exempts domestic CNY). The sibling BANK_CNY_BUSINESS_PURPOSE_EXPECTED (warning) says the same where the payment names no destination (no creditor.country, creditor IBAN or creditor agent BIC), so the engine cannot tell whether it crosses a border.
  • BANK_CNY_PAIN_VERSION_ADVISED (warning): a CNY payment to Mainland China, or one that names no destination, is built in a pain.001 version other than the one the bank's own notes ask for. HSBC Germany's "Notes for foreign currency payments" ask for pain.001.001.03, so a connection set to pain.001.001.09 gets this warning. The file is still built. Ask the bank whether it takes the payment in that version, or set the connection's pain.001 version to the one the note names.
  • BANK_BNP_SEPA_CATEGORY_PURPOSE_NOT_ALLOWED (error): a SEPA credit transfer from a BNP Paribas account carries categoryPurpose SALA, INTC, INTE, FCOL or FCIN. This applies at BNP Paribas in France, Germany, Spain, the Netherlands, Ireland, the UK, Bulgaria and Hungary, and at BNL (Italy), BGL BNP Paribas (Luxembourg) and BNP Paribas Bank Polska: the entities BNP's European SEPA guideline (SEPACT MX v3, 4 May 2026) lists. Rule BNPP_CtgyPurpCd_02 does not allow SALA or INTC; BNP takes payroll and intra-company transfers as separate PAYR and INTC orders, which BankConnector does not build for BNP. Rule BNPP_CtgyPurpCd_01 does not allow INTE, FCOL or FCIN, citing the 2021 SEPA Rulebook. Remove categoryPurpose to send the payment as an ordinary SEPA transfer. SEPA Instant payments are not affected.
  • BANK_DANSKE_SEPA_INSTANT_NOT_HONOURED (error): a SEPA Instant payment from a Danske Bank account in Denmark, Finland, Ireland or Sweden carries categoryPurpose SALA, INTC or URGP, or SDVA in Finland only. Danske's CGI-MP Appendix (v5.3, Appendix J) says it ignores the SEPA Instant marker on salary, group (intra-company) and urgent payments, and on capital payments in Finland, and sends them as ordinary SEPA payments, so the payment would not be instant. This covers an explicit sepa-instant payment and, in Finland, an urgent euro payment, which is sent as SEPA Instant there. Remove categoryPurpose to send it as SEPA Instant, or send it as sepa (in Finland, without priority: "urgent").
  • BANK_SEPA_REMITTANCE_TEXT_AND_REFERENCE, BANK_SEPA_REMITTANCE_UNSTRUCTURED_REPEATED (errors): a SEPA credit transfer from a German or Belgian bank carries more remittance than the national standard allows. The German standard (DK, DFÜ-Abkommen Anlage 3) and the Belgian one (Febelfin) allow one unstructured line or one creditor reference, never both. Send either unstructured (one line of at most 140 characters) or creditorReference. additionalInfo is refused at a German bank (BANK_SEPA_REMITTANCE_ADDITIONAL_INFO_UNSUPPORTED, error) and left out at a Belgian bank, which ignores it (BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT, warning). A German same-day urgent euro payment (priority: "urgent", EUR) is held to one unstructured line too: a second line is refused with BANK_SEPA_REMITTANCE_UNSTRUCTURED_REPEATED. The sibling BANK_REMITTANCE_DOCUMENTS_AS_TEXT (warning) says that documents go out as that one line, rather than as structured blocks: each document's type, number and amount when the whole line fits 140 characters, or the document numbers alone (a credit note's marked with a leading "-") once it does not. A line still longer than 140 characters is cut at a word boundary, so an invoice number in your text is left out whole rather than cut short; the warning quotes the line as sent and names what is not sent: the words the cut leaves out, and your whole text when the document numbers fill the line. At a German bank every creditor reference is sent typed SCOR, the only code the German standard admits. SEB Germany is excepted: it takes the SEB group format.
  • BANK_CREDITOR_REFERENCE_TOO_LONG (error): a Danish account transfer or salary at Nordea Danmark (standard, same-day or NemKonto) carries a creditorReference longer than 25 characters. Nordea's guides for both pain.001 versions limit the reference on these payments to 25 characters. The reference is counted as the file carries it, so the spaces in a printed RF reference do not count. Shorten the reference, or send it as unstructured text. Transfer forms (FIK) have their own reference lengths and are not affected.
  • BANK_NPC_REMITTANCE_UNSTRUCTURED_REPEATED (error): a Danish account transfer or salary in DKK, executed on or after the date its bank applies the move of Danish batch payments to the Nordic Payments Council rules (Nordea Danmark: 24 May 2027), carries more than one unstructured line. From that date the payment carries one line of at most 140 characters or one creditor reference. Combine the lines into one. The siblings are warnings: BANK_REMITTANCE_DOCUMENTS_AS_TEXT (the documents go out as that one line, as at a German bank, and the warning quotes the line as sent and names what is not sent), BANK_REMITTANCE_TEXT_NOT_SENT (a creditor reference goes alone and the text or documents beside it are left out because the bank would not forward them) and BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT. Transfer forms (FIK), SEPA and international payments are not affected.
  • BANK_NPC_REMITTANCE_UNSTRUCTURED_REPEATED, BANK_NPC_OCR_REFERENCE_INVALID, BANK_NPC_REFERRED_AMOUNTS_MISMATCH (errors): a Swedish account transfer or Bankgiro/PlusGiro payment in SEK, executed on or after the date its bank applies the move to the Nordic Payments Council rules (Swedbank: 30 November 2026), carries more than one unstructured line; carries a numeric creditor reference typed scor on a Bankgiro or PlusGiro payment that is not a valid OCR number (2–25 digits, 5–25 for PlusGiro, modulus-10 check digit); or carries two or more invoices and credit notes whose amounts do not add up to the payment. The bank rejects each of these from that date. Combine the lines into one, check the OCR number on the invoice, or correct the amounts.
  • BANK_NPC_ERI_TOO_MANY_REFERENCES, BANK_NPC_ERI_DOCUMENT_AMOUNT_MISSING, BANK_NPC_ERI_REFERENCE_WITHOUT_AMOUNT, BANK_NPC_ERI_CREDIT_NOTE_ALONE (errors): the same Swedish payments from the date their bank takes Extended Remittance Information (Swedbank: 30 November 2026) carry more than 999 invoices, credit notes and references; or, with more than one, a document without its amount or a creditor reference beside documents; or credit notes with no invoice. Split the documents over more payments, give each its amount, and send a reference alone.
  • BANK_NPC_ERI_CATEGORY_PURPOSE_CONFLICT (error): a Swedbank Sweden payment carrying two or more invoices, credit notes or references, executed from 30 November 2026, names a categoryPurpose other than SUPP. Swedbank's guide takes such a payment only as a supplier payment, and the engine writes SUPP for it when no category purpose is given. Remove the category purpose, set it to SUPP, or send one document per payment. On such a payment additionalInfo is not sent (BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT, warning): every structured record carries an invoice, credit note or reference and its amount, so a note for the whole payment has no place. From the same date a payment with no invoice, credit note or reference does not send its additionalInfo either, with the same warning: Swedbank's guide places a note only beside the reference it clarifies. Put the text in the unstructured line. Handelsbanken Sweden does the same with additionalInfo from 11 October 2026: a note travels inside the record of the one invoice, credit note or reference it belongs to, and with none or two or more it is not sent, with the same warning code. Handelsbanken's guide sets no category-purpose rule for ERI.
  • BANK_SE_ERI_CREDIT_NOTE_BEFORE_DATE (error): a credit note on its own in a Swedbank Sweden payment executed BEFORE 30 November 2026. A credit note travels beside the invoice it reduces. Add the invoice the credit note reduces.
  • BANK_REMITTANCE_TEXT_NOT_SENT, BANK_REMITTANCE_TEXT_JOINED, BANK_REMITTANCE_DOCUMENTS_AS_TEXT, BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT (warnings): the same Swedish payments at Swedbank, executed BEFORE it takes Extended Remittance Information (30 November 2026). Swedbank's guide allows one structured reference or one line of text until then, never both, so the payment is sent in that shape: a creditor reference goes alone and the text or documents beside it are not sent; two or more unstructured lines are joined into one line (the warning shows it); two or more invoices and credit notes go as one text line (the warning shows it); one invoice goes alone and text beside it is not sent; additionalInfo is not sent. To have the text reach the payee, send it without the reference or the invoice. At SEB, additionalInfo on an account transfer is not sent on any date (BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT): SEB's guide takes none there; put the text in the unstructured line. On a Bankgiro or PlusGiro payment at SEB, additionalInfo is sent only beside an invoice, a credit note or a creditor reference; with none of them it is not sent, with the same warning, and the text belongs in the unstructured lines. At Handelsbanken Sweden, from 11 October 2026, a Bankgiro, PlusGiro or account payment carries one line of text or one invoice, credit note or reference, and both only as Extended Remittance Information with two or more of them: one invoice or reference goes alone and text beside it is not sent (BANK_REMITTANCE_TEXT_NOT_SENT); on Bankgiro and PlusGiro before 1 November 2026 two or more invoices go as one text line (BANK_REMITTANCE_DOCUMENTS_AS_TEXT). Account payments there take Extended Remittance Information, with its rules, from 11 October 2026.
  • BANK_REMITTANCE_TOO_MANY_LINES, BANK_REMITTANCE_TEXT_TOO_LONG, BANK_REMITTANCE_DOCUMENT_NUMBER_TOO_LONG, BANK_REMITTANCE_TOO_MANY_REFERENCES, BANK_REMITTANCE_TEXT_BESIDE_REFERENCE, BANK_REMITTANCE_TEXT_BESIDE_DOCUMENTS, BANK_REMITTANCE_REFERENCE_BESIDE_DOCUMENTS, BANK_REMITTANCE_DOCUMENT_AMOUNT_MISSING, BANK_REMITTANCE_AMOUNTS_MISMATCH, BANK_REMITTANCE_CREDIT_NOTE_ALONE, BANK_REMITTANCE_CREDIT_NOTE_TO_PLUSGIRO, BANK_REMITTANCE_ADDITIONAL_INFO_TOO_LONG (errors): a Swedish payment at Nordea Sverige or SEB carries remittance the bank's own guide does not take, on any date. At Nordea Sverige an account transfer or Bankgiro/PlusGiro payment carries one unstructured line, and document numbers and creditor references of at most 25 characters (BANK_CREDITOR_REFERENCE_TOO_LONG); a Bankgiro or PlusGiro payment carries at most 300 invoices, credit notes and references, each document with its amount when there are two or more, and a credit note only beside an invoice. At SEB a Bankgiro or PlusGiro payment carries at most three unstructured lines and 350 characters, at most 999 invoices, credit notes and references, each document with its amount, no credit note to a PlusGiro payee, text or documents, never both, and additionalInfo of at most 315 characters across its lines. At both, on Bankgiro and PlusGiro, the invoices less the credit notes add up to the payment (one invoice included: send the amount paid), and a creditor reference goes without text and without documents beside it. At SEB an account transfer with invoices or a creditor reference goes as SEB's SEK Credit Transfer and carries at most one unstructured line, at most 999 invoices, credit notes and references, each document with its amount, the amounts adding up to the payment, and no creditor reference beside documents; text beside a reference is taken. The message names the limit and the bank's guide; shorten the text, split the documents over more payments, or correct the amounts.
  • BANK_SE_CREDITOR_REFERENCE_NOT_RF (error): a SEB account transfer (domestic, SEK) carries a creditor reference that is not an RF creditor reference (ISO 11649). SEB's guide takes only an RF reference between bank accounts and writes it with issuer ISO. An OCR number belongs to a Bankgiro or PlusGiro payment: pay the payee's Bankgiro or PlusGiro number with it, or send the reference as unstructured text.
  • BANK_SE_RF_REFERENCE_ON_GIRO (error): a Swedbank Sweden Bankgiro or PlusGiro payment carries an RF creditor reference (ISO 11649), typed scor or untyped. Swedbank's guide takes an RF reference only with an IBAN or account number as the creditor account, and an OCR number only with a Bankgiro or PlusGiro number. Pay the payee's IBAN or account number with the RF reference, or pay the Bankgiro or PlusGiro number with the payee's OCR number.
  • BANK_NEMKONTO_SCHEME_UNSUPPORTED, BANK_NEMKONTO_ID_INVALID, BANK_NEMKONTO_CREDITOR_ID_TAKEN (errors): a NemKonto payment at Nordea Danmark, where the payee's number travels as the creditor's identification (in pain.001.001.03 and pain.001.001.09 alike). Nordea takes a CPR number (scheme NKC, 10 digits) or a CVR number (NKV, 8 digits) and names no form for a P- or SE-number (NKP, NKR, NKS); and the creditor's organisationId has no place beside the number. Address the payee by CPR or CVR number, or by account number, and remove the organisationId.
  • BANK_DANSKE_SEPA_INSTANT_DEBIT_ACCOUNT_NOT_EUR, BANK_DANSKE_SEPA_INSTANT_AMOUNT_LIMIT (errors): a SEPA Instant payment from a Danske Bank account whose stated debtor.account.currency is not EUR. Danske's CGI-MP Appendix (v5.3, Appendix J) says the debit account must be in EUR, except in Finland and Ireland, where an account in another currency is limited to EUR 3,000,000 a transaction. So the payment is refused from a Danish or Swedish account in another currency, and above EUR 3,000,000.00 from a Finnish or Irish one. A EUR account has no SEPA Instant limit at Danske. Pay it from a EUR account, split it, or send it as sepa.
  • BANK_CREDITOR_REFERENCE_TYPE_MISSING (warning): a Finnish, Dutch or Swiss bank receives a creditorReference with no type that is neither the country's own reference (a viitenumero, a betalingskenmerk, or a Swiss 27-digit QR reference) nor an ISO 11649 RF reference, such as an invoice number. Those banks' guides, and the Swiss Payment Standards, require every creditor reference to be typed and admit only those references, so the bank may reject the payment. The reference is sent as given, with no type. If it is free text for the creditor, send it as unstructured. An untyped RF reference is sent typed SCOR at those banks and needs nothing.
  • BANK_CH_SCOR_REFERENCE_NOT_ISO11649 (error): a payment from a Swiss bank in CHF or EUR to a Swiss or Liechtenstein account, off the SEPA rail, carries a creditorReference that goes out typed SCOR and is not an ISO 11649 RF reference: a non-RF value typed scor (a 27-digit QR reference among them), or a Belgian, Finnish or Dutch national reference or a Danish FIK reference. The Swiss Payment Standards validate every SCOR reference on such a payment as an RF reference and reject one that is not. Send an RF reference, a QR reference typed qrr (or untyped) to the creditor's QR-IBAN, or the text as unstructured.
  • BANK_REMITTANCE_TEXT_NOT_SENT, BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT (warnings): a SEPA credit transfer from a Finnish or Dutch bank carries a creditorReference beside unstructured text, documents or additionalInfo; or, from a Finnish bank, exactly one of documents beside unstructured text or additionalInfo; or, from a Dutch bank, documents beside additionalInfo. The Finnish banks' payments guide and the EPC guidelines the Dutch banks follow allow unstructured text or one structured item, never both, and Nordea ignores the text when both arrive. The creditor reference, or the one invoice or credit note, is sent alone and the rest is left out of the file. Each warning names what was left out, on the field it came from: BANK_REMITTANCE_TEXT_NOT_SENT for the text or documents, BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT for additionalInfo. To have the text reach the payee instead, send it without the reference or document. A Finnish payment of several documents (the ERI service) keeps its text.
  • BANK_REMITTANCE_DOCUMENTS_AS_TEXT (warning): a SEPA credit transfer from a Dutch bank carries documents and no creditorReference. The Dutch guide has no structured slot for invoices, so the documents go out as one unstructured line (each document's type, number and amount, then your unstructured text, shortened to the document numbers when that does not fit, and cut at a word boundary past 140 characters); the warning quotes the line as sent and names what is not sent.
  • BANK_REMITTANCE_ADDITIONAL_INFO_AS_TEXT (warning): a SEPA credit transfer from a Finnish or Dutch bank carries additionalInfo and no creditorReference, documents or unstructured text. Those banks' guides give additional information no structured slot, so it goes out as the payment's one unstructured line (its lines joined by a space, cut at a word boundary past 140 characters), which the payee receives as free text; the warning quotes the line as sent and names what is not sent. To send it as text without this warning, put it in unstructured.
  • BANK_REMITTANCE_DOCUMENTS_AS_TEXT (warning): a SEPA credit transfer from an ING account carries documents. ING's SEPA credit transfer guide admits a structured remittance only as a creditor reference typed SCOR and ignores referred documents, so the documents go out as one unstructured line (each document's type, number and amount, then your unstructured text, shortened to the document numbers when that does not fit). A line still longer than 140 characters is cut at a word boundary. The warning quotes the line as sent and names what is not sent: the words the cut leaves out, and your whole text when the document numbers fill the line. Beside a creditorReference the line still goes, but ING forwards the reference to the payee rather than the line. The Dutch, German and Belgian rules above decide this for ING's accounts in those countries.
  • BANK_REMITTANCE_ADDITIONAL_INFO_NOT_SENT (warning): a SEPA credit transfer from an ING account carries additionalInfo. ING's guide removes it from the structured remittance and rejects a payment that carries it, so it is left out of the file. Put the text in the one unstructured line to have it reach the payee. The Dutch rules above decide this for ING's Dutch accounts.
  • BANK_CREDITOR_REFERENCE_NOT_SCOR (warning): a SEPA credit transfer from an ING account carries a creditorReference that goes out without the type SCOR: one with no type that is neither a national reference nor (at a Finnish or Dutch bank) an RF reference, or a kid, ocr or qrr reference, which goes out with a proprietary type ING's guide removes. ING may reject the payment, or pass the reference on as unstructured text. The reference is sent as given and never relabelled SCOR. If it is an ISO 11649 RF reference, send it with type: "scor"; if it is free text for the creditor, send it as unstructured. An untyped reference at ING Netherlands draws BANK_CREDITOR_REFERENCE_TYPE_MISSING instead.
  • BANK_REMITTANCE_TEXT_JOINED (warning): a SEPA credit transfer carries two or more unstructured lines at a bank whose own guide allows one unstructured line: Swedbank Sweden, and ING (at ING Germany and ING Belgium the German and Belgian standards refuse a second line instead). The lines are sent as one, joined with a space; past 140 characters the line is cut at a word boundary, so a word or an invoice number that does not fit is left out whole rather than cut short. The warning quotes the line as sent and names any text that is not sent.
  • BANK_REMITTANCE_TEXT_JOINED (warning): a payment carries two or more unstructured lines on a local instrument whose bank guide allows one unstructured line: J.P. Morgan US ACH CCD, CTX and PPD (an ach payment with no localInstrument goes as CCD). The lines are sent as one, joined with a space; past the limit J.P. Morgan sets for the instrument the line is cut at a word boundary. The warning quotes the line as sent and names any text that is not sent.
  • BANK_FI_INVOICES_WITHOUT_CREDIT_NOTE_NOT_ERI (warning): a SEPA credit transfer from Nordea Finland, Säästöpankki, Oma Säästöpankki or Aktia carries two or more invoices in documents and no credit note. Nordea's Appendix Finland and Samlink's service description for the other three make at least one credit note part of the Extended Remittance Information (ERI) service, so the payment goes as a normal SEPA credit transfer, which carries one unstructured line or one structured item: the invoices, then your unstructured text, as one line (the document numbers alone when the full line does not fit 140 characters, and cut at a word boundary past 140 characters), or the creditorReference alone when there is one. additionalInfo is not sent. The warning quotes the line as sent and names what is not sent, or lists what was left out beside the reference. To send the invoices structured, add the credit note they are netted against, or pay each invoice on its own.
  • REGULATORY_REPORTING_REQUIRED (error): a cross-border payment out of a country that runs a payer-supplied reporting regime, in that regime's currency, above its threshold, carrying no regulatoryReporting.details[].code. Today that is Norway (Skatteetaten's Valutaregisteret, above NOK 100 000, a two-digit code plus free text) and Sweden (Skatteverket's kontrolluppgift KU81, above SEK 150 000, a three-digit code). This is a legal reporting duty and the debtor's bank may refuse the payment over it, so the engine refuses it first. Read the whole rule (authority, threshold and the authority's published code list, so you can offer a dropdown) from regulatoryReporting on GET /api/banks/<bank>/payment-types.
  • REGULATORY_REPORTING_EXPECTED (warning): the same duty on a payment in a third currency. The engine holds no exchange rates, so it compares the bare number and cannot know the payment is over the threshold; it tells you, and the payment still converts. Convert it yourself.
  • BANK_ADDRESS_DERIVATION_*: only when your bank settings turn on deriveHybridAddress. For a German, Austrian, Finnish, French, Dutch, UK, Jersey, Guernsey or Isle of Man party whose postalAddress has addressLines but no townName, the engine takes the postcode and town from the one line shaped 12345 Town (DE, FI, FR), 1234 Town (AT), 1234 AB Town (NL) or Town AB1 2CD (GB, JE, GG, IM) and sends a hybrid address; each element it fills is listed in autoFilled, and the payment's journal event names the party whose town was derived (the values themselves are in the payment's file). When it cannot do that with certainty it refuses the payment instead of guessing, and the issue names the party and quotes your lines: _TOWN_NOT_FOUND (no such line), _TOWN_AMBIGUOUS (more than one, or a line that still repeats the postcode or town), _POSTCODE_CONFLICT (your postCode disagrees with the line), _TOO_MANY_LINES (more than two lines would remain), _TOWN_TOO_LONG, _COUNTRY_MISSING, _COUNTRY_UNSUPPORTED (not DE or AT) and _VERSION_UNSUPPORTED (the bank agreement emits pain.001.001.03, which has no hybrid address). Supplying postalAddress.townName yourself always avoids all of them.
  • BANK_DEBTOR_ADDRESS_NOT_FILLED_* (warning): only when your bank settings turn on fillDebtorAddressFromRegisteredAddress. A payment whose debtor sends no postalAddress, and whose debtor name is your organisation's legal name or organisation name (case, spacing and punctuation aside), is given your registered address from Company settings → Company: street, building number, postcode, town and county, and debtor.country when you sent none. Each element it fills is listed in autoFilled, and an address you send is never changed. When it does not fill a debtor it says why: _OTHER_PARTY (the debtor name is not your organisation's, as when a group pays for a subsidiary), _NO_REGISTERED_ADDRESS (the registered address has no town or country) or _COUNTRY_CONFLICT (debtor.country is not the registered country).

Query GET /api/banks/<bank>/payment-types and the bank's setup info to see what a given bank expects before you build against it.

Payment-type rules (by scheme)

TypeKey requirements
sepacreditor IBAN required; EUR only
sepa-instantas SEPA; no scheme maximum, only a bank's own published ceiling
internationalcreditor account and creditor BIC required
fik (DK)valid FIK reference (kortart + Luhn); FIK/giro creditor number; DKK only
kid (NO)4–25 chars, MOD10/MOD11 (a MOD11 check value of 10 is a trailing -); NOK only
bankgiro (SE)Luhn-checked, digit-length bounded; scheme BGNR; SEK only
plusgiro (SE)Luhn-checked, digit-length bounded; scheme BBAN
bacs / chaps / faster-payment (UK)6-digit sort code + 8-digit account; GBP only; Faster ≤ £1,000,000
ach / wire (US)9-digit routing + ABA checksum; USD only
ch-domestic / ch-qr (CH)CH/LI creditor IBAN + CHF/EUR; QR adds a 27-digit reference check
eft (CA)routing + account; CAD only

If you omit paymentType, the engine attempts to infer it and returns autoSelected in the response. If it can't (PAYMENT_TYPE_AUTO_UNRESOLVED) or the type isn't offered by that bank (PAYMENT_TYPE_NOT_OFFERED), you get an error; set it explicitly when in doubt.

A third, rarer error means the fault is ours, not yours: PAYMENT_TYPE_BANK_OFFERS_NO_PAYMENT_TYPES says the bank profile has no payment types configured at all, so no rail can be selected and no file is produced. Setting paymentType explicitly will not help. Tell us and we fix the profile.

Where warnings are returned

A warning never blocks anything. It reports a file the bank will _accept_ while doing something other than what you asked: a payment marked urgent riding a non-urgent rail (it settles at normal speed), or a creditor name the bank will truncate. So warnings arrive on success responses, not only on a 422:

CallSuccess responseWhere the warnings are
POST /api/validate/{bank}200 JSONissues, mixed with any errors, filter on severity
POST /api/journal/payments201 JSONwarnings (top level, omitted when there are none)
POST /api/journal/payments/preview200 JSONwarnings
POST /api/convert-async/{bank}202 JSONwarnings
POST /api/convert/{bank}200 XML (the file)X-Validation-Warnings header, the body is a file, so there is no JSON field to put them in
any call422 JSONerror.details.issues, mixed with the errors that caused the rejection

warnings holds exactly the same issue objects as issues, same code, message, path, level, filtered to severity: "warning". One shape on every path, so one parser handles them all.

Date rules are evaluated in the tenant's timezone, not UTC. GENERIC_EXECUTION_DATE_PAST, GENERIC_EXECUTION_DATE_FAR_FUTURE and GENERIC_EXECUTION_DATE_INTL_TOO_SOON all derive "today" from a timezone, so what counts as "past" depends on which calendar day the check runs in. GENERIC_EXECUTION_DATE_AFTER_CUTOFF is the exception: a cut-off is a deadline the bank publishes in its own zone ("15:30"), so both "is the execution date today?" and "has the deadline passed?" are answered in the BANK's timezone. A tenant in Auckland and a tenant in Lisbon get the same answer about a German bank. On POST /api/convert/{bank} and POST /api/convert-async/{bank} that is the timezone of the company your credential names (a signed-in session or an install's own organisation; an API key names its company by supplying ?companyId=); a call that names no single company (an API key that omits those params, or an unauthenticated/dev-mode call) is evaluated in UTC.

The header on POST /api/convert/{bank} is the one exception, and it carries codes only:

X-Validation-Warnings: SEPA_INSTRPRTY_IGNORED=1,PROFILE_NAME_TRUNCATED=3

CODE=count pairs, comma separated, one per distinct code, so the header is bounded by the number of warning _codes_, not by the size of your batch. code is the stable value you branch on anyway; for the full messages and paths, post the same body to POST /api/validate/{bank}.

All of these fields are additive: they appear only when a payment actually raised a warning, so a response for a clean payment is unchanged.

Handling issues in your client

// Rejected (422): the issues that caused it, plus any warnings alongside them.
if (res.status === 422) {
  const { error } = await res.json();
  const blocking = (error.details?.issues ?? []).filter((i: any) => i.severity !== "warning");
  const warnings = (error.details?.issues ?? []).filter((i: any) => i.severity === "warning");
  // Surface `blocking` to whoever owns the payment data; log `warnings`.
}

// Accepted (201): the payment went through; log anything it warned about.
if (res.status === 201) {
  const { journalNo, warnings = [] } = await res.json();
  for (const w of warnings) console.warn(`${journalNo} ${w.code} @ ${w.path}: ${w.message}`);
}

Treat errors as "fix and resubmit," and warnings as "worth logging, but it went through." Don't discard warnings: a truncation or non-banking-day warning is often the first sign of a data-quality issue upstream.


A bank with no payment rails

A bank profile with no payment types has no rail a payment could use. A payment to it is refused at conversion with the blocking issue PAYMENT_TYPE_BANK_OFFERS_NO_PAYMENT_TYPES, and no file is produced. This is a fault in the bank profile, not in your payment.

When a connection is created for a bank with no payment rails, BankConnector emits a connection.no-payment-rails event once (see Receiving results). The connection still activates. An inbound-only connection (statements and status reports, no payments) needs no action.