Reten Docs

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

FieldTypeRequiredDescription
itemsobject[]YesList of routes to write (minimum 1, maximum 500).

Each element of items:

FieldTypeRequiredDescription
codestringYesCode of the route. Upsert key.
namestringYesDisplay 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

FieldTypeDescription
summary.totalnumberTotal items submitted.
summary.creatednumberItems inserted (new routes).
summary.updatednumberItems updated (existing routes modified).
summary.failednumberItems that could not be persisted.
errorsobject[]Detail per failed item (empty if all succeeded).
errors[].indexnumberPosition (0-based) of the item within the submitted items array.
errors[].identifierstringThe code of the failed item.
errors[].errorstringStable error code (see table below).
errors[].messagestringHuman/log-readable message with the cause.

Per-item error codes

errorMeaning
upsert_errorThe item could not be persisted; message carries the cause.

Errors (for the whole request)

StatusDescription
400items 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.
401Missing or invalid API key.
403The API key lacks the route:batch-upsert permission.