How to run a full batch job
The following example presents a full lifecycle of a job using cURL and bash, illustrating how to create a job, poll for its status until processing completes, and then download the results and potential errors.
Prerequisite
Before you begin, make sure to have a HERE platform account and an App with OAuth credentials in ~/.here.
A file input.csv with input data.
Install the following tools:
Script
#!/bin/bash
# config
pollTimeout="30s" # 10s is good for small jobs (<10k records). For lager use 30-60s.
# Get OAuth token form olp cli. This will be passed as 'Authorization' header.
# As alternative an ApiKey can be passed as query parameter.
YOUR_BEARER_TOKEN=$(olp api token get --json | jq -r .accessToken)
# Submit job
resp=$(curl --request 'POST' \
'https://batch.search.hereapi.com/v7/batch/jobs?serviceHrn=hrn%3Ahere%3Aservice%3A%3Aolp-here%3Asearch-geocode-7&inputDelimiter=%7C&outputDelimiter=%7C&outputColumns=position%7Ctitle%7Cid' \
--header "Authorization: Bearer ${YOUR_BEARER_TOKEN}" \
--header 'accept: application/json' \
--header 'Content-Type: text/plain' \
--data-binary @input.csv \
2>/dev/null)
# Print response and jobId
echo ${resp} | jq
jobId=$(echo $resp | jq -r '.id') && echo Job Id is: ${jobId}
# Extract 'status'
status=$(echo $resp | jq -r '.status')
# Poll metadata until 'completed' 'failure' or 'deleted'
while [[ "completed failure deleted" != *${status}* ]]; do
# Sleep for configured time
sleep ${pollTimeout}
# Fetch metadata
resp=$(curl --request 'GET' \
"https://batch.search.hereapi.com/v7/batch/jobs/${jobId}" \
--header "Authorization: Bearer ${YOUR_BEARER_TOKEN}" \
--header 'accept: application/json' \
2>/dev/null)
# Extract status
status=$(echo $resp | jq -r '.status')
# Print timestamp, status and progress
# Sample output: 2025-08-12 13:25:32+02:00 inProgress - 12000/127050 processed.
echo "$(date --rfc-3339=seconds) ${status} - $(echo ${resp} | jq -r '.records.processed')/$(echo ${resp} | jq -r '.records.total') processed."
done
# Job is completed.
# Print some statistics
echo Job is completed. Statistics:
echo $resp | jq '.records'
echo Downloading output.
# Download results
# Extract URL to results from metadata 'resultsHref'
resultsHref=$(echo $resp | jq -r '.resultsHref')
# If resultHref is empty, there are no results. All records caused an error.
if [ "${resultsHref}" ]; then
curl --request 'GET' \
"${resultsHref}" \
--header "Authorization: Bearer ${YOUR_BEARER_TOKEN}" \
--header 'accept: text/plain' \
-o "${jobId}_results.csv" \
2>/dev/null
echo Results saved at ${jobId}_results.csv
else
echo No results provided.
fi
# Download errors
# Extract URL to errors from metadata 'errorsHref'
errorsHref=$(echo $resp | jq -r '.errorsHref')
# If errorsHref is empty, there are no errors. Great!
if [ "${errorsHref}" ]; then
curl --request 'GET' \
"${errorsHref}" \
--header "Authorization: Bearer ${YOUR_BEARER_TOKEN}" \
--header 'accept: text/plain' \
-o "${jobId}_errors.csv" \
2>/dev/null
echo Results saved at ${jobId}_errors.csv
else
echo No errors provided.
fi
echo Job done.Description
- Get an OAuth token form OLP CLI
- Submit a job and save response.
- Extract the
jobIdand status for later use. - Poll metadata until status is
completedfailureordeleted. - Print the processed records vs. total while polling.
- Print some statistics about the job.
- Download the results based on metadata
resultsHref. If empty, there are no results. All records failed. - Download errors based on metadata
errorsHref. If empty, there are no errors.
Input
The input is similar to this:
recId|q|country
0001|Invalidenstraße 116 10115 Berlin|DEU
0002|Am Kronberger Hang 8 65824 Schwalbach|DEU
0003|425 W Randolph St Chicago IL 60606|USA
0004|One Main Street Cambridge MA 02142|USA
...Output
The script output will look like this:
{
"id": "<jobId>",
"serviceHrn": "hrn:here:service::olp-here:search-geocode-7",
"billingTags": [],
"status": "queued",
"href": "https://batch.search.hereapi.com/v7/batch/jobs/<jobId>"
}
Job Id is: <jobId>
2025-08-14 11:23:00+02:00 inProgress - 0/127050 processed.
2025-08-14 11:23:30+02:00 inProgress - 8000/127050 processed.
2025-08-14 11:24:00+02:00 inProgress - 17000/127050 processed.
2025-08-14 11:24:30+02:00 inProgress - 26000/127050 processed.
2025-08-14 11:25:00+02:00 inProgress - 34000/127050 processed.
2025-08-14 11:25:31+02:00 inProgress - 44000/127050 processed.
2025-08-14 11:26:01+02:00 inProgress - 54000/127050 processed.
2025-08-14 11:26:31+02:00 inProgress - 65000/127050 processed.
2025-08-14 11:27:01+02:00 inProgress - 76000/127050 processed.
2025-08-14 11:27:31+02:00 inProgress - 87000/127050 processed.
2025-08-14 11:28:02+02:00 inProgress - 100000/127050 processed.
2025-08-14 11:28:32+02:00 inProgress - 112000/127050 processed.
2025-08-14 11:29:02+02:00 inProgress - 125050/127050 processed.
2025-08-14 11:29:32+02:00 completed - 127050/127050 processed.
Job is completed. Statistics:
{
"total": 127050,
"valid": 127050,
"invalid": 0,
"processed": 127050,
"pending": 0,
"succeeded": 127050,
"failed": 0
}
Downloading output.
Results saved at <jobId>_results.csv
No errors provided.
Job done.Result
The Result is similar to this:
recId|seqNumber|seqLength|position|title|id
1|1|1|(52.53086,13.38469)|Invalidenstraße 116, 10115 Berlin, Deutschland|here:af:streetsection:tVuvjJYhO86yd5jk1cmzNB:CgcIBCCE59BeEAEaAzExNg
2|1|1|(50.16193,8.53361)|Am Kronberger Hang 8, Hillsite, 65824 Schwalbach am Taunus, Deutschland|here:af:streetsection:6cjWtEIO2t07E.pKRVV5bA:CgcIBCCa46pZEAEaATgiCEhpbGxzaXRl
3|1|1|(41.88432,-87.63877)|425 W Randolph St, Chicago, IL 60606-1515, United States|here:af:streetsection:hdZ6xBRUraY46IQZCqZidD:CgcIBCDMlOElEAEaAzQyNQ
4|1|1|(42.36225,-71.0803)|1 Main St, Cambridge, MA 02142-1517, United States|here:af:streetsection:k-3ojKsslOuU0B1PF4J4HD:CgcIBCCq3cJGEAEaATE
...Updated 29 days ago