
Batch API
Batch API lets you process large Geoapify workloads asynchronously.
- How it works: submit one batch task, run it in the background, and fetch results when ready.
- What it wraps: Geoapify endpoints that return JSON responses, including Geocoding API, Reverse Geocoding API, Place Details API, and Route Planner API.
- Why use it: higher practical limits for non-interactive jobs and lower processing cost than synchronous calls.
On this page
- About Batch API
- Why Use Batch API
- How to Send Batch API Requests
- Batch Geocoding API
- Batch Reverse Geocoding API
- Batch Places API
- Batch Place Details API
- Batch Route Planner API
- Batch Route Matrix API
- Batch Routing API
- Batch Isoline API
- Batch Map Matching API
- Batch Boundaries API
- Batch Postcode API
- Batch IP Geolocation API
- Getting started
- Pricing
- Learn More
- FAQ
Why Use Batch API
Batch API is asynchronous: you submit a job, it is processed in the background, and you fetch results when ready instead of waiting in one synchronous request.
This gives you practical benefits:
- Process Up to 1000 Requests in One: Submit up to 1000 inputs in a single batch request instead of sending many separate API calls.
- Plan Jobs and Reduce Cost: Batch API accepts a
priorityparameter that multiplies the total cost. For example, withpriority=0.5for non-real-time tasks, total consumed credits are multiplied by0.5. - Process Bigger Tasks:
| API | Sync Limit | Async Batch Limit | Key Metric |
|---|---|---|---|
| Isoline | - Time range: 3,600 sec (60 min) - Distance range: 100 km (62 mi) | - Time range: 7,200 sec (120 min) - Distance range: 200 km (124 mi) | Time/distance range per isoline |
| Routing (profile-dependent) | - Walk/Hike: 100 km (62 mi) - Scooter: 300 km (186 mi) - Bicycle: 300 km (186 mi) - Mountain bike: 500 km (311 mi) - Road bike: 1,000 km (621 mi) - Default vehicles: 10,000 km (6,214 mi) | - Walk/Hike: 200 km (124 mi) - Scooter: 600 km (373 mi) - Bicycle: 600 km (373 mi) - Mountain bike: 1,000 km (621 mi) - Road bike: 1,000 km (621 mi) - Default vehicles: 10,000 km (6,214 mi) | Max distance between consecutive waypoints (per segment) |
| Route Matrix | - Max cells: 1,000 - Total distance: 300,000 km (186,411 mi) | - Max cells: 2,000 - Total distance: 1,000,000 km (621,371 mi) | Matrix size and aggregate distance |
| Route Planner | - Unique locations: 300 - Distance sum: 300,000 km (186,411 mi) | - Unique locations: 1,000 - Distance sum: 1,000,000 km (621,371 mi) | Optimization matrix size and aggregate distance |
Note: Processing time depends on the
priorityparameter. For example, withpriority=0.5(default), tasks can take longer (up to a few hours), but you get the price benefit (credits are multiplied by0.5). Increase topriority=1for faster processing when needed, but without price benefits.
How to Send Batch API Requests
Batch API can wrap Geoapify endpoints that return JSON responses and process long-running or high-volume workloads asynchronously. It is not intended for image or map tile endpoints. Your app can submit jobs and continue working without waiting for immediate results.
1. Create a Batch API request
The Batch API request has this structure:
{
"api": "GEOAPIFY_API_ENDPOINT",
"params": { /* ... */ },
"priority": 0.5,
"inputs": [
{
"id": "optional_input_id",
"params": { /* ... */ }
},
/* ... */
]
}| Field | Description | Example |
|---|---|---|
api | Target Geoapify endpoint you want to wrap. | /v1/geocode/search |
params | Shared parameters applied to all input records. | { "format": "json", "filter": "countrycode:us" } |
priority | Task priority from 0.5 to 1. All batch tasks are scheduled by priority, so processing time depends on this value and current platform load. | 0.5 |
inputs | Array of records to process; each record can include an optional id and its own params. | [{"id":"optional_input_id","params":{"text":"5201 Julianna Drive, Norfolk, VA"}}] |
How to Wrap APIs (GET vs POST):
- If the wrapped API is already a
POSTAPI, the mapping is straightforward: put each input payload intoinputs[].params.- If the wrapped API is a
GETAPI, convert URL query parameters to JSON fields insideparams/inputs[].params(instead of sending them in the URL query string).Check the corresponding API section below for an exact request example.
All batch jobs are created with an HTTP POST request to https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY:
curl -X POST "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"api": "GEOAPIFY_API_ENDPOINT",
"params": { },
"priority": 0.5,
"inputs": [
{
"id": "optional_input_id",
"params": { }
},
...
]
}'The create request can return either:
202: job accepted and still pending.200: job already completed and response already contains results.
Example 202 pending response:
{
"id": "fae18391597c43cf9423d6800a7ce214",
"status": "pending"
}This means the batch job was created successfully and queued for processing.
id is your job identifier, and status: "pending" means the result is not ready yet.
If step 1 returns 200, you can skip step 2 and read the results directly.
2. Query Job Results (if step 1 returned 202)
Use the returned job id to check the batch status:
https://api.geoapify.com/v1/batch?id=fae18391597c43cf9423d6800a7ce214&apiKey=YOUR_API_KEYid must be the exact job identifier returned in the step 1 202 response (for example, fae18391597c43cf9423d6800a7ce214).
Status response codes:
202: job is still pending.200: job is completed and response contains results.
3. Read Results
When status changes to 200, parse the returned payload and continue your pipeline.
Here is the structure of results:
{
"api": "/v1/geocode/search",
"params": {
"filter": "countrycode:us",
"format": "json"
},
"id": "fae18391597c43cf9423d6800a7ce214",
"results": [
{
"id": "optional-input-id1",
"params": { /* ... */ },
"result": { /* ... */ }
},
/* ... */
]
}Each item in results[] has:
id: the input identifier you passed (helps map output to input).params: the input parameters used for this specific record.result: the exact payload returned by the wrapped API for that record.
Batch Geocoding API
Use the general Batch API endpoint (POST /v1/batch) to run Geocoding API jobs, using the structure below:
| Param | Description | Example |
|---|---|---|
api | Use /v1/geocode/search for geocoding | "/v1/geocode/search" |
body.params | Common parameters applied to all addresses in the batch request (for example, filter, lang, format). | { "filter": "countrycode:us", "format": "json" } |
body.inputs[].params | Geocoding parameters for each individual address record, typically text (or structured fields like housenumber, street, postcode, city). | { "text": "5201 Julianna Drive, Norfolk, VA 23502, United States of America" } |
Here is an example of Batch Geocoding request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/geocode/search",
"params": {
"filter": "countrycode:us",
"format": "json"
},
"inputs": [
{
"id": "optional-input-id-1",
"params": {
"text": "5201 Julianna Drive, Norfolk, VA 23502, United States of America"
}
},
{
"id": "optional-input-id-2",
"params": {
"text": "1401 Norcova Avenue, Norfolk, VA 23502, United States of America"
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Alternative endpoint: use the dedicated Batch Geocoding API for a simplified address-to-lat/lon workflow.
Batch Reverse Geocoding API
Convert large coordinate datasets to addresses with Reverse Geocoding API.
Use the general Batch API endpoint (POST /v1/batch) to run Reverse Geocoding API jobs, using the structure below:
| Param | Description | Example |
|---|---|---|
api | Use /v1/geocode/reverse for reverse geocoding. | "/v1/geocode/reverse" |
body.params | Common parameters applied to all coordinate records in the batch request (for example, lang, format, type). | { "lang": "en", "format": "json" } |
body.inputs[].params | Reverse geocoding parameters for each coordinate record, typically lat and lon. | { "lat": 36.8692947, "lon": -76.2220594 } |
Here is an example of request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/geocode/reverse",
"params": {
"format": "json",
"lang": "en"
},
"inputs": [
{
"id": "optional-input-id-1",
"params": {
"lat": 36.8692947,
"lon": -76.2220594
}
},
{
"id": "optional-input-id-2",
"params": {
"lat": 36.872314,
"lon": -76.233001
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Alternative endpoint: the dedicated Batch Geocoding API also supports reverse geocoding workflows.
Batch Places API
Process high-volume place search jobs with Places API.
Use cases:
- Get one category for a large area by splitting it into smaller tiles (recommended).
This approach improves coverage and stability for large-area scans and helps build reliable category datasets for analytics, ranking, and planning. - Get different categories for the same area.
Run separate batch queries for multiple categories (for example, supermarkets, pharmacies, ATMs) to build multi-category area datasets for analytics, ranking, and planning. - Get nearby places for many coordinates at once.
Send one input per coordinate to batch-process location-based place lookups at scale.
To batch Places API requests, call POST /v1/batch and set the wrapped endpoint to /v2/places.
| Param | Description | Example |
|---|---|---|
api | Use /v2/places for place search requests. | "/v2/places" |
body.params | Common parameters applied to all place queries in the batch (for example, categories, lang, conditions). | { "categories": "commercial.supermarket", "lang": "en" } |
body.inputs[].params | Per-query parameters, typically search area and limits (for example, filter, bias, limit). | { "filter": "rect:-76.240,36.860,-76.200,36.890", "limit": 20 } |
Here is an example of Batch Places request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v2/places",
"params": {
"categories": "commercial.supermarket",
"lang": "en"
},
"inputs": [
{
"id": "optional-input-id-1",
"params": {
"filter": "rect:-76.240,36.860,-76.200,36.890",
"limit": 20
}
},
{
"id": "optional-input-id-2",
"params": {
"filter": "rect:-76.275,36.845,-76.225,36.875",
"limit": 20
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Place Details API
Enrich records in bulk with Place Details API.
Use cases:
- Enrich large lists of places with structured details (categories, contact data, opening hours).
- Retrieve building-level context and related features for many places at once.
- Get place details in bulk by
osm_idandosm_type. - Get boundaries and geometry attributes for analytics, reporting, and map visualization.
You can process Place Details API in batch mode via POST /v1/batch by wrapping /v2/place-details.
| Param | Description | Example |
|---|---|---|
api | Use /v2/place-details for place enrichment requests. | "/v2/place-details" |
body.params | Common parameters for all places in the batch (for example, features, lang). | { "features": "details,building", "lang": "en" } |
body.inputs[].params | Per-place identifiers and parameters, typically id (place_id) or osm_id + osm_type. | { "id": "51b188618731b11240599ae1500999e54940f00103f901afc5c7a500000000c00203" } |
Here is an example of Batch Place Details request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v2/place-details",
"params": {
"features": "details,building",
"lang": "en"
},
"inputs": [
{
"id": "optional-input-id-1",
"params": {
"id": "51b188618731b11240599ae1500999e54940f00103f901afc5c7a500000000c00203"
}
},
{
"id": "optional-input-id-2",
"params": {
"id": "513e31a138360e53c059068b790c456f4240f00102f901fe92451800000000c00203"
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Route Planner API
Execute larger optimization workloads with Route Planner API.
Use cases:
- Schedule large sets of planning jobs as asynchronous background tasks. The synchronous API supports up to 300 locations and max route distance of 300000 km (186411 mi), while asynchronous batch supports up to 1000 locations and max route distance of 1000000 km (621371 mi).
Use POST /v1/batch to execute Route Planner API tasks in batch mode by wrapping /v1/routeplanner.
| Param | Description | Example |
|---|---|---|
api | Use /v1/routeplanner for route optimization requests. | "/v1/routeplanner" |
body.params | Common optimization parameters shared across all tasks (for example, mode). | { "mode": "drive" } |
body.inputs[].params | Per-task Route Planner input objects (for example, agents, shipments, locations, constraints). | { "agents": [...], "shipments": [...], "locations": [...] } |
Here is an example of Batch Route Planner request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/routeplanner",
"params": {
"mode": "drive"
},
"inputs": [
{
"id": "task-norfolk-1",
"params": {
"agents": [
{
"start_location": [-76.2220, 36.8692],
"time_windows": [[0, 28800]]
}
],
"shipments": [
{
"id": "order-1",
"delivery": {
"location": [-76.2104, 36.8751],
"duration": 120
}
}
],
"locations": [
{ "id": "warehouse-1", "location": [-76.2220, 36.8692] }
]
}
},
{
"id": "task-norfolk-2",
"params": {
"agents": [
{
"start_location": [-76.2330, 36.8723],
"time_windows": [[0, 28800]]
}
],
"shipments": [
{
"id": "order-2",
"delivery": {
"location": [-76.2401, 36.8634],
"duration": 180
}
}
],
"locations": [
{ "id": "warehouse-2", "location": [-76.2330, 36.8723] }
]
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Route Matrix API
Calculate many-to-many travel time and distance datasets with Route Matrix API.
Use cases:
- Calculate travel time and distance matrices for many planning zones in one async workflow.
- Run matrix jobs for multiple depots, service areas, or time windows in parallel.
- Calculate very large matrices by splitting them into smaller batch tasks and combining results into one final matrix.
- Scale larger jobs: synchronous supports up to 1000 matrix elements and 300000 km (186411 mi), while asynchronous batch supports up to 2000 elements and 1000000 km (621371 mi).
To run Route Matrix API in batch mode, submit POST /v1/batch and wrap /v1/routematrix.
| Param | Description | Example |
|---|---|---|
api | Use /v1/routematrix for matrix requests. | "/v1/routematrix" |
body.params | Common parameters shared by all matrix tasks (for example, mode, units). | { "mode": "drive", "units": "metric" } |
body.inputs[].params | Per-task matrix payload, typically sources and targets arrays (plus optional task-specific routing options). | { "sources": [{"location":[-76.2220,36.8692]}], "targets": [{"location":[-76.2104,36.8751]}] } |
Here is an example of Batch Route Matrix request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/routematrix",
"params": {
"mode": "drive",
"units": "metric"
},
"inputs": [
{
"id": "matrix-task-1",
"params": {
"sources": [
{ "location": [-76.2220, 36.8692] },
{ "location": [-76.2330, 36.8723] }
],
"targets": [
{ "location": [-76.2104, 36.8751] },
{ "location": [-76.2401, 36.8634] }
]
}
},
{
"id": "matrix-task-2",
"params": {
"sources": [
{ "location": [-76.2750, 36.8450] }
],
"targets": [
{ "location": [-76.2250, 36.8750] },
{ "location": [-76.2000, 36.8900] }
]
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Routing API
Build route batches for multiple origin-destination pairs with Routing API.
Use cases:
- Calculate routes for large lists of trips in asynchronous background jobs.
- Build many route alternatives for different modes and restrictions (for example, drive, truck, avoid tolls).
- Handle profile-dependent limits: Walk/Hike up to 100 km (sync) / 200 km (async), Bikes up to 300-1000 km depending on bike type, Vehicles up to 10000 km in both sync and async modes.
- Recompute route sets in bulk after location or policy updates.
To batch Routing API requests, call POST /v1/batch and wrap /v1/routing.
| Param | Description | Example |
|---|---|---|
api | Use /v1/routing for route calculation requests. | "/v1/routing" |
body.params | Common routing parameters for all requests in the batch (for example, mode, details, units). | { "mode": "drive", "details": "route_details", "units": "metric" } |
body.inputs[].params | Per-route parameters, typically waypoints and optional route-specific options like avoid. | { "waypoints": "36.8692,-76.2220|36.8751,-76.2104", "avoid": "tolls" } |
Here is an example of Batch Routing request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/routing",
"params": {
"mode": "drive",
"details": "route_details",
"units": "metric"
},
"inputs": [
{
"id": "route-task-1",
"params": {
"waypoints": "36.8692,-76.2220|36.8751,-76.2104",
"avoid": "tolls"
}
},
{
"id": "route-task-2",
"params": {
"waypoints": "36.8723,-76.2330|36.8634,-76.2401",
"avoid": "highways"
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Isoline API
Generate many reachability areas in background jobs with Isoline API.
Use cases:
- Generate service areas for many origin points in one asynchronous workflow.
- Compare reachability zones (time or distance based) across multiple locations.
- Scale larger ranges: synchronous supports up to 3,600 sec (60 min) or 100 km (62 mi), while asynchronous batch supports up to 7,200 sec (120 min) or 200 km (124 mi).
Use POST /v1/batch to execute Isoline API requests in batch mode by wrapping /v1/isoline.
| Param | Description | Example |
|---|---|---|
api | Use /v1/isoline for isoline requests. | "/v1/isoline" |
body.params | Common isoline parameters shared by all tasks (for example, type, mode, range, route_type). | { "type": "time", "mode": "drive", "range": [900, 1800] } |
body.inputs[].params | Per-origin parameters, typically lat and lon (and optional task-specific overrides). | { "lat": 36.8692, "lon": -76.2220 } |
Here is an example of Batch Isoline request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/isoline",
"params": {
"type": "time",
"mode": "drive",
"range": [900, 1800],
"route_type": "balanced"
},
"inputs": [
{
"id": "isoline-task-1",
"params": {
"lat": 36.8692,
"lon": -76.2220
}
},
{
"id": "isoline-task-2",
"params": {
"lat": 36.8751,
"lon": -76.2104
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Map Matching API
Process large GPS trajectory cleanup tasks with Map Matching API.
Use cases:
- Snap large GPS track datasets to the road network in asynchronous jobs.
- Normalize noisy trajectories before analytics, ETL pipelines, or route replay.
- Batch-process multiple tracks from vehicles, couriers, or IoT devices in parallel.
To run Map Matching API in batch mode, send POST /v1/batch and wrap /v1/mapmatching.
| Param | Description | Example |
|---|---|---|
api | Use /v1/mapmatching for map matching requests. | "/v1/mapmatching" |
body.params | Common map matching parameters shared by all tracks (for example, mode). | { "mode": "drive" } |
body.inputs[].params | Per-track payload, typically waypoints (and optional timestamps and overrides). | { "waypoints": [{ "location": [-76.2220, 36.8692] }, { "location": [-76.2104, 36.8751] }] } |
Here is an example of Batch Map Matching request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/mapmatching",
"params": {
"mode": "drive"
},
"inputs": [
{
"id": "track-1",
"params": {
"waypoints": [
{ "location": [-76.2220, 36.8692] },
{ "location": [-76.2202, 36.8708] },
{ "location": [-76.2177, 36.8729] },
{ "location": [-76.2104, 36.8751] }
]
}
},
{
"id": "track-2",
"params": {
"waypoints": [
{ "location": [-76.2330, 36.8723] },
{ "location": [-76.2365, 36.8691] },
{ "location": [-76.2401, 36.8634] }
]
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Boundaries API
Resolve many locations to administrative areas with Boundaries API.
Use cases:
- Resolve administrative hierarchy (city, county, state, country) for many places in one batch.
- Enrich large location datasets with boundary context for analytics and reporting.
- Fetch boundary geometries in bulk for map overlays and region-based filtering.
To process Boundaries API requests in batch mode, call POST /v1/batch and wrap /v1/boundaries/consists-of or /v1/boundaries/part-of.
| Param | Description | Example |
|---|---|---|
api | Boundaries endpoint to wrap: /v1/boundaries/consists-of or /v1/boundaries/part-of. | "/v1/boundaries/consists-of" |
body.params | Common boundary parameters applied to all inputs (for example, geometry). | { "geometry": "geometry_1000" } |
body.inputs[].params | Per-record boundary lookup parameters, typically id (place id), or location coordinates where supported. | { "id": "51ecbccfa440182740598d7dd2e49a134840f00101f901dcf3000000000000" } |
Here is an example of Batch Boundaries request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/boundaries/consists-of",
"params": {
"geometry": "geometry_1000"
},
"inputs": [
{
"id": "boundary-task-1",
"params": {
"id": "51ecbccfa440182740598d7dd2e49a134840f00101f901dcf3000000000000"
}
},
{
"id": "boundary-task-2",
"params": {
"id": "513e31a138360e53c059068b790c456f4240f00102f901fe92451800000000c00203"
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch Postcode API
Run postcode parsing and lookup tasks in bulk with Postcode API.
Use cases:
- Validate and normalize large postcode lists in background jobs.
- Enrich customer records with postcode-level location data at scale.
- Run bulk postcode lookups by code, coordinates, or area filters.
To batch Postcode API requests, call POST /v1/batch and wrap /v1/postcode/search or /v1/postcode/list.
| Param | Description | Example |
|---|---|---|
api | Wrapped postcode endpoint for the batch task. | "/v1/postcode/search" |
body.params | Common postcode parameters applied to all inputs (for example, countrycode, limit). | { "countrycode": "us" } |
body.inputs[].params | Per-record postcode query parameters, such as postcode, lat + lon, or filter. | { "postcode": "23502" } |
Here is an example of Batch Postcode request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/postcode/search",
"params": {
"countrycode": "us"
},
"inputs": [
{
"id": "postcode-task-1",
"params": {
"postcode": "23502"
}
},
{
"id": "postcode-task-2",
"params": {
"postcode": "90210"
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
Batch IP Geolocation API
Geolocate large IP datasets asynchronously with IP Geolocation API.
Use cases:
- Enrich large IP datasets with location and timezone data in background jobs.
- Run fraud, compliance, or localization preprocessing for many IPs at once.
- Batch-process visitor IP logs before analytics pipelines or BI ingestion.
To run IP Geolocation API in batch mode, call POST /v1/batch and wrap /v1/ipinfo.
| Param | Description | Example |
|---|---|---|
api | Use /v1/ipinfo for IP geolocation requests. | "/v1/ipinfo" |
body.inputs[].params | Per-record IP query parameters, typically ip. | { "ip": "8.8.8.8" } |
Here is an example of Batch IP Geolocation request body:
{
"type": "HTTP POST",
"url": "https://api.geoapify.com/v1/batch?apiKey=YOUR_API_KEY",
"headers": "Content-Type=application/json",
"body": {
"api": "/v1/ipinfo",
"inputs": [
{
"id": "ip-task-1",
"params": {
"ip": "8.8.8.8"
}
},
{
"id": "ip-task-2",
"params": {
"ip": "1.1.1.1"
}
}
]
}
}You can generate the request with the help of Batch API Playground >>
See full request formats and endpoint details in the Batch API documentation.
Getting Started
To send Batch API requests, you need a Geoapify API key. Sign up in Geoapify, create a project, and use the first API key that is created automatically for that project. See details on the Getting Started page >>
Then set up a mechanism to submit jobs, query status, and read results.
- For one-time jobs, you can use Postman.
- For recurring jobs, implement a small script (or backend job) that submits batch tasks and polls results automatically.
Here are examples of scripts:
- JavaScript
- Python
- Go
const API_KEY = "YOUR_API_KEY";
const CREATE_URL = `https://api.geoapify.com/v1/batch?apiKey=${API_KEY}`;
const STATUS_URL = (id) => `https://api.geoapify.com/v1/batch?id=${id}&apiKey=${API_KEY}`;
const POLL_INTERVAL_MS = 60_000; // 1 minute
const MAX_ATTEMPTS = 180; // up to ~3 hours
const requestBody = {
api: "/v1/geocode/search",
priority: 0.5,
params: { format: "json" },
inputs: [
{ id: "addr-1", params: { text: "5201 Julianna Drive, Norfolk, VA 23502, USA" } },
{ id: "addr-2", params: { text: "1401 Norcova Avenue, Norfolk, VA 23502, USA" } }
]
};
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function runBatchJob() {
const createResp = await fetch(CREATE_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody)
});
const createData = await createResp.json();
if (createResp.status === 200) {
console.log("Job is ready:", createData);
return;
}
if (createResp.status !== 202) {
throw new Error(`Unexpected create status: ${createResp.status}`);
}
const { id } = createData;
if (!id) {
throw new Error("Batch job id is missing in 202 response");
}
console.log("Created batch job:", id);
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
await sleep(POLL_INTERVAL_MS);
const statusResp = await fetch(STATUS_URL(id));
if (statusResp.status === 202) {
console.log(`Job is still pending... attempt ${attempt}/${MAX_ATTEMPTS}`);
continue;
}
if (statusResp.status === 200) {
const result = await statusResp.json();
console.log("Job is ready:", result);
return;
}
throw new Error(`Unexpected status response: ${statusResp.status}`);
}
throw new Error(`Batch job was not ready after ${MAX_ATTEMPTS} polling attempts.`);
}
runBatchJob().catch(console.error);All script examples follow the same Batch API workflow:
- Send one batch request with:
api(target endpoint to wrap)- optional shared
params inputs(list of records to process)
- Check the first response:
200means the result is returned immediately.202means the job is accepted for background processing and returns anid.
- If the response is
202, query/v1/batch?id=...until it returns200. - Polling controls:
POLL_INTERVALdefines how often your script checks status.MAX_ATTEMPTSdefines how long your script waits before timeout (POLL_INTERVAL x MAX_ATTEMPTS).- Lower-priority jobs can take longer, so increase
MAX_ATTEMPTSand, if needed, use a longerPOLL_INTERVAL.
- The final payload contains per-input results, matching what you would get from individual API calls.
This pattern is the same for all wrapped Geoapify APIs; only api, params, and inputs change.
How Much Does It Cost?
We calculate API usage in credits. Our Free plan includes up to 3000 credits / day. See all plans on the Pricing page >>
Batch API cost has three parts:
1credit to create a batch job (POST /v1/batch)1credit to get batch job status/result (GET /v1/batch?id=...)- wrapped API cost multiplied by
priority
In short:
Total credits = 1 (create) + 1 (status/result) + (wrapped API credits × priority)
Examples:
- Example 1: wrapped API work costs
1000credits,priority=0.5
Total =1 + 1 + (1000 × 0.5) = 502credits - Example 2: wrapped API work costs
1000credits,priority=1
Total =1 + 1 + (1000 × 1) = 1002credits
Each extra status check (
GET /v1/batch?id=...) also costs1credit. With lowerpriority, jobs can take longer, so wait longer between checks and use a higher polling interval.
Learn More
Explore related pages to choose the right API endpoint to wrap with Batch API and find endpoint-specific request examples:

Batch Geocoding - Bulk Convert Addresses to Lat/Long

JavaScript Tutorial: Batch Geocoding and API Rate Limits

Batch Geocoding in Python
FAQ
What is Batch API?
Batch API is an asynchronous service that executes large Geoapify API workloads in background jobs. You submit a job, track its status, and fetch results when processing is finished.
Which Geoapify APIs can I run with Batch API?
Batch API can wrap Geoapify endpoints that return JSON responses. It is not intended for image or map tile endpoints. Common examples include Geocoding API, Reverse Geocoding API, Place Details API, and Route Planner API.
When should I use Batch API instead of synchronous requests?
Use Batch API for larger non-interactive processing, such as imports, periodic refreshes, data enrichment, and back-office pipelines. For immediate user-facing responses, synchronous APIs are usually a better fit.
How does the priority parameter affect processing time and cost?
The priority value affects both queue priority and price multiplier for the wrapped API work. Lower priority reduces cost but can increase processing time. Higher priority is processed faster under load but gives less or no cost benefit.
What are the minimum and maximum priority values?
Batch API supports priority values from 0.5 to 1.0.
How many input records can I include in one batch request?
You can include up to 1000 input records in a single batch request.
How long are batch job results available for retrieval?
Batch job results are available for retrieval for 24 hours.
What do HTTP 202 and HTTP 200 mean in Batch API responses?
HTTP 202 means the batch job is accepted and still processing in the background. HTTP 200 means the result payload is ready and returned.
What happens if some records fail while others succeed in the same batch job?
Batch API returns each input item result exactly as returned by the wrapped API. Successful items include successful payloads, and failed items include error payloads for those specific records.
