ISO 20022 Academy
300 · Library

pacs.008: The Message That Actually Moves the Money

The interbank workhorse. When one bank tells another 'pay this customer, here's who, here's how much,' it sends a pacs.008. We open it field by field, then let you edit a live one.

11 min read · free, no signup
Read in the interactive Academy →

The problem first. Bob's bank has accepted his instruction. The money is leaving Dubai for Bangalore. But the next bank in the chain has never seen Bob, never seen this payment, and won't take a phone call about it.

This is the one message to learn in depth if you only ever learn one. And the way to really read it is to first work out what the situation forces into it.

What has to be in the message?

{{think}} A machine at the next bank — another country, another system — has to act on this payment with zero ambiguity and no human involved. It's never heard of Bob. It can't ask a follow-up question.

Given all that, what does Bob's bank have to put in the message for that machine to process it safely and pass it on? {{reveal}} Everything that removes ambiguity:

That message is the pacs.008 — the ISO 20022 successor to the MT103, and by volume one of the most important messages in global finance. {{/think}}

What the name means, and who sends it

Decode the name once and it's never cryptic again: pacs = Payments Clearing and Settlement; 008 = the FI-to-FI customer credit transfer. Full technical id: pacs.008.001.08 (the trailing numbers are variant and version).

It's strictly bank-to-bank. It is not what Bob's app sends (that's a pain.001). Bob's bank receives the pain.001 and turns it into a pacs.008 to pass onward. Created by the Debtor Agent (Bob's bank), received by the Creditor Agent (Sweety's bank) — directly or through intermediaries. Every hop preserves who pays whom.

See pacs.008 in the Message Explorer →

The anatomy, block by block

Two big parts: a Group Header (facts about this hop) and one or more Credit Transfer Transaction blocks (the payment).

<GrpHdr>
  <MsgId>BNKAUS33-20260627-000400</MsgId>
  <CreDtTm>2026-06-27T09:30:00+04:00</CreDtTm>
  <NbOfTxs>1</NbOfTxs>
  <SttlmInf><SttlmMtd>INDA</SttlmMtd></SttlmInf>
</GrpHdr>
<CdtTrfTxInf>
  <PmtId>
    <EndToEndId>BOB-INV0042</EndToEndId>
    <UETR>eb6305c9-1f7c-4a9b-9b1e-2c2f4e7a91d4</UETR>
  </PmtId>
  <IntrBkSttlmAmt Ccy="USD">400.00</IntrBkSttlmAmt>
  <Dbtr><Nm>Bob Marsh</Nm></Dbtr>
  <DbtrAgt><FinInstnId><BICFI>EBILAEAD</BICFI></FinInstnId></DbtrAgt>
  <CdtrAgt><FinInstnId><BICFI>HDFCINBB</BICFI></FinInstnId></CdtrAgt>
  <Cdtr><Nm>Sweety Rao</Nm></Cdtr>
  <RmtInf><Ustrd>Invoice 0042 — June freelance</Ustrd></RmtInf>
</CdtTrfTxInf>

The cast you know, now in tags: Dbtr/Cdtr the Debtor (Bob) and Creditor (Sweety); DbtrAgt/CdtrAgt their banks, each a BIC of 8 or 11 characters; IntrBkSttlmAmt the amount that settles between the banks, currency as an attribute; RmtInf/Ustrd what the payment is for.

The three identifiers everyone confuses

The single most common interview question on pacs.008 — commit it to memory:

Schema-valid, still rejected

{{think}} Here's a pacs.008 that passes every XSD check — well-formed XML, all mandatory elements present. You send it to production and it gets NAK'd anyway. Before reading on: what are the usual culprits? {{reveal}} The failures that live above the schema, in the usage rules and the real world:

Schema-valid and accepted are two different bars, and this gap is exactly where real payments die. {{/think}}

The fastest way to make this stick: edit a real pacs.008 and watch it validate live. The Playground holds Bob's exact transfer — change a name to 40 characters, blank the reference, drop the timezone, and watch each one get caught. You can also run it through the live engine to see it become an MT103 and back.

Edit a live pacs.008 in the Playground →

{{aside:model|The mental model}} pacs.008 is the interbank workhorse — the machine-readable "pay this customer, exactly, no ambiguity." Every hop preserves who pays whom. MsgId rotates per hop; EndToEndId and UETR are the threads that survive the whole journey. {{/aside}}

{{aside:chair|From the engineer's chair}} The rejections that hurt aren't schema errors — they're usage-rule and real-world ones: placeholder EndToEndId, timezone-less CreDtTm, malformed UETR, truncated names. Validating against the raw XSD passes all four. Validate against the usage guideline (CBPR+/HVPS+), and remember the full id pacs.008.001.08 — the version is pinned by the rulebook, not by you. {{/aside}}

{{aside:breaks|Where it breaks}}

{{/aside}}

{{aside:map|The map}} The workhorse and its neighbours:

{{/aside}}

{{aside:ref|Reference card}}

{{/aside}}

So what can you do now?

You can open any pacs.008, point to the Group Header and the transaction, name the Debtor/Creditor and their agents, tell MsgId from EndToEndId from UETR without hesitating, and predict the handful of reasons a real payment gets rejected before it ever reaches Sweety.

pacs.008 is best described as… The interbank workhorse that moves a customer's payment between banks

Which reference stays with the payment across every bank, end to end? The UETR — a globally unique tracking reference

Part of ISO 20022 Academy — lessons, a message playground, quizzes, and a glossary for the language of modern payments. Written by Revanth Sai Rayapati.