Batches
The Batches API cleans a whole file of addresses. Upload a CSV, check the columns we found, run it, and download the same file with every row matched to G-NAF the way Validate matches one line: the corrected address, its parts, its id and coordinates. Your own columns come back untouched. The same files are in the Cleaning tab of your console.
Batches need your subscription's admin key: the files hold your own data, so the API key used for address look-ups can't reach them. Domain tokens are refused.
1. Upload
POST https://api.getaddress.io/batches?name=customers.csv&api-key={your-admin-key}
The body is the file itself (Content-Type: text/csv): up to 100,000 rows and
20 MB, any encoding Excel or Google Sheets writes, separated by commas, semicolons,
tabs or pipes. We find the address columns for you: the headers and a few sample rows are read by an AI service
(Anthropic) to work out which columns hold the address. Nothing is charged. 20 uploads a day.
curl -X POST "https://api.getaddress.io/batches?name=customers.csv&api-key={your-admin-key}" -H "Content-Type: text/csv" --data-binary @customers.csv
Response (201)
{
"id": "6f1c0e2a9b8d4c7e8a1b2c3d4e5f6a7b",
"file_name": "customers.csv",
"status": "ready",
"rows": 1200,
"mapping": {
"has_header": true,
"columns": [
{ "column": 2, "role": "street", "header": "Street" },
{ "column": 3, "role": "suburb", "header": "Suburb" },
{ "column": 4, "role": "state", "header": "State" },
{ "column": 5, "role": "postcode", "header": "Postcode" }
]
},
"mapping_reason": "Used Street, Suburb, State and Postcode; Notes holds delivery instructions.",
"needs_review": false,
"price_cents": 240,
"free": false,
"expires": "2026-10-12T09:30:00+00:00",
…
}
2. Check the columns
When needs_review is true, look at mapping before running. To choose the columns
yourself, send every address column (numbered from 0) with its role: unit, number,
street, line (a whole or partial address in one cell), suburb,
state or postcode, in reading order.
PUT https://api.getaddress.io/batches/{id}/mapping?api-key={your-admin-key}
{
"has_header": true,
"columns": [ { "column": 1, "role": "line" }, { "column": 4, "role": "postcode" } ]
}
3. Run
POST https://api.getaddress.io/batches/{id}/run?api-key={your-admin-key}
A free batch starts at once (status running). Otherwise the response carries
checkout_url: open it to pay, and the batch starts when the payment is made
(status awaiting_payment until then). Every row is paid for up front and the rows that
don't match are refunded when the batch finishes, so you pay only for matched rows.
Files up to 200 rows are free once a day on the Free plan.
4. Wait, then download
GET https://api.getaddress.io/batches/{id}?api-key={your-admin-key}
rows_done counts up while it runs. Ask every few seconds; a batch of 100,000 rows takes minutes, and
we email you when it's done. When status is done, download it:
GET https://api.getaddress.io/batches/{id}/result?api-key={your-admin-key}
GET /batches lists your subscription's batches, newest first.
The cleaned file
Your columns, in order and as they were, then these. UTF-8, your own separator, and a header row (a file without
one gets column_1, column_2 …).
| Column | Holds |
|---|---|
ga_status | matched (one address fits; charged), ambiguous (several fit, or no suburb or postcode to place it), not_found, or invalid (no address, or over 200 characters). |
ga_id | The G-NAF id, for Get. |
ga_address | The address on one line. |
ga_level, ga_unit, ga_number, ga_street, ga_suburb, ga_state, ga_postcode | Its parts. |
ga_latitude, ga_longitude | Its coordinates. |
ga_candidates | For an ambiguous row, up to 5 G-NAF ids it could be, separated by ;. |
Keeping your data
Your file and the cleaned file are deleted 7 days after upload. A batch is then gone from the API too.