Batch Upsert
Create or update up to 500 routes in a single operation, with per-item result reporting.
POST /api/integration/routes/batch-upsert
Creates or updates (upsert) up to 500 routes in a single operation. It is the integration entry point for loading the route catalog from an external system.
Auth: Required — route:batch-upsert permission
Partial success. Once the body passes format validation, each item is
processed independently: the ones that can be persisted are, and the ones that
fail are reported in errors[] with a stable code — a failing item does not
undo the others. Always check summary.failed and errors in the response.
Upsert key
Each item is matched against existing routes by code. If a route with that code exists it is updated (counted in summary.updated); otherwise it is created (summary.created).
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
items | object[] | Yes | List of routes to write (minimum 1, maximum 500). |
Each element of items:
| Field | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Code of the route. Upsert key. |
name | string | Yes | Display name of the route. |
Example
curl -X POST "https://api.reten.ai/api/integration/routes/batch-upsert" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "code": "ROUTE-NORTH", "name": "North Zone" },
{ "code": "ROUTE-SOUTH", "name": "South Zone" },
{ "code": "ROUTE-CENTRAL", "name": "Central Zone" }
]
}'const response = await fetch(
"https://api.reten.ai/api/integration/routes/batch-upsert",
{
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
items: [
{ code: "ROUTE-NORTH", name: "North Zone" },
{ code: "ROUTE-SOUTH", name: "South Zone" },
{ code: "ROUTE-CENTRAL", name: "Central Zone" },
],
}),
},
);
const result = await response.json();import requests
response = requests.post(
"https://api.reten.ai/api/integration/routes/batch-upsert",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"items": [
{"code": "ROUTE-NORTH", "name": "North Zone"},
{"code": "ROUTE-SOUTH", "name": "South Zone"},
{"code": "ROUTE-CENTRAL", "name": "Central Zone"},
],
},
)
result = response.json()Response 200 OK
In this example, ROUTE-NORTH already existed and was updated, and the other two routes were created:
{
"summary": {
"total": 3,
"created": 2,
"updated": 1,
"failed": 0
},
"errors": []
}Response fields
| Field | Type | Description |
|---|---|---|
summary.total | number | Total items submitted. |
summary.created | number | Items inserted (new routes). |
summary.updated | number | Items updated (existing routes modified). |
summary.failed | number | Items that could not be persisted. |
errors | object[] | Detail per failed item (empty if all succeeded). |
errors[].index | number | Position (0-based) of the item within the submitted items array. |
errors[].identifier | string | The code of the failed item. |
errors[].error | string | Stable error code (see table below). |
errors[].message | string | Human/log-readable message with the cause. |
Per-item error codes
error | Meaning |
|---|---|
upsert_error | The item could not be persisted; message carries the cause. |
Errors (for the whole request)
| Status | Description |
|---|---|
400 | items empty or with more than 500 elements; an item that does not match the format (missing required field or invalid type); or a property not declared here. |
401 | Missing or invalid API key. |
403 | The API key lacks the route:batch-upsert permission. |