Before you start
Run these examples on a trusted server with TAROT_API_KEY set in its environment. Use X-Tarot-API-Key on every request. Never expose the key in client-side code, including browser or mobile app code. See Getting an API key.
Choose the scenario
A scenario groups jobs to be planned and dispatched together, usually for a service date. This walkthrough uses POST /v3/core/jobs/bulk_create to find or create the scenario and add jobs in one request.
Within the named organisation, scenario.name and scenario.scheduled_date identify the scenario. With force_new_scenario: false, an existing match is reused; otherwise a new scenario is created. If multiple scenarios match, the most recently created is selected. Use consistent names and dates rather than deliberately creating duplicate matches.
You can inspect existing scenarios first:
GET /v3/core/scenarios?page=1&per_page=100
curl --fail-with-body -X GET "https://api.optimiser.app/v3/core/scenarios?page=1&per_page=100" \
-H "X-Tarot-API-Key: $TAROT_API_KEY"
import os, requests
response = requests.get(
"https://api.optimiser.app/v3/core/scenarios?page=1&per_page=100",
headers={"X-Tarot-API-Key": os.environ["TAROT_API_KEY"]},
timeout=60,
)
response.raise_for_status()
print(response.json())
const response = await fetch(`https://api.optimiser.app/v3/core/scenarios?page=1&per_page=100`, {
method: "GET",
headers: {
"X-Tarot-API-Key": process.env.TAROT_API_KEY,
},
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
console.log(await response.json());
Collection responses contain data, page, per_page, total_pages, and total_count, not a bare array. Process data, then request each subsequent page through total_pages, preserving your filters. Examples show the first page only.
Create jobs and units
Replace the organisation name with the exact existing name accessible to your key. Change the sample date to your actual service date and use your own job and parcel identifiers. Include the scenario object: omitting it sends jobs to the organisation job pool instead.
Prepare a JSON request body like the following. The examples assume it is available in jobs.json.
{
"organisation": {
"name": "Your organisation name"
},
"scenario": {
"name": "Deliveries",
"scheduled_date": "2026-10-20"
},
"jobs": [
{
"uid": "DEL-20261020-001",
"duration": 2,
"location": {
"address": "1 Martin Place, Sydney NSW 2000, Australia",
"lat": -33.8679,
"lon": 151.2073
},
"arrive_after": "09:00:00",
"leave_by": "17:00:00",
"priority": false,
"customer_name": "Example Customer",
"comments": "Use the loading dock; call on arrival.",
"dock_location": "Rear entrance",
"extra_fields": {
"order_reference": "ORDER-20261020-001"
},
"units": [
{
"uid": "PARCEL-20261020-001"
}
],
"returns": []
}
],
"reader_settings": {
"force_new_scenario": false,
"job_pool_force_new_job": true,
"update_client_address": true,
"scenario_force_new_job": false
}
}
POST /v3/core/jobs/bulk_create
curl --fail-with-body -X POST "https://api.optimiser.app/v3/core/jobs/bulk_create" \
-H "X-Tarot-API-Key: $TAROT_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @jobs.json
import os, requests, json
with open("jobs.json") as file:
payload = json.load(file)
response = requests.post(
"https://api.optimiser.app/v3/core/jobs/bulk_create",
headers={"X-Tarot-API-Key": os.environ["TAROT_API_KEY"]},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())
import { readFile } from "node:fs/promises";
const payload = await readFile("jobs.json", "utf8");
const response = await fetch(`https://api.optimiser.app/v3/core/jobs/bulk_create`, {
method: "POST",
headers: {
"X-Tarot-API-Key": process.env.TAROT_API_KEY,
"Content-Type": "application/json",
},
body: payload,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
console.log(await response.json());
Important job fields
| Field | Meaning |
|---|---|
uid | Your job identifier. Keep it stable for reconciliation; use a distinct value for each intended stop. |
duration | Service time at the stop, in minutes. |
location | Address plus latitude/longitude. Supplying accurate coordinates avoids ambiguity; address-only jobs are geocoded. |
arrive_after / leave_by | Visit time window, using HH:MM:SS in the scenario’s planning timezone. |
spec_type | Optional compatibility/skill constraints; coordinate the values with your planners and driver setup. |
priority | Whether to prioritise the job during planning. |
customer_name / comments / dock_location | Customer and delivery instructions. |
extra_fields | Additional integration metadata as an object. |
units | Parcels or other deliverables; each unit can carry a uid such as its barcode. |
returns | Return items, where applicable. See the schema for their fields. |
See CreateBulkJobsSchema schema reference, JobBulkSchema schema reference, and UnitSchema schema reference for the full request fields and constraints. Swagger paths use the upstream /api prefix; send integration requests through /v3/core.
Matching settings
These reader_settings fields accept true or false.
| Field | false | true |
|---|---|---|
force_new_scenario | Reuse a scenario with matching name and date, or create one if none exists. | Create a new scenario. |
scenario_force_new_job | Match scenario jobs by uid and append supplied units and returns; create unmatched jobs. | Create new scenario jobs. |
job_pool_force_new_job | When importing without a scenario, match job-pool jobs by uid and append supplied units and returns; create unmatched jobs. | Create new job-pool jobs. |
update_client_address | Keep linked client addresses unchanged. | Update a linked client’s address and coordinates when the imported job has a different address. |
Keep the returned IDs
A successful request returns HTTP 201 with an object containing scenario and jobs. Save scenario.id, each job’s id and scenario_id, and each unit’s id. Numeric Tarot IDs are different from your supplied uid values.
Ensure you have the scenario’s numeric ID, from this bulk-create response or GET /v3/core/scenarios. The following guides assume it is available in the SCENARIO_ID environment variable. Next, plan the scenario in Tarot Routing and retrieve its planned runs.