Part of the SortWare service. One request validates a United Kingdom sort code and account number: it runs the modulus check digit algorithm of the bank, looks the sort code up in the Extended Industry Sort Code Directory, returns the branch with its BIC and address and the payment schemes the branch takes part in, and calculates the IBAN. Irish national sort codes are handled the same way. Every check comes back as its own coded result, so your code can act on the one it needs instead of parsing messages.
https://api.iban.com/clients/api/v4/sort/https://api.iban.com/clients/api/v4/sort/?api_key=YOUR_API_KEY&format=json&sortcode=200415&account=38290008application/x-www-form-urlencoded; GET takes the same parameters in the query string. Both methods return the same response, and the parameters may be split between them.api_key, format, sortcode or account is missing (for a search, search), or format is not exactly json or xml. Check for an empty body before parsing.Content-Type follows the format parameter.YOUR_API_KEY:curl "https://api.iban.com/clients/api/v4/sort/" -d api_key=YOUR_API_KEY -d format=json -d sortcode=200415 -d account=38290008The full response to this request is in the Response section; the same request in six more languages is under Example request.
| Parameter | Required | Value | Description |
|---|---|---|---|
api_key | yes | string | Your personal key, shown under API Access. |
format | yes | json or xml | Response format, lower case. Missing or any other value (including JSON in upper case) gives an empty response body. |
sortcode | for validation | string, 6 digits | The sort code (United Kingdom) or national sort code (Ireland). Characters other than digits are reported by chars_sortcode and then removed; more than six characters are reported by length_sortcode and only the first six digits are used. |
account | for validation | string, 8 digits | The account number. Characters other than digits are reported by chars_account and removed; more than eight characters are reported by length_account and only the first eight digits are used. Six- and seven-digit numbers pass the length check but are not padded, so send the full eight digits as printed on the account. |
search | for search | string, 6 digits | Looks a sort code up in the directory without an account number. Ignored when sortcode is also sent. |
The endpoint has two functions, chosen by the parameters you send:
sortcode and account. Runs all six checks, returns the branch, the payment schemes and, when the modulus check passes, the IBAN. One query.search only. Looks the sort code up and returns the branch and the payment schemes with the three checks that concern the sort code (chars_sortcode, length_sortcode, sort_found). No account number, no modulus check, no IBAN. One query.https://api.iban.com/clients/api/v4/sort/?api_key=YOUR_API_KEY&format=json&search=200415When search and sortcode are both sent, the request is treated as a validation and search is ignored; if account is then missing, the body is empty.
Every example validates the same account: sort code 200415 with account number 38290008, a Barclays test pair; its response is shown in the next section. Replace YOUR_API_KEY with the key from API Access.
curl "https://api.iban.com/clients/api/v4/sort/" \
-d api_key=YOUR_API_KEY \
-d format=json \
-d sortcode=200415 \
-d account=38290008A validation response has five objects: errors, validations, account_data, bank_data, payment_schemes (a search response has three). JSON and XML list them in a different order, and the order of the members inside validations differs too, so address everything by name. The response to the example request:
{
"errors": [],
"validations": {
"chars_sortcode": {
"code": "006",
"message": "Sort Code does not contain illegal characters"
},
"chars_account": {
"code": "007",
"message": "Account Number does not contain illegal characters"
},
"length_sortcode": {
"code": "008",
"message": "Sort Code length is correct"
},
"length_account": {
"code": "009",
"message": "Account Number length is correct"
},
"modulus": {
"code": "001",
"message": "Modulus Success: Check digit is valid"
},
"sort_found": {
"code": "002",
"message": "Sort Code found in bank directory"
}
},
"account_data": {
"sortcode": "200415",
"account": "38290008",
"iban": "GB46BUKB20041538290008"
},
"bank_data": {
"bic": "BUKBGB22XXX",
"bank": "BARCLAYS BANK UK PLC",
"branch": "BARCLAYBANK B'CARD N'PTON",
"address": " ",
"city": "Leicester",
"zip": "LE87 2BB",
"phone": "0345 7345345",
"country": "GB"
},
"payment_schemes": {
"DD": "NO",
"FPS_PAYMENTS": "YES",
"CHAPS": "YES",
"BACS": "YES",
"CCC_PAYMENTS": "YES"
}
}| Field | Description |
|---|---|
sortcode | The sort code as used by the API: digits only, at most six. A string; keep leading zeros. |
account | The account number as used: digits only, at most eight, not padded. A string. |
iban | The IBAN calculated from the sort code and account number when the modulus check passed and the sort code was found (GB… or IE…). Empty when the modulus check failed (an empty string, null for Irish sort codes); null when the sort code was not found. |
The branch that owns the sort code, from the Extended Industry Sort Code Directory. All fields are null in JSON and empty elements in XML when the sort code was not found.
| Field | Description |
|---|---|
bic | BIC of the bank and branch, 11 characters. |
bank | Name of the bank that owns the sort code. |
branch | Name of the branch the sort code is assigned to. |
address | Street address of the branch; may be a single space or empty. |
city | City of the branch. |
zip | Postal code of the branch; may be empty, as it is for most Irish branches. |
phone | Telephone number of the branch; empty or null when the directory has none. |
country | GB or IE. |
Which clearings the branch takes part in, YES or NO. In a validation response the five fields are null when the sort code was not found and for Irish sort codes, which are outside the UK schemes; in a search response they are empty strings in those cases.
| Field | Description |
|---|---|
DD | The branch accepts Bacs Direct Debits. |
FPS_PAYMENTS | The branch is reachable through the Faster Payments Service. |
CHAPS | The branch accepts CHAPS sterling payments. |
BACS | The branch accepts Bacs credits. |
CCC_PAYMENTS | The branch takes part in cheque clearing (Cheque and Credit Clearing Company, now the Image Clearing System). |
Six members, one per check, each with a code and a message. Codes are three-character strings with a leading zero ("006", not 6); compare them as strings. modulus is absent in JSON (empty in XML) when the sort code was not found, because no bank algorithm can be chosen. The codes are listed under Result codes.
Empty when the request was accepted. On an account error it holds one entry with code and message; in JSON the other four objects are then omitted, in XML they are present and empty.
The same sort code with the last digit of the account number changed. The branch is still returned; iban is empty:
{
"errors": [],
"validations": {
"chars_sortcode": {
"code": "006",
"message": "Sort Code does not contain illegal characters"
},
"chars_account": {
"code": "007",
"message": "Account Number does not contain illegal characters"
},
"length_sortcode": {
"code": "008",
"message": "Sort Code length is correct"
},
"length_account": {
"code": "009",
"message": "Account Number length is correct"
},
"modulus": {
"code": "201",
"message": "Modulus Failed: Check digit is not valid"
},
"sort_found": {
"code": "002",
"message": "Sort Code found in bank directory"
}
},
"account_data": {
"sortcode": "200415",
"account": "38290009",
"iban": ""
},
"bank_data": {
"bic": "BUKBGB22XXX",
"bank": "BARCLAYS BANK UK PLC",
"branch": "BARCLAYBANK B'CARD N'PTON",
"address": " ",
"city": "Leicester",
"zip": "LE87 2BB",
"phone": "0345 7345345",
"country": "GB"
},
"payment_schemes": {
"DD": "NO",
"FPS_PAYMENTS": "YES",
"CHAPS": "YES",
"BACS": "YES",
"CCC_PAYMENTS": "YES"
}
}Sort code 999999: no modulus member; iban, the bank data and the payment schemes are null, the sort code and account number are echoed:
{
"errors": [],
"validations": {
"chars_sortcode": {
"code": "006",
"message": "Sort Code does not contain illegal characters"
},
"chars_account": {
"code": "007",
"message": "Account Number does not contain illegal characters"
},
"length_sortcode": {
"code": "008",
"message": "Sort Code length is correct"
},
"length_account": {
"code": "009",
"message": "Account Number length is correct"
},
"sort_found": {
"code": "202",
"message": "Sort Code not found in bank directory"
}
},
"account_data": {
"sortcode": "999999",
"account": "12345678",
"iban": null
},
"bank_data": {
"bic": null,
"bank": null,
"branch": null,
"address": null,
"city": null,
"zip": null,
"phone": null,
"country": null
},
"payment_schemes": {
"DD": null,
"FPS_PAYMENTS": null,
"CHAPS": null,
"BACS": null,
"CCC_PAYMENTS": null
}
}Search for the same sort code. JSON carries only the three objects that apply; XML has all five with the others empty. An unknown sort code gives sort_found 202 and empty strings:
{
"bank_data": {
"bic": "BUKBGB22XXX",
"bank": "BARCLAYS BANK UK PLC",
"branch": "BARCLAYBANK B'CARD N'PTON",
"address": " ",
"city": "Leicester",
"zip": "LE87 2BB",
"phone": "0345 7345345",
"country": "GB"
},
"payment_schemes": {
"DD": "NO",
"FPS_PAYMENTS": "YES",
"CHAPS": "YES",
"BACS": "YES",
"CCC_PAYMENTS": "YES"
},
"validations": {
"length_sortcode": {
"code": "008",
"message": "Sort Code length is correct"
},
"chars_sortcode": {
"code": "006",
"message": "Sort Code does not contain illegal characters"
},
"sort_found": {
"code": "002",
"message": "Sort Code found in bank directory"
}
}
}Bank of Ireland, national sort code 905838: the IBAN is Irish, country is IE and the payment schemes are null:
{
"errors": [],
"validations": {
"chars_sortcode": {
"code": "006",
"message": "Sort Code does not contain illegal characters"
},
"chars_account": {
"code": "007",
"message": "Account Number does not contain illegal characters"
},
"length_sortcode": {
"code": "008",
"message": "Sort Code length is correct"
},
"length_account": {
"code": "009",
"message": "Account Number length is correct"
},
"modulus": {
"code": "001",
"message": "Account number check digit is valid"
},
"sort_found": {
"code": "002",
"message": "Sort Code found in bank directory"
}
},
"account_data": {
"sortcode": "905838",
"account": "71924374",
"iban": "IE42BOFI90583871924374"
},
"bank_data": {
"bic": "BOFIIE2DXXX",
"bank": "Bank of Ireland",
"branch": "Tralee",
"address": "Lower Castle Street",
"city": "Tralee",
"zip": "",
"phone": null,
"country": "IE"
},
"payment_schemes": {
"DD": null,
"FPS_PAYMENTS": null,
"CHAPS": null,
"BACS": null,
"CCC_PAYMENTS": null
}
}One entry in errors. 301 shown; 302 to 305 have the same shape with the messages from the code table:
{
"errors": [
{
"code": "301",
"message": "API Key is invalid"
}
]
}XML schema of the response: sortware-api-v4.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!-- SortWare API v4 response. Every leaf element is a string and may be empty: codes keep their leading zero ("006"),
sort codes and account numbers keep theirs too. -->
<xs:complexType name="check">
<xs:sequence>
<xs:element name="code" type="xs:string"/>
<xs:element name="message" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="result">
<xs:complexType>
<xs:sequence>
<xs:element name="account_data">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element name="sortcode" type="xs:string"/>
<xs:element name="account" type="xs:string"/>
<xs:element name="iban" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="bank_data">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element name="bic" type="xs:string"/>
<xs:element name="bank" type="xs:string"/>
<xs:element name="branch" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="zip" type="xs:string"/>
<xs:element name="phone" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="payment_schemes">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element name="DD" type="xs:string"/>
<xs:element name="FPS_PAYMENTS" type="xs:string"/>
<xs:element name="CHAPS" type="xs:string"/>
<xs:element name="BACS" type="xs:string"/>
<xs:element name="CCC_PAYMENTS" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="validations">
<xs:complexType>
<xs:sequence>
<xs:element name="modulus" type="check"/>
<xs:element name="chars_account" type="check"/>
<xs:element name="chars_sortcode" type="check"/>
<xs:element name="length_sortcode" type="check"/>
<xs:element name="length_account" type="check"/>
<xs:element name="sort_found" type="check"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="errors">
<xs:complexType>
<xs:sequence>
<xs:element name="error" type="check" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>Each check answers with one success code or one failure code. Success codes start with 0, failure codes with 2.
| Member | Success | Failure |
|---|---|---|
chars_sortcode | 006 Sort Code does not contain illegal characters | 206 Sort Code contains illegal characters |
chars_account | 007 Account Number does not contain illegal characters | 207 Account Number contains illegal characters |
length_sortcode | 008 Sort Code length is correct | 208 Sort Code length is not correct |
length_account | 009 Account Number length is correct | 209 Account Number length is not correct |
modulus | 001 Modulus Success: Check digit is valid Irish sort codes: Account number check digit is valid | 201 Modulus Failed: Check digit is not valid Irish sort codes: Account number check digit is not valid |
sort_found | 002 Sort Code found in bank directory | 202 Sort Code not found in bank directory |
Returned in errors when the request itself is refused. No validation is performed.
| Code | Message | What to do |
|---|---|---|
| 301 | API Key is invalid | Copy the key exactly as shown under API Access. |
| 302 | Subscription expired | Renew the SortWare service under My Services. |
| 303 | No queries available | Your query balance is used up; top up under Pricing. |
| 304 | You have no access to this API | The SortWare service is not active on this account. |
| 305 | IP Address not allowed | The key is restricted to certain IP addresses; add the calling server's address under Settings. |
What each outcome means for your code. Validation results are deterministic for a given input, so there is never a reason to resend one; the directory changes weekly, so if you cache responses, give the cache a limited lifetime.
| Situation | Meaning | What to do |
|---|---|---|
| HTTP 200, empty body | The request was not understood: api_key, format, sortcode or account is missing (for a search, search), or format is not exactly json or xml. | Fix the request. Do not retry it unchanged. |
errors 301 or 304 | The key is wrong, or the SortWare service is not on the account. | Stop sending; every request will fail the same way. Check the key under API Access, or contact support for 304. |
errors 302 or 303 | The service has expired, or the query balance is used up. | Stop sending and alert whoever handles the subscription. Poll the services endpoint to catch this before it happens. |
errors 305 | The calling address is not on the key’s IP allow-list. | Add the address under Settings, then resend. |
| HTTP 429, HTML body | More than 20 requests per second. The request was rejected by the web server before reaching the API: not processed, not charged. | Wait a moment and resend; lower the sending rate. Safe to retry. There is no Retry-After header. |
| HTTP 500, empty body | A parameter was sent in a form the API cannot read, such as sortcode[]. | Send plain string parameters. |
| HTTP 5xx, timeout, connection error | Temporary problem on the way to the API or on the API itself. | Retry with increasing delays (1 s, 2 s, 4 s, then give up and queue). A request that got no response may still have been processed, so a retry costs at most one extra query. |
A 2xx code in validations | The request was fine; the sort code or account number is not. | Do not retry: the same input gives the same result. Show the user the failed check, log the code. |
modulus 001, sort_found 002, chars_sortcode 006, chars_account 007, length_sortcode 008, length_account 009. Only then is iban the account’s IBAN.20-04-15 is reported with 206 and 208 and still validated as 200415; a nine-digit account number gets 209 and is checked on its first eight digits. Treat a 2xx in any of the four as a reason to correct the input, even when the modulus passed.8290008 is checked as sent and fails, 38290008 passes. Some banks print seven-digit numbers; add the leading zero before calling.sort_found 002 with the branch details is the stronger evidence.country is IE, the IBAN starts with IE, the account check digit is verified, and the payment scheme flags are null because the branch is outside the UK clearings.address, zip and phone can be empty, a single space or null; trim before use.Each validation or search uses one query from your SortWare balance; requests answered with an account error (301–305) do not. The services endpoint returns every service active on your account with its remaining queries and expiry date; it takes api_key and format and does not use a query. It is documented with a sample response on the Validation API page; the SortWare entry is named SortWare.
https://api.iban.com/clients/api/v4/services/?api_key=YOUR_API_KEY&format=json| Term | Meaning |
|---|---|
| Sort code | Six-digit identifier of a bank branch in the United Kingdom, usually printed as 20-04-15. The first two digits identify the bank. |
| NSC | National Sort Code, the Irish equivalent (six digits, 90-58-38). The API accepts them in sortcode and returns an IE IBAN. |
| Modulus check | The UK account-number check digit algorithm (modulus 10, 11 or double alternate) published by Vocalink with per-sort-code weightings and exceptions. The modulus member reports its result; a bank without a published rule reports 001. |
| EISCD | Extended Industry Sort Code Directory, Vocalink’s weekly directory of sort codes, branches and clearing memberships. The bank data and payment scheme flags come from it; the file itself is available as the EISCD Data File. |
| Bacs | The UK bulk clearing for Direct Debits and Direct Credits (three-day cycle). Flags BACS and DD. |
| FPS | Faster Payments Service, the UK near-real-time clearing. Flag FPS_PAYMENTS. |
| CHAPS | Clearing House Automated Payment System, the UK same-day high-value sterling clearing. Flag CHAPS. |
| C&CCC / ICS | Cheque and Credit Clearing Company, operator of the Image Clearing System for cheques. Flag CCC_PAYMENTS. |
| IBAN | International Bank Account Number. For the UK: GB, two check digits, the four-letter bank code from the BIC, sort code, account number (22 characters). For Ireland: IE, check digits, bank code, NSC, account number (22 characters). |