From c52972421d326a0bd5c7cabf4ed24636a9571297 Mon Sep 17 00:00:00 2001 From: Keith Stenson <147769+kstenson@users.noreply.github.com> Date: Tue, 21 Apr 2026 09:29:39 +0100 Subject: [PATCH] docs(preview): add bulk contacts endpoint and merged contact 410 response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents two new Preview API features: 1. POST /contacts/bulk and GET /contacts/bulk/{id} — new bulk update endpoint with clean request format, async job tracking, and status polling (PR #495002) 2. 410 Gone with Link header for merged contacts on GET /contacts/{id} and GET /contacts/find_by_external_id/{external_id} — returns RFC 8288 Link header pointing to canonical contact (PR #497262) Co-Authored-By: Claude Opus 4.6 (1M context) --- descriptions/0/api.intercom.io.yaml | 368 +++++++++++++++++++++++++++- 1 file changed, 364 insertions(+), 4 deletions(-) diff --git a/descriptions/0/api.intercom.io.yaml b/descriptions/0/api.intercom.io.yaml index ebbedce..2cbb13d 100644 --- a/descriptions/0/api.intercom.io.yaml +++ b/descriptions/0/api.intercom.io.yaml @@ -5931,8 +5931,23 @@ paths: description: | You can fetch the details of a single contact. - {% admonition type="warning" name="Merged contacts" %} - If a contact has been merged into another contact via the Merge endpoint (POST /contacts/merge), requesting it by its original ID will return a `404 Not Found` error. Use the merged-into contact's ID instead. + {% admonition type="info" name="Merged contacts return 410 Gone" %} + If a contact has been merged into another contact via the Merge endpoint (`POST /contacts/merge`), requesting it by its original ID will return **HTTP 410 Gone** with a `Link` header pointing to the canonical (merged-into) contact. + + **Response headers:** + ``` + Link: ; rel="canonical" + ``` + + **Response body:** + ```json + { + "type": "error.list", + "errors": [{ "code": "contact_merged", "message": "This contact has been merged. See the 'Link' header for the canonical contact." }] + } + ``` + + The `Link` header contains the path to the final merge target, resolving multi-hop merge chains (up to 3 hops). {% /admonition %} responses: '200': @@ -6052,6 +6067,28 @@ paths: message: Access Token Invalid schema: "$ref": "#/components/schemas/error" + '410': + description: Contact Merged + headers: + Link: + description: 'Link to the canonical (merged-into) contact. Format: + `; rel="canonical"`' + schema: + type: string + example: '; rel="canonical"' + content: + application/json: + examples: + Contact Merged: + value: + type: error.list + request_id: 45b30bd1-75d2-40cc-bb39-74ac133a2836 + errors: + - code: contact_merged + message: This contact has been merged. See the 'Link' header + for the canonical contact. + schema: + "$ref": "#/components/schemas/error" delete: summary: Delete a contact parameters: @@ -6616,8 +6653,12 @@ paths: tags: - Contacts operationId: ShowContactByExternalId - description: You can fetch the details of a single contact by external ID. Note - that this endpoint only supports users and not leads. + description: | + You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads. + + {% admonition type="info" name="Merged contacts return 410 Gone" %} + If the contact with this external ID has been merged into another contact, the API returns **HTTP 410 Gone** with a `Link` header pointing to the canonical (merged-into) contact. See `GET /contacts/{id}` for details on the response format. + {% /admonition %} responses: '200': description: successful @@ -6736,6 +6777,28 @@ paths: message: Access Token Invalid schema: "$ref": "#/components/schemas/error" + '410': + description: Contact Merged + headers: + Link: + description: 'Link to the canonical (merged-into) contact. Format: + `; rel="canonical"`' + schema: + type: string + example: '; rel="canonical"' + content: + application/json: + examples: + Contact Merged: + value: + type: error.list + request_id: 1fb28be7-cda6-4029-b4da-447ef61cb61a + errors: + - code: contact_merged + message: This contact has been merged. See the 'Link' header + for the canonical contact. + schema: + "$ref": "#/components/schemas/error" "/contacts/{id}/archive": post: summary: Archive contact @@ -6814,6 +6877,168 @@ paths: application/json: schema: "$ref": "#/components/schemas/contact_blocked" + "/contacts/bulk": + post: + summary: Bulk update contacts + parameters: + - name: Intercom-Version + in: header + schema: + "$ref": "#/components/schemas/intercom_version" + tags: + - Contacts + operationId: BulkUpdateContacts + description: | + You can bulk update contacts by submitting an array of contact objects with the fields to update. Each contact must include an `id` field identifying the contact to update. + + The endpoint creates an async job that processes the updates in the background. Use the returned job ID with `GET /contacts/bulk/{id}` to check the job status. + + {% admonition type="info" name="Limits" %} + - Maximum of 100 contacts per request. + - You can append tasks to an existing job by including `job.id` in the request body. + {% /admonition %} + requestBody: + content: + application/json: + schema: + "$ref": "#/components/schemas/bulk_update_contacts_request" + examples: + successful: + summary: Successful + value: + contacts: + - id: abc123 + language_override: fr + - id: def456 + name: Updated Name + - id: ghi789 + language_override: es + name: "María García" + append_to_existing_job: + summary: Append to existing job + value: + contacts: + - id: abc123 + language_override: de + job: + id: job_v2_1 + responses: + '202': + description: Accepted + content: + application/json: + examples: + successful: + value: + id: job_v2_1 + type: contacts.bulk.job + state: running + created_at: 1713360000 + updated_at: 1713360060 + completed_at: + tasks: + - id: task_v2_1 + item_count: 3 + state: pending + created_at: 1713360000 + started_at: + completed_at: + url: https://api.intercom.io/contacts/bulk/job_v2_1 + schema: + "$ref": "#/components/schemas/contacts_bulk_job" + '401': + description: Unauthorized + content: + application/json: + examples: + Unauthorized: + value: + type: error.list + request_id: 2859da57-c83f-405c-8166-240a312442a3 + errors: + - code: unauthorized + message: Access Token Invalid + schema: + "$ref": "#/components/schemas/error" + '422': + description: Unprocessable Entity + content: + application/json: + examples: + missing_contacts: + value: + type: error.list + request_id: 2859da57-c83f-405c-8166-240a312442a3 + errors: + - code: missing_field + message: contacts field must be supplied + too_many_contacts: + value: + type: error.list + request_id: 2859da57-c83f-405c-8166-240a312442a3 + errors: + - code: invalid_parameter + message: maximum number of contacts per request is 100 + schema: + "$ref": "#/components/schemas/error" + "/contacts/bulk/{id}": + get: + summary: Get a bulk update job + parameters: + - name: Intercom-Version + in: header + schema: + "$ref": "#/components/schemas/intercom_version" + - name: id + in: path + description: The unique identifier for the bulk job. + example: job_v2_1 + required: true + schema: + type: string + tags: + - Contacts + operationId: ShowBulkUpdateContactsJob + description: | + You can check the status of a bulk contact update job. The `state` field indicates the overall job progress: `pending`, `running`, `completed`, or `completed_with_errors`. + responses: + '200': + description: successful + content: + application/json: + examples: + successful: + value: + id: job_v2_1 + type: contacts.bulk.job + state: completed + created_at: 1713360000 + updated_at: 1713360120 + completed_at: 1713360120 + tasks: + - id: task_v2_1 + item_count: 3 + state: completed + created_at: 1713360000 + started_at: 1713360060 + completed_at: 1713360120 + url: https://api.intercom.io/contacts/bulk/job_v2_1 + schema: + "$ref": "#/components/schemas/contacts_bulk_job" + '401': + description: Unauthorized + content: + application/json: + examples: + Unauthorized: + value: + type: error.list + request_id: 2859da57-c83f-405c-8166-240a312442a3 + errors: + - code: unauthorized + message: Access Token Invalid + schema: + "$ref": "#/components/schemas/error" "/content_snippets": get: summary: List all content snippets @@ -19986,6 +20211,51 @@ components: type: array items: $ref: "#/components/schemas/brand" + bulk_update_contacts_request: + title: Bulk Update Contacts Request + type: object + description: Request body for bulk updating contacts. + required: + - contacts + properties: + contacts: + type: array + description: An array of contact objects to update. Each must include an `id` + and the fields to update. Maximum 100 contacts per request. + maxItems: 100 + items: + type: object + required: + - id + properties: + id: + type: string + description: The unique identifier for the contact. + example: abc123 + email: + type: string + description: The contact's email address. + example: joe@example.com + name: + type: string + description: The contact's name. + example: Joe Bloggs + language_override: + type: string + description: A preferred language setting for the contact, used by + the Intercom Messenger. + example: fr + custom_attributes: + type: object + description: Custom attributes to update on the contact. + job: + type: object + description: Optional. Include to append tasks to an existing job. + properties: + id: + type: string + description: The ID of an existing bulk job to append to. + example: job_v2_1 company: title: Company type: object @@ -20550,6 +20820,96 @@ components: example: 100 pages: "$ref": "#/components/schemas/cursor_pages" + contacts_bulk_job: + title: Contacts Bulk Job + type: object + x-tags: + - Contacts + description: A bulk job for updating contacts asynchronously. Track the job + status using the `state` field. + properties: + id: + type: string + description: The unique identifier for the bulk job. + example: job_v2_1 + type: + type: string + description: The type of the object. + enum: + - contacts.bulk.job + example: contacts.bulk.job + state: + type: string + description: The current state of the job. + enum: + - pending + - running + - completed + - completed_with_errors + example: running + created_at: + type: integer + format: date-time + description: The time the job was created as a UNIX timestamp. + example: 1713360000 + updated_at: + type: integer + format: date-time + description: The time the job was last updated as a UNIX timestamp. + example: 1713360060 + completed_at: + type: integer + format: date-time + nullable: true + description: The time the job completed as a UNIX timestamp. Null if not + yet completed. + example: 1713360120 + tasks: + type: array + description: The tasks that make up this bulk job. + items: + type: object + properties: + id: + type: string + description: The unique identifier for the task. + example: task_v2_1 + item_count: + type: integer + description: The number of items in this task. + example: 3 + state: + type: string + description: The current state of the task. + enum: + - pending + - running + - completed + - completed_with_errors + example: pending + created_at: + type: integer + format: date-time + description: The time the task was created as a UNIX timestamp. + example: 1713360000 + started_at: + type: integer + format: date-time + nullable: true + description: The time the task started as a UNIX timestamp. Null if + not yet started. + example: 1713360060 + completed_at: + type: integer + format: date-time + nullable: true + description: The time the task completed as a UNIX timestamp. Null + if not yet completed. + example: 1713360120 + url: + type: string + description: The URL to check the job status. + example: https://api.intercom.io/contacts/bulk/job_v2_1 contact_location: title: Contact Location type: object