# Bulk Operations API Perform operations on multiple contacts at once. Bulk endpoints accept an array of contact IDs and apply the action to all of them in a single request. > [!quote] Scale Your Workflows > Tag 500 contacts, update a field across your entire book, or clean up duplicates - ==all in one API call.== ## Requirements All bulk endpoints require: | Header | Required | Description | |--------|----------|-------------| | `Authorization` | Yes | `Bearer rlb_your_key` | | `Content-Type` | Yes | `application/json` | | `X-Book-ID` | Yes | UUID of the book | --- ## Bulk Delete Contacts Delete multiple contacts in a single request. ``` POST /api/v1/contacts/bulk-delete ``` ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `contact_ids` | array of UUIDs | Yes | Contact IDs to delete (max 10,000) | ### Example Request ```bash curl -X POST "https://app.relaybook.io/api/v1/contacts/bulk-delete" \ -H "Authorization: Bearer rlb_your_key" \ -H "Content-Type: application/json" \ -H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \ -d '{ "contact_ids": [ "f47ac10b-58cc-4372-a567-0e02b2c3d479", "b23dc4e5-6789-4abc-def0-123456789abc", "d34ef5a6-7890-4bcd-ef01-234567890def" ] }' ``` ### Response ``` HTTP/1.1 200 OK ``` ```json { "data": { "deleted": 3 } } ``` > [!note] Permanent deletion > Deleted contacts cannot be recovered. Related data (labels, interactions, campaign enrollments) is also removed. ### Errors | Status | Code | Cause | |--------|------|-------| | 400 | `MISSING_BOOK` | `X-Book-ID` header is missing | | 400 | `INVALID_INPUT` | Empty contact_ids or exceeds 10,000 limit | | 403 | `FORBIDDEN` | Book doesn't belong to your team | | 500 | `SERVER_ERROR` | Database error | --- ## Bulk Add Label Add a label to multiple contacts at once. Contacts that already have the label are silently skipped. ``` POST /api/v1/contacts/bulk-add-label ``` ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `contact_ids` | array of UUIDs | Yes | Contact IDs to tag | | `label_id` | UUID | Yes | Label to add | ### Example Request ```bash curl -X POST "https://app.relaybook.io/api/v1/contacts/bulk-add-label" \ -H "Authorization: Bearer rlb_your_key" \ -H "Content-Type: application/json" \ -H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \ -d '{ "contact_ids": ["f47ac10b-58cc-4372-a567-0e02b2c3d479", "b23dc4e5-6789-4abc-def0-123456789abc"], "label_id": "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f" }' ``` ### Response ``` HTTP/1.1 200 OK ``` ```json { "data": { "added": 2 } } ``` ### Errors | Status | Code | Cause | |--------|------|-------| | 400 | `INVALID_INPUT` | Missing contact_ids or label_id | | 403 | `FORBIDDEN` | Book doesn't belong to your team | | 500 | `SERVER_ERROR` | Database error | --- ## Bulk Remove Label Remove a label from multiple contacts. ``` POST /api/v1/contacts/bulk-remove-label ``` ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `contact_ids` | array of UUIDs | Yes | Contact IDs to untag | | `label_id` | UUID | Yes | Label to remove | ### Example Request ```bash curl -X POST "https://app.relaybook.io/api/v1/contacts/bulk-remove-label" \ -H "Authorization: Bearer rlb_your_key" \ -H "Content-Type: application/json" \ -H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \ -d '{ "contact_ids": ["f47ac10b-58cc-4372-a567-0e02b2c3d479", "b23dc4e5-6789-4abc-def0-123456789abc"], "label_id": "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f" }' ``` ### Response ``` HTTP/1.1 200 OK ``` ```json { "data": { "removed": 2 } } ``` ### Errors | Status | Code | Cause | |--------|------|-------| | 400 | `INVALID_INPUT` | Missing contact_ids or label_id | | 403 | `FORBIDDEN` | Book doesn't belong to your team | | 500 | `SERVER_ERROR` | Database error | --- ## Bulk Update Custom Field Set a custom field value on multiple contacts. Creates the value if it doesn't exist, updates it if it does. ``` POST /api/v1/contacts/bulk-update-field ``` ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `contact_ids` | array of UUIDs | Yes | Contact IDs to update | | `field_definition_id` | UUID | Yes | Custom field definition to set | | `value` | string | Yes | Value to apply to all contacts | ### Example Request ```bash curl -X POST "https://app.relaybook.io/api/v1/contacts/bulk-update-field" \ -H "Authorization: Bearer rlb_your_key" \ -H "Content-Type: application/json" \ -H "X-Book-ID: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \ -d '{ "contact_ids": ["f47ac10b-58cc-4372-a567-0e02b2c3d479", "b23dc4e5-6789-4abc-def0-123456789abc"], "field_definition_id": "fd1a2b3c-d4e5-4f6a-7b8c-9d0e1f2a3b4c", "value": "https://www.example.com/listing" }' ``` ### Response ``` HTTP/1.1 200 OK ``` ```json { "data": { "updated": 2 } } ``` ### Errors | Status | Code | Cause | |--------|------|-------| | 400 | `INVALID_INPUT` | Missing contact_ids or field_definition_id | | 403 | `FORBIDDEN` | Book doesn't belong to your team | | 404 | `NOT_FOUND` | Custom field definition doesn't exist in this book | | 500 | `SERVER_ERROR` | Database error | --- ## Example: Tag and Enroll Contacts in a Campaign A common workflow - tag a batch of contacts, then enroll them in a drip campaign: ```bash # 1. Add "New Customer" label to contacts curl -X POST https://app.relaybook.io/api/v1/contacts/bulk-add-label \ -H "Authorization: Bearer rlb_your_key" \ -H "X-Book-ID: your-book-id" \ -H "Content-Type: application/json" \ -d '{ "contact_ids": ["id-1", "id-2", "id-3"], "label_id": "new-customer-label-id" }' # 2. Set their onboarding URL curl -X POST https://app.relaybook.io/api/v1/contacts/bulk-update-field \ -H "Authorization: Bearer rlb_your_key" \ -H "X-Book-ID: your-book-id" \ -H "Content-Type: application/json" \ -d '{ "contact_ids": ["id-1", "id-2", "id-3"], "field_definition_id": "onboarding-url-field-id", "value": "https://app.example.com/welcome" }' # 3. Enroll them in the onboarding campaign curl -X POST https://app.relaybook.io/api/v1/campaigns/CAMPAIGN_ID/participants \ -H "Authorization: Bearer rlb_your_key" \ -H "X-Book-ID: your-book-id" \ -H "Content-Type: application/json" \ -d '{"contact_ids": ["id-1", "id-2", "id-3"]}' ``` --- ## Limits - Maximum **10,000 contact IDs** per bulk request - All contacts must belong to the book specified in `X-Book-ID` - Labels and custom fields must belong to the same book - Contacts not found in the book are silently skipped --- **Next:** Set up [[Campaigns|automated email campaigns]] for your contacts, or explore [[Webhooks]] for real-time event notifications.