Workspace API
Batch Writes
Write up to 100 workspace records per call with the /batch sibling endpoints.
Every workspace write has a batch sibling that applies up to 100 records in one call:
POST /workspace/accounts/upsert/batchPOST /workspace/accounts/delete/batchPOST /workspace/projects/upsert/batchPOST /workspace/projects/delete/batchPOST /workspace/contacts/upsert/batchPOST /workspace/contacts/delete/batchPOST /workspace/views/upsert/batchPOST /workspace/views/delete/batchPOST /workspace/views/{id}/records/add/batchPOST /workspace/views/{id}/records/delete/batchPOST /workspace/favorite-views/upsert/batchPOST /workspace/favorite-views/delete/batchAll of these cost 0 credits. Favorite batch routes require a user JWT.
The Workspace API requires the Pro plan. A request from a non-Pro workspace or a non-member receives 403 forbidden.
Request body
Upsert batches take inputs, an array of 1-100 elements, where each element is exactly the corresponding single endpoint’s request body (same identifiers, same partial-update semantics):
{ "inputs": [ { "account_id": "1c9e...", "icp_tier": "disqualified" }, { "match": { "domain": "acme.example" }, "icp_tier": "tier_1", "tags": ["hot"] } ]}Delete batches take ids, an array of 1-100 record UUIDs (note the verb: batch deletes are POST with a body, unlike the single DELETE /{id}):
{ "ids": ["1c9e...", "2d0f..."] }Response: per-item results
Batch writes are never all-or-nothing. Valid records apply; each failed record reports its own error. Results come back in input order:
{ "data": { "results": [ { "index": 0, "status": "ok", "record": { "account_id": "1c9e...", "icp_tier": "disqualified" } }, { "index": 1, "status": "error", "error": { "code": "ambiguous_match", "message": "Domain 'acme.example' matches more than one account; pass account_id instead." } } ] }, "metadata": { "credits": 0, "succeeded": 1, "failed": 1 }}Item errors reuse the single-endpoint codes: bad_request (malformed record or missing identifier), not_found (a match that resolves to nothing), ambiguous_match (a match that resolves to more than one record). Retry just the failed indexes.
A batch-level 400 occurs only for envelope problems: an empty array, more than 100 elements, or a malformed body. In that case nothing is applied. Envelope failures are rejected by request validation, so the response carries the request-validation error shape described in Errors, not the { "error": { "code", "message" } } envelope.
Semantics
- Records apply sequentially in input order. If one batch targets the same record twice, the later element wins, exactly as two single calls would.
- Batch deletes are idempotent per item: an id that is not in your book still reports
ok. - Setting
icp_tierin an account batch schedules one atlas recompute covering every touched account. - An upsert item that writes successfully but whose row cannot be read back (a narrow concurrent-delete window) still reports
status: "ok", with a minimal record carrying just the resolved id. The single-record endpoints returndata: nullin the same situation.