> ## Documentation Index
> Fetch the complete documentation index at: https://developers.circle.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# Validating IBAN bank account numbers

> Validate IBAN account numbers by checking structure, country-specific length, and bank country match.

When providing beneficiary account data during payment creation or during RFIs,
OFIs may need to submit IBAN (International Bank Account Number) values that
follow a specific format. You can validate these numbers by checking their
structure, their country-specific length, and their country code against the
bank country.

An IBAN has 15 to 34 alphanumeric characters and follows the ISO 13616 standard.
Its structure is:

* First 2 characters: country code (uppercase letters, ISO 3166-1 alpha-2)
* Next 2 characters: check digits (digits)
* Remaining 11 to 30 characters: country-specific BBAN (Basic Bank Account
  Number), alphanumeric

IBANs are validated by their format, their country-specific length, and by
matching their country code against `BANK_COUNTRY`.

## Country-specific length

Each IBAN-issuing country has a fixed length defined by the ISO 13616 registry.
The following table lists the expected lengths:

| Country code | Country | Length |
| - | - | - |
| `AD` | Andorra | 24 |
| `AE` | United Arab Emirates | 23 |
| `AL` | Albania | 28 |
| `AT` | Austria | 20 |
| `AZ` | Azerbaijan | 28 |
| `BA` | Bosnia and Herzegovina | 20 |
| `BE` | Belgium | 16 |
| `BG` | Bulgaria | 22 |
| `BH` | Bahrain | 22 |
| `BI` | Burundi | 27 |
| `BR` | Brazil | 29 |
| `BY` | Belarus | 28 |
| `CH` | Switzerland | 21 |
| `CR` | Costa Rica | 22 |
| `CY` | Cyprus | 28 |
| `CZ` | Czech Republic | 24 |
| `DE` | Germany | 22 |
| `DJ` | Djibouti | 27 |
| `DK` | Denmark | 18 |
| `DO` | Dominican Republic | 28 |
| `EE` | Estonia | 20 |
| `EG` | Egypt | 29 |
| `ES` | Spain | 24 |
| `FI` | Finland | 18 |
| `FK` | Falkland Islands | 18 |
| `FO` | Faroe Islands | 18 |
| `FR` | France | 27 |
| `GB` | United Kingdom | 22 |
| `GE` | Georgia | 22 |
| `GI` | Gibraltar | 23 |
| `GL` | Greenland | 18 |
| `GR` | Greece | 27 |
| `GT` | Guatemala | 28 |
| `HN` | Honduras | 28 |
| `HR` | Croatia | 21 |
| `HU` | Hungary | 28 |
| `IE` | Ireland | 22 |
| `IL` | Israel | 23 |
| `IQ` | Iraq | 23 |
| `IS` | Iceland | 26 |
| `IT` | Italy | 27 |
| `JO` | Jordan | 30 |
| `KW` | Kuwait | 30 |
| `KZ` | Kazakhstan | 20 |
| `LB` | Lebanon | 28 |
| `LC` | Saint Lucia | 32 |
| `LI` | Liechtenstein | 21 |
| `LT` | Lithuania | 20 |
| `LU` | Luxembourg | 20 |
| `LV` | Latvia | 21 |
| `LY` | Libya | 25 |
| `MC` | Monaco | 27 |
| `MD` | Moldova | 24 |
| `ME` | Montenegro | 22 |
| `MK` | North Macedonia | 19 |
| `MN` | Mongolia | 20 |
| `MR` | Mauritania | 27 |
| `MT` | Malta | 31 |
| `MU` | Mauritius | 30 |
| `NI` | Nicaragua | 28 |
| `NL` | Netherlands | 18 |
| `NO` | Norway | 15 |
| `OM` | Oman | 23 |
| `PK` | Pakistan | 24 |
| `PL` | Poland | 28 |
| `PS` | Palestinian Territory | 29 |
| `PT` | Portugal | 25 |
| `QA` | Qatar | 29 |
| `RO` | Romania | 24 |
| `RS` | Serbia | 22 |
| `RU` | Russia | 33 |
| `SA` | Saudi Arabia | 24 |
| `SC` | Seychelles | 31 |
| `SD` | Sudan | 18 |
| `SE` | Sweden | 24 |
| `SI` | Slovenia | 19 |
| `SK` | Slovakia | 24 |
| `SM` | San Marino | 27 |
| `SO` | Somalia | 23 |
| `ST` | São Tomé and Príncipe | 25 |
| `SV` | El Salvador | 28 |
| `TL` | Timor-Leste | 23 |
| `TN` | Tunisia | 24 |
| `TR` | Turkey | 26 |
| `UA` | Ukraine | 29 |
| `VA` | Vatican City | 22 |
| `VG` | British Virgin Islands | 24 |
| `XK` | Kosovo | 20 |
| `YE` | Yemen | 30 |

Some overseas territories use their parent country's IBAN format:

| Territory code | Territory | Parent | Length |
| - | - | - | - |
| `AX` | Åland Islands | `FI` | 18 |
| `BL` | Saint Barthélemy | `FR` | 27 |
| `EA` | Ceuta and Melilla | `ES` | 24 |
| `GF` | French Guiana | `FR` | 27 |
| `GG` | Guernsey | `GB` | 22 |
| `GP` | Guadeloupe | `FR` | 27 |
| `IC` | Canary Islands | `ES` | 24 |
| `IM` | Isle of Man | `GB` | 22 |
| `JE` | Jersey | `GB` | 22 |
| `MF` | Saint Martin (French part) | `FR` | 27 |
| `MQ` | Martinique | `FR` | 27 |
| `NC` | New Caledonia | `FR` | 27 |
| `PF` | French Polynesia | `FR` | 27 |
| `PM` | Saint Pierre et Miquelon | `FR` | 27 |
| `RE` | Réunion | `FR` | 27 |
| `SJ` | Svalbard and Jan Mayen | `NO` | 15 |
| `TF` | French Southern Territories | `FR` | 27 |
| `WF` | Wallis and Futuna Islands | `FR` | 27 |
| `YT` | Mayotte | `FR` | 27 |

## Cross-field validation with bank country

When both IBAN and `BANK_COUNTRY` are provided, the IBAN's country code (first 2
characters) must match `BANK_COUNTRY`. Overseas territories resolve to their
parent country before the check. For example, an IBAN starting with `GG`
(Guernsey) is treated as `GB`.

## Example

The following is an example of validating the IBAN `GB82WEST12345698765432`:

**Structure**

* Country code: `GB` (United Kingdom)
* Check digits: `82`
* BBAN: `WEST12345698765432` (18 characters)
* Total length: `22` (matches the fixed length for `GB`)

**Cross-field check**

* IBAN country code: `GB`
* `BANK_COUNTRY`: `GB` (matches)
