KasarKasar Docs
API Reference

Bulk Operations

Perform batch updates, add or remove relations on multiple records in a single API call.

The bulk endpoint lets you apply the same operation to multiple records at once. It supports field updates and relation management, with per-record permission checks.

Bulk Operation

POST /api/v1/bulk

Request Body

{
  "action": "update_field",
  "object_name": "contacts",
  "record_ids": ["id-1", "id-2", "id-3"],
  "field_name": "status",
  "field_value": "qualified"
}

Actions

ActionDescriptionExtra Fields
update_fieldSet a field value on all specified recordsfield_name, field_value
add_relationAdd related records to a relation fieldrelation_field, target_ids
remove_relationRemove related records from a relation fieldrelation_field, target_ids

Common Fields

FieldTypeRequiredDescription
actionstringYesOne of update_field, add_relation, remove_relation
object_namestringYesThe object to operate on (e.g. contacts, companies)
record_idsUUID[]YesArray of record IDs to modify

Action-Specific Fields

update_field:

FieldTypeDescription
field_namestringThe field to update. Must exist on the object.
field_valueanyThe new value to set

add_relation:

FieldTypeDescription
relation_fieldstringThe relation field name
target_idsUUID[]IDs of related records to add
junction_dataobjectOptional. Extra junction-table field values applied to each new link (for many-to-many relations with junction fields).

remove_relation:

FieldTypeDescription
relation_fieldstringThe relation field name. Must be a MANY_TO_MANY relation.
target_idsUUID[]IDs of related records to remove

Examples

Update a Field

Set the owner field on three contacts:

curl -X POST "https://kasar.app/api/v1/bulk" \
  -H "Authorization: Bearer ksr_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{
    "action": "update_field",
    "object_name": "contacts",
    "record_ids": [
      "550e8400-e29b-41d4-a716-446655440000",
      "660f9511-f3ac-52e5-b827-557766551111",
      "770a0622-a4bd-63f6-c938-668877662222"
    ],
    "field_name": "owner",
    "field_value": "alice-workspace-id"
  }'

Add Relations

Link two tags to multiple opportunities:

curl -X POST "https://kasar.app/api/v1/bulk" \
  -H "Authorization: Bearer ksr_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{
    "action": "add_relation",
    "object_name": "opportunities",
    "record_ids": ["opp-id-1", "opp-id-2"],
    "relation_field": "tags",
    "target_ids": ["tag-id-1", "tag-id-2"]
  }'

Remove Relations

curl -X POST "https://kasar.app/api/v1/bulk" \
  -H "Authorization: Bearer ksr_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{
    "action": "remove_relation",
    "object_name": "contacts",
    "record_ids": ["contact-id-1", "contact-id-2"],
    "relation_field": "tags",
    "target_ids": ["tag-id-1"]
  }'

Response

The response shape depends on the action performed. Every response includes an errors array (empty when nothing failed, capped at 50 entries) and a total.

update_field: total is the number of record IDs supplied.

{
  "action": "update_field",
  "updated": 3,
  "failed": 0,
  "errors": [],
  "total": 3
}

add_relation: the success counter is processed (the number of records that had relations added). total is the number of record IDs supplied.

{
  "action": "add_relation",
  "processed": 2,
  "failed": 0,
  "errors": [],
  "total": 2
}

remove_relation: removed is the count of links actually unlinked, and total is record_ids × target_ids (the number of attempted unlinks).

{
  "action": "remove_relation",
  "removed": 2,
  "failed": 0,
  "errors": [],
  "total": 2
}

Partial Failures

If some records fail (for example, due to permission checks), they appear in the errors array. Each entry has an id (the failing record ID) and a reason string:

{
  "action": "update_field",
  "updated": 2,
  "failed": 1,
  "errors": [
    {
      "id": "770a0622-a4bd-63f6-c938-668877662222",
      "reason": "You do not have permission to update this record"
    }
  ],
  "total": 3
}

RBAC checks are performed per record. If the user lacks permission on a specific record, that record fails but the rest of the batch proceeds.

Error Responses

These errors apply to the whole request and are returned with HTTP 400.

StatusCodeDescription
400INVALID_OBJECTThe object_name does not exist
400MISSING_REQUIRED_FIELDrecord_ids is empty, or an action is missing its required fields (field_name for update_field; relation_field and target_ids for relation actions)
400INVALID_FIELDfield_name does not exist on the object, or relation_field is not a MANY_TO_MANY relation (for remove_relation)

On this page