Submit an ISO 20022 pacs.009 credit transfer
POST/v1/iso20022/messages
Submit an ISO 20022 pacs.009.001.08 (Financial Institution Credit Transfer) message to
start an INTERBANK transfer from your bank to another bank on the network. This is an XML
alternative to POST /v1/transfers for banks whose payment systems
already produce ISO 20022 messages. The transfer is processed asynchronously: a successful
submission returns 202 Accepted with an empty body and the operation id in the headers.
Required scope: connector:transfers:create.
Supported messages
Only one message type and version is accepted:
| Part | Namespace | Notes |
|---|---|---|
| Business application header | urn:iso:std:iso:20022:tech:xsd:head.001.001.03 | Required. MsgDefIdr must be pacs.009.001.08. |
| Document | urn:iso:std:iso:20022:tech:xsd:pacs.009.001.08 | Exactly one CdtTrfTxInf (one transaction per message). |
Any other message type or version (for example pacs.009.001.09, pacs.008, or
head.001.001.02) is rejected with 400.
The request body must be a single XML document whose root element is a wrapper (envelope)
element of your choice, for example BusMsgEnvlp, containing the AppHdr element first and
the Document element second as its only child elements. A bare Document without an
application header is rejected with missing ISO 20022 application header.
How the message maps to the transfer
| ISO 20022 element | Use | Rules |
|---|---|---|
AppHdr/Fr/FIId/FinInstnId/BICFI | Sending bank | Required. Must equal (case-insensitively) the BIC registered for the bank you are calling as; otherwise 403. |
CdtTrfTxInf/CdtrAgt/FinInstnId/BICFI | Receiving (beneficiary) bank | Required. Must be the BIC of exactly one active bank on the network, and not your own bank; otherwise 400. |
CdtTrfTxInf/PmtId/UETR | Payment identity | Required. Lowercase UUID version 4. Must also be sent as the Idempotency-Key header. Used to retrieve the status and the source message. |
CdtTrfTxInf/IntrBkSttlmAmt | Amount | Required. Decimal amount in major units, for example 250000.00. It may have no more fractional digits than the asset's decimals, must be greater than zero, and is converted to the asset's minor units. |
CdtTrfTxInf/IntrBkSttlmAmt/@Ccy | Asset | Required. Three uppercase letters. Matched case-insensitively to the root id of an active asset (for example USD selects asset usd); if none matches, 400. |
CdtTrfTxInf/DbtrAcct/Id/Othr/Id or .../Id/IBAN | Source account | Required. The account identifier at your bank, treated as the account's external_account_id. |
CdtTrfTxInf/CdtrAcct/Id/Othr/Id or .../Id/IBAN | Destination account | Required. The account identifier at the receiving bank, treated as that account's external_account_id. |
CdtTrfTxInf/PmtId/InstrId, EndToEndId, TxId | None | Required to be present, but not used to process the transfer. They are kept in the stored source message. |
All other elements, for example AppHdr/To, BizMsgIdr, GrpHdr/MsgId, SttlmInf,
IntrBkSttlmDt, Dbtr, Cdtr, InstgAgt, InstdAgt and intermediary agents, only need to
be schema-valid; they do not affect processing and are kept in the stored source message.
Validation
Before anything is stored or any workflow is started, the message is checked for:
- size: at most 1 MiB (1,048,576 bytes); larger bodies are rejected with
413; - structure: at most 256 XML nodes (elements, text and whitespace between elements all count) and at most 32 levels of nesting;
- safety: document type declarations (DTDs) and external entities are always rejected;
- the pinned head.001.001.03 and pacs.009.001.08 XSD schemas;
- the mapping rules in the table above.
Every failure returns 400 with an XML problem document. Schema errors name the offending
element, for example invalid XML: UETR value ... does not match the required format;
several errors can be returned at once.
Idempotency and UETR uniqueness
The Idempotency-Key header is required and must be the message's UETR (compared as a UUID,
so letter case does not matter); otherwise the request is rejected with 400.
A UETR identifies one message for good. Resending the byte-for-byte identical message
is always safe: it returns 202 with the original operation id and creates nothing new.
Sending a different message (any byte difference, including whitespace) with a UETR that
has already been used is rejected with 409:
IDEMPOTENCY_CONFLICTwhen the same API client reuses the UETR within 72 hours;STATE_CONFLICT(detail: "Resubmit the original message unchanged or assign a new UETR.") otherwise, including when the UETR was already used by another bank.
A duplicate that arrives while the first submission is still being accepted returns 409
with IDEMPOTENCY_PENDING.
Validation failures (the 400 errors listed under Validation, and a wrong
Idempotency-Key) are detected before the UETR is claimed, so you can correct the message
and resend it with the same UETR. Any later failure (for example 400 for an unknown
receiver BIC or asset, 403 for a sender BIC mismatch, 424, or 503) happens after the
UETR is claimed by your API client:
- resending the identical message returns
409IDEMPOTENCY_PENDINGfor up to 5 minutes after the failed attempt, after which it is processed again; - sending a corrected message with the same UETR returns
409IDEMPOTENCY_CONFLICTfor 72 hours, so assign a new UETR to a corrected message.
Source message storage
The raw message is stored encrypted, readable only by the sending and the receiving bank,
using each bank's registered key-encryption key for source messages. If either key cannot
be used, the submission fails with 424 and nothing is started (KEY_UNAVAILABLE for your
key, COUNTERPARTY_UNAVAILABLE for the receiving bank's key). If either bank has no
encryption target registered, the submission fails with 400.
After acceptance
Track the transfer with GET /v1/iso20022/messages/{uetr}
(pacs.002 status report) or with GET /v1/operations/{operation_id}. The
transfer also appears as an INTERBANK transfer in the transfers API. Business outcomes decided
after acceptance, such as screening rejection by the receiving bank or insufficient liquidity,
are reported through the operation and the pacs.002 status, not through this response.
While the network is halted (outbound halted or read-only mode), submissions are refused
with 503 and a JSON:API error document.
Request
Responses
- 202
- 400
- 401
- 403
- 409
- 413
- 415
- 422
- 424
- 429
- 503
Message accepted. The platform has stored the source message and created an asynchronous transfer operation for it. The response body is empty; use the headers to track the payment:
Location: the operation resource,/v1/operations/{operation_id}.X-DAN-Operation-Id: the operation id (a UUID).X-ISO20022-UETR: the UETR of the submitted message.
A replay of an identical message returns this same response with the original operation id.
Response Headers
Sent by the ISO 20022 endpoints only. Relative URL of the operation created for this request, /v1/operations/{operation_id}.
Poll it to follow the request to a terminal state.
Sent by the ISO 20022 endpoints only. Identifier (a UUID) of the operation that tracks this request.
UETR (Unique End-to-end Transaction Reference) of the payment this response refers to: a
lowercase, hyphenated UUID version 4, taken from PmtId/UETR of the submitted pacs.009
message. The platform never assigns a UETR; it always echoes the one the sending bank chose.
The message is malformed, breaks a schema or mapping rule, or cannot be routed. Examples:
missing ISO 20022 application header, ISO 20022 document type declarations are not allowed, expected exactly one credit-transfer transaction, Idempotency-Key must equal the ISO 20022 UETR, ISO 20022 receiver BIC is not configured, ISO 20022 transfer must target a different bank, invalid ISO 20022 amount, no active asset is configured for the ISO 20022 settlement currency.
Error, returned as an XML problem document (application/problem+xml). The HTTP status
code is repeated in <status>; each <error> carries a <title> and, where one applies,
a <code> and a <detail>.
The caller may not submit this message: the token lacks connector:transfers:create
or is not scoped to the bank (Forbidden or ISO 20022 authorization failed), the bank
is suspended or terminated, or the application header's sender BIC is not the calling
bank's BIC.
The UETR is already associated with a different message (IDEMPOTENCY_CONFLICT or
STATE_CONFLICT), or an identical submission is still in progress (IDEMPOTENCY_PENDING).
The request body is larger than 1 MiB. This response is produced before the message is read and has a plain-text body, not an XML problem document.
The Content-Type header is missing or is not application/iso20022+xml.
The platform rejected the command with a business-rule error code.
The source message could not be encrypted because a key-encryption key cannot be used.
KEY_UNAVAILABLE: your bank's key (the detail says whether to restore the platform's
permission to use it or to re-enable or replace it), then resubmit.
COUNTERPARTY_UNAVAILABLE: the receiving bank's key. No transfer is started in either case.
Error, returned as an XML problem document (application/problem+xml). The HTTP status
code is repeated in <status>; each <error> carries a <title> and, where one applies,
a <code> and a <detail>.
A platform dependency (key provider, object store or workflow service) is temporarily
unavailable, for example DEPENDENCY_UNAVAILABLE. Resend the identical message with the
same Idempotency-Key after 5 minutes (see Idempotency and UETR uniqueness). While the
network is halted, this status is returned with a JSON:API error document instead of XML.