From e17322afe12804ab4fb789205e1e82f8c4d9c350 Mon Sep 17 00:00:00 2001 From: Mark Dennis Date: Thu, 22 Oct 2026 09:50:40 +0100 Subject: [PATCH 1/4] Align the 2.17 Custom Object Instances reference with what the API does Swaps the two delete operationIds so each matches its path, types custom_attributes values in the create request, documents the 400s and the delete 404s the API returns, explains the external_id lookup, and adds the accepted OAuth scopes to each operation. Co-Authored-By: Claude Opus 5.5 (1M context) --- descriptions/2.17/api.intercom.io.yaml | 142 +++++++++++++++++++++---- 1 file changed, 124 insertions(+), 18 deletions(-) diff --git a/descriptions/2.17/api.intercom.io.yaml b/descriptions/2.17/api.intercom.io.yaml index c87a7a84..e3a0d388 100644 --- a/descriptions/2.17/api.intercom.io.yaml +++ b/descriptions/2.17/api.intercom.io.yaml @@ -17731,7 +17731,10 @@ paths: tags: - Custom Object Instances operationId: createCustomObjectInstances - description: Create or update a custom object instance + description: | + Create or update a custom object instance + + Requires the `read_write_custom_object_instances` OAuth scope. responses: '200': description: successful @@ -17752,6 +17755,27 @@ paths: updated_at: 1734537745 schema: "$ref": "#/components/schemas/custom_object_instance" + '400': + description: Bad Request + content: + application/json: + examples: + Reserved external_id: + value: + type: error.list + request_id: 3f1a6d2b-9c47-4e58-8a01-6b7d2e4f9c13 + errors: + - code: bad_request + message: Invalid external_id value + Value does not match the attribute type: + value: + type: error.list + request_id: 5c8e4b17-2a6d-49f3-b0e5-71c9a3d82f46 + errors: + - code: parameter_invalid + message: Invalid value 'yesterday' for attribute 'ordered_at' + schema: + "$ref": "#/components/schemas/error" '401': $ref: "#/components/responses/Unauthorized" '404': @@ -17813,13 +17837,15 @@ paths: tags: - Custom Object Instances operationId: listCustomObjectInstances - description: |- + description: | List instances of a custom object type. Three modes are supported: - **No filter** — returns all instances for the type. - **`references_contact_id`** — returns instances associated with the given contact. - **`references_conversation_id`** — returns instances associated with the given conversation. - When **`external_id`** is provided, returns a single matching instance (not a list). + When **`external_id`** is provided, returns a single matching instance (not a list). If no instance matches, the response is still `200`, with the same body the single-instance endpoint returns for a miss. + + Requires the `read_conversations`, `read_users_companies`, `read_write_custom_object_instances` or `read_write_users` OAuth scope. responses: '200': description: successful @@ -17857,7 +17883,24 @@ paths: created_at: 1734537100 updated_at: 1734537100 schema: - "$ref": "#/components/schemas/custom_object_instances_paginated_list" + oneOf: + - "$ref": "#/components/schemas/custom_object_instances_paginated_list" + - "$ref": "#/components/schemas/custom_object_instance" + - "$ref": "#/components/schemas/custom_object_instance_not_found" + '400': + description: Bad Request + content: + application/json: + examples: + Both reference filters given: + value: + type: error.list + request_id: 7d2b9e54-6c13-4a87-95f0-2e8b4c71d9a3 + errors: + - code: bad_request + message: Cannot provide both references_contact_id and references_conversation_id + schema: + "$ref": "#/components/schemas/error" '401': $ref: "#/components/responses/Unauthorized" '404': @@ -17885,8 +17928,11 @@ paths: "$ref": "#/components/schemas/intercom_version" tags: - Custom Object Instances - operationId: deleteCustomObjectInstancesById - description: Delete a single Custom Object instance by external_id. + operationId: deleteCustomObjectInstancesByExternalId + description: | + Delete a single Custom Object instance by external_id. + + Requires the `read_write_custom_object_instances` OAuth scope. responses: '200': description: successful @@ -17903,7 +17949,26 @@ paths: '401': $ref: "#/components/responses/Unauthorized" '404': - $ref: "#/components/responses/ObjectNotFound" + description: Custom object type or instance not found + content: + application/json: + examples: + Instance not found: + value: + type: error.list + request_id: 9e4c1a86-3d75-42b9-8c60-5f1a7b93e2d4 + errors: + - code: not_found + message: Custom object instance not found + Type not found: + value: + type: error.list + request_id: 2a7f5c93-8b14-46e0-97d2-3c6e1b85a07f + errors: + - code: not_found + message: Custom object type `undefined` not found + schema: + "$ref": "#/components/schemas/error" "/custom_object_instances/{custom_object_type_identifier}/{custom_object_instance_id}": parameters: - name: custom_object_type_identifier @@ -17919,7 +17984,9 @@ paths: parameters: - name: custom_object_instance_id in: path - description: The id or external_id of the custom object instance + description: The Intercom defined id of the custom object instance. An external + id here is not looked up; to find an instance by its external id, call + `GET /custom_object_instances/{custom_object_type_identifier}?external_id=`. required: true schema: type: string @@ -17930,7 +17997,10 @@ paths: tags: - Custom Object Instances operationId: getCustomObjectInstancesById - description: Fetch a Custom Object Instance by id. + description: | + Fetch a Custom Object Instance by id. + + Requires the `read_conversations`, `read_users_companies`, `read_write_custom_object_instances` or `read_write_users` OAuth scope. responses: '200': description: "successful. If the custom object type exists but no instance matches, the response is still `200` with `found: false`." @@ -17984,9 +18054,11 @@ paths: "$ref": "#/components/schemas/intercom_version" tags: - Custom Object Instances - operationId: deleteCustomObjectInstancesByExternalId - description: Delete a single Custom Object instance using the Intercom defined - id. + operationId: deleteCustomObjectInstancesById + description: | + Delete a single Custom Object instance using the Intercom defined id. + + Requires the `read_write_custom_object_instances` OAuth scope. responses: '200': description: successful @@ -18003,7 +18075,26 @@ paths: '401': $ref: "#/components/responses/Unauthorized" '404': - $ref: "#/components/responses/ObjectNotFound" + description: Custom object type or instance not found + content: + application/json: + examples: + Instance not found: + value: + type: error.list + request_id: 4b6d8e01-7f29-4c53-a1b8-9d3e5c270f84 + errors: + - code: not_found + message: Custom object instance not found + Type not found: + value: + type: error.list + request_id: 6e9a3c47-1b58-4d02-83f7-c5214a9e6b30 + errors: + - code: not_found + message: Custom object type `undefined` not found + schema: + "$ref": "#/components/schemas/error" "/data_attributes": get: summary: List all data attributes @@ -33958,27 +34049,42 @@ components: external_id: type: string description: A unique identifier for the Custom Object instance in the external - system it originated from. + system it originated from. The value `reference_not_found` is reserved + and is rejected with a `400`. Omitting this field creates a new instance + on every request instead of updating an existing one. external_created_at: type: integer format: date-time nullable: true description: The time when the Custom Object instance was created in the - external system it originated from. + external system it originated from. A value that cannot be read as a time + is stored as `null` rather than rejected. example: 1571672154 external_updated_at: type: integer format: date-time nullable: true description: The time when the Custom Object instance was last updated in - the external system it originated from. + the external system it originated from. A value that cannot be read as + a time is stored as `null` rather than rejected. example: 1571672154 custom_attributes: type: object nullable: true - description: The custom attributes which are set for the Custom Object instance. + description: |- + The custom attributes which are set for the Custom Object instance. + + Each value must match the type of the attribute it is set on: a string, integer, number or boolean, the label of one of a list attribute's options, or `null` to clear the attribute. A reference attribute takes the id of the record it points at, as a string. additionalProperties: - type: string + anyOf: + - type: string + nullable: true + - type: integer + - type: number + - type: boolean + example: + order_number: ORDER-12345 + total_amount: 99.99 create_or_update_tag_request: description: You can create or update an existing tag. type: object From b5fb422e8a0228592f8c5e1f9eeded4cb95e4a97 Mon Sep 17 00:00:00 2001 From: Mark Dennis Date: Thu, 22 Oct 2026 10:05:37 +0100 Subject: [PATCH 2/4] Use anyOf for the list custom object instances response A list body also matches the single-instance schema, which requires no properties, so oneOf would reject an ordinary list response. Co-Authored-By: Claude Opus 5.5 (1M context) --- descriptions/2.17/api.intercom.io.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/descriptions/2.17/api.intercom.io.yaml b/descriptions/2.17/api.intercom.io.yaml index e3a0d388..81d2e69d 100644 --- a/descriptions/2.17/api.intercom.io.yaml +++ b/descriptions/2.17/api.intercom.io.yaml @@ -17883,7 +17883,7 @@ paths: created_at: 1734537100 updated_at: 1734537100 schema: - oneOf: + anyOf: - "$ref": "#/components/schemas/custom_object_instances_paginated_list" - "$ref": "#/components/schemas/custom_object_instance" - "$ref": "#/components/schemas/custom_object_instance_not_found" From b8a3739aa60c8d990d0a982befca6cf98ca3053f Mon Sep 17 00:00:00 2001 From: Mark Dennis Date: Thu, 22 Oct 2026 17:34:27 +0100 Subject: [PATCH 3/4] Document array, datetime and unmatched list values for custom object attributes Reference attributes take an array of ids, so the create request's custom_attributes union now allows an array of strings. The description says datetime attributes take a Unix timestamp or date string, list attributes take an option label or id and clear on a value that matches no option, and an unmatched reference id is skipped. Co-Authored-By: Claude Opus 5.5 (1M context) --- descriptions/2.17/api.intercom.io.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/descriptions/2.17/api.intercom.io.yaml b/descriptions/2.17/api.intercom.io.yaml index 81d2e69d..1f343e09 100644 --- a/descriptions/2.17/api.intercom.io.yaml +++ b/descriptions/2.17/api.intercom.io.yaml @@ -34074,7 +34074,7 @@ components: description: |- The custom attributes which are set for the Custom Object instance. - Each value must match the type of the attribute it is set on: a string, integer, number or boolean, the label of one of a list attribute's options, or `null` to clear the attribute. A reference attribute takes the id of the record it points at, as a string. + Each value must match the type of the attribute it is set on: a string, integer, number or boolean, a Unix timestamp or date string for a datetime attribute, or `null` to clear the attribute. A list attribute takes the label or id of one of its options; a value that matches no option clears the attribute rather than being rejected. A reference attribute takes the Intercom id of the record it points at, or an array of ids for a reference to several records; an id that matches no record is skipped. additionalProperties: anyOf: - type: string @@ -34082,6 +34082,9 @@ components: - type: integer - type: number - type: boolean + - type: array + items: + type: string example: order_number: ORDER-12345 total_amount: 99.99 From 7608d72c588b4ebc6adddc9d4d3140db9e45f506 Mon Sep 17 00:00:00 2001 From: Mark Dennis Date: Fri, 23 Oct 2026 09:55:02 +0100 Subject: [PATCH 4/4] Port the Custom Object Instances changes to Preview Applies the same 2.17 changes to the Preview spec, merged operation by operation so Preview-only content stays, such as the `{id}` path parameter name. The next version is cut from Preview, and the Preview SDKs are generated from it. Co-Authored-By: Claude Opus 5.5 (1M context) --- descriptions/0/api.intercom.io.yaml | 145 ++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 18 deletions(-) diff --git a/descriptions/0/api.intercom.io.yaml b/descriptions/0/api.intercom.io.yaml index 605b1b06..2c3c62c5 100644 --- a/descriptions/0/api.intercom.io.yaml +++ b/descriptions/0/api.intercom.io.yaml @@ -18263,7 +18263,10 @@ paths: tags: - Custom Object Instances operationId: createCustomObjectInstances - description: Create or update a custom object instance + description: | + Create or update a custom object instance + + Requires the `read_write_custom_object_instances` OAuth scope. responses: '200': description: successful @@ -18284,6 +18287,27 @@ paths: updated_at: 1734537745 schema: "$ref": "#/components/schemas/custom_object_instance" + '400': + description: Bad Request + content: + application/json: + examples: + Reserved external_id: + value: + type: error.list + request_id: 3f1a6d2b-9c47-4e58-8a01-6b7d2e4f9c13 + errors: + - code: bad_request + message: Invalid external_id value + Value does not match the attribute type: + value: + type: error.list + request_id: 5c8e4b17-2a6d-49f3-b0e5-71c9a3d82f46 + errors: + - code: parameter_invalid + message: Invalid value 'yesterday' for attribute 'ordered_at' + schema: + "$ref": "#/components/schemas/error" '401': $ref: "#/components/responses/Unauthorized" '404': @@ -18345,13 +18369,15 @@ paths: tags: - Custom Object Instances operationId: listCustomObjectInstances - description: |- + description: | List instances of a custom object type. Three modes are supported: - **No filter** — returns all instances for the type. - **`references_contact_id`** — returns instances associated with the given contact. - **`references_conversation_id`** — returns instances associated with the given conversation. - When **`external_id`** is provided, returns a single matching instance (not a list). + When **`external_id`** is provided, returns a single matching instance (not a list). If no instance matches, the response is still `200`, with the same body the single-instance endpoint returns for a miss. + + Requires the `read_conversations`, `read_users_companies`, `read_write_custom_object_instances` or `read_write_users` OAuth scope. responses: '200': description: successful @@ -18389,7 +18415,24 @@ paths: created_at: 1734537100 updated_at: 1734537100 schema: - "$ref": "#/components/schemas/custom_object_instances_paginated_list" + anyOf: + - "$ref": "#/components/schemas/custom_object_instances_paginated_list" + - "$ref": "#/components/schemas/custom_object_instance" + - "$ref": "#/components/schemas/custom_object_instance_not_found" + '400': + description: Bad Request + content: + application/json: + examples: + Both reference filters given: + value: + type: error.list + request_id: 7d2b9e54-6c13-4a87-95f0-2e8b4c71d9a3 + errors: + - code: bad_request + message: Cannot provide both references_contact_id and references_conversation_id + schema: + "$ref": "#/components/schemas/error" '401': $ref: "#/components/responses/Unauthorized" '404': @@ -18417,8 +18460,11 @@ paths: "$ref": "#/components/schemas/intercom_version" tags: - Custom Object Instances - operationId: deleteCustomObjectInstancesById - description: Delete a single Custom Object instance by external_id. + operationId: deleteCustomObjectInstancesByExternalId + description: | + Delete a single Custom Object instance by external_id. + + Requires the `read_write_custom_object_instances` OAuth scope. responses: '200': description: successful @@ -18435,7 +18481,26 @@ paths: '401': $ref: "#/components/responses/Unauthorized" '404': - $ref: "#/components/responses/ObjectNotFound" + description: Custom object type or instance not found + content: + application/json: + examples: + Instance not found: + value: + type: error.list + request_id: 9e4c1a86-3d75-42b9-8c60-5f1a7b93e2d4 + errors: + - code: not_found + message: Custom object instance not found + Type not found: + value: + type: error.list + request_id: 2a7f5c93-8b14-46e0-97d2-3c6e1b85a07f + errors: + - code: not_found + message: Custom object type `undefined` not found + schema: + "$ref": "#/components/schemas/error" "/custom_object_instances/{custom_object_type_identifier}/{id}": parameters: - name: custom_object_type_identifier @@ -18451,7 +18516,9 @@ paths: parameters: - name: id in: path - description: The id or external_id of the custom object instance + description: The Intercom defined id of the custom object instance. An external + id here is not looked up; to find an instance by its external id, call + `GET /custom_object_instances/{custom_object_type_identifier}?external_id=`. required: true schema: type: string @@ -18462,7 +18529,10 @@ paths: tags: - Custom Object Instances operationId: getCustomObjectInstancesById - description: Fetch a Custom Object Instance by id. + description: | + Fetch a Custom Object Instance by id. + + Requires the `read_conversations`, `read_users_companies`, `read_write_custom_object_instances` or `read_write_users` OAuth scope. responses: '200': description: "successful. If the custom object type exists but no instance matches, the response is still `200` with `found: false`." @@ -18516,9 +18586,11 @@ paths: "$ref": "#/components/schemas/intercom_version" tags: - Custom Object Instances - operationId: deleteCustomObjectInstancesByExternalId - description: Delete a single Custom Object instance using the Intercom defined - id. + operationId: deleteCustomObjectInstancesById + description: | + Delete a single Custom Object instance using the Intercom defined id. + + Requires the `read_write_custom_object_instances` OAuth scope. responses: '200': description: successful @@ -18535,7 +18607,26 @@ paths: '401': $ref: "#/components/responses/Unauthorized" '404': - $ref: "#/components/responses/ObjectNotFound" + description: Custom object type or instance not found + content: + application/json: + examples: + Instance not found: + value: + type: error.list + request_id: 4b6d8e01-7f29-4c53-a1b8-9d3e5c270f84 + errors: + - code: not_found + message: Custom object instance not found + Type not found: + value: + type: error.list + request_id: 6e9a3c47-1b58-4d02-83f7-c5214a9e6b30 + errors: + - code: not_found + message: Custom object type `undefined` not found + schema: + "$ref": "#/components/schemas/error" "/data_attributes": get: summary: List all data attributes @@ -38375,27 +38466,45 @@ components: external_id: type: string description: A unique identifier for the Custom Object instance in the external - system it originated from. + system it originated from. The value `reference_not_found` is reserved + and is rejected with a `400`. Omitting this field creates a new instance + on every request instead of updating an existing one. external_created_at: type: integer format: date-time nullable: true description: The time when the Custom Object instance was created in the - external system it originated from. + external system it originated from. A value that cannot be read as a time + is stored as `null` rather than rejected. example: 1571672154 external_updated_at: type: integer format: date-time nullable: true description: The time when the Custom Object instance was last updated in - the external system it originated from. + the external system it originated from. A value that cannot be read as + a time is stored as `null` rather than rejected. example: 1571672154 custom_attributes: type: object nullable: true - description: The custom attributes which are set for the Custom Object instance. + description: |- + The custom attributes which are set for the Custom Object instance. + + Each value must match the type of the attribute it is set on: a string, integer, number or boolean, a Unix timestamp or date string for a datetime attribute, or `null` to clear the attribute. A list attribute takes the label or id of one of its options; a value that matches no option clears the attribute rather than being rejected. A reference attribute takes the Intercom id of the record it points at, or an array of ids for a reference to several records; an id that matches no record is skipped. additionalProperties: - type: string + anyOf: + - type: string + nullable: true + - type: integer + - type: number + - type: boolean + - type: array + items: + type: string + example: + order_number: ORDER-12345 + total_amount: 99.99 create_or_update_tag_request: description: You can create or update an existing tag. type: object