From 8271f82606ef3a3655f0dbc8a9597d6e579fc866 Mon Sep 17 00:00:00 2001 From: alexpetrash-code Date: Fri, 5 Jun 2026 17:51:01 +0100 Subject: [PATCH 1/4] Add Articles draft lifecycle endpoints to Preview spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the three Articles draft endpoints (Preview): - GET /articles/{id}/draft — retrieve a staged draft - PUT /articles/{id}/draft — stage a draft - POST /articles/{id}/draft/publish — publish a staged draft Responses reuse the existing article schema; the PUT body reuses update_article_request. Adds a publish_article_draft_request schema for the publish endpoint. _sent by alexbot_ Co-Authored-By: Claude Opus 4.8 (1M context) --- descriptions/0/api.intercom.io.yaml | 309 ++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) diff --git a/descriptions/0/api.intercom.io.yaml b/descriptions/0/api.intercom.io.yaml index 3f4ebff..cb66dc9 100644 --- a/descriptions/0/api.intercom.io.yaml +++ b/descriptions/0/api.intercom.io.yaml @@ -1640,6 +1640,296 @@ paths: message: Access Token Invalid schema: "$ref": "#/components/schemas/error" + "/articles/{id}/draft": + get: + summary: Retrieve an article draft + parameters: + - name: Intercom-Version + in: header + schema: + "$ref": "#/components/schemas/intercom_version" + - name: id + in: path + required: true + description: The unique identifier for the article which is given by Intercom. + example: 123 + schema: + type: integer + tags: + - Articles + operationId: retrieveArticleDraft + description: | + Fetch the staged draft of a published article by making a GET request to + `https://api.intercom.io/articles//draft`. The response is the article + rendered with its draft content, leaving the live article untouched. + + A draft exists only when a published article has unpublished changes staged + on top of it. Returns `404` when the article has no staged draft. + responses: + '200': + description: Article draft found + content: + application/json: + examples: + Article draft found: + value: + id: '45' + type: article + workspace_id: this_is_an_id74_that_should_be_at_least_4 + parent_ids: [] + title: This is the draft title + description: '' + body:

Unpublished changes staged as a draft

+ body_markdown: "Unpublished changes staged as a draft\n" + author_id: 991267502 + state: published + created_at: 1734537292 + updated_at: 1734537292 + url: http://help-center.test/myapp-74/en/articles/45-this-is-the-article-title + ai_chatbot_availability: true + ai_copilot_availability: true + ai_sales_agent_availability: true + schema: + "$ref": "#/components/schemas/article" + '404': + description: Article has no draft + content: + application/json: + examples: + Article has no draft: + value: + type: error.list + request_id: 79abd27a-1bfb-42ec-a404-5728c76ba773 + errors: + - code: not_found + message: Resource Not Found + schema: + "$ref": "#/components/schemas/error" + '401': + description: Unauthorized + content: + application/json: + examples: + Unauthorized: + value: + type: error.list + request_id: 2eab07fb-5092-49a4-ba74-44094f31f264 + errors: + - code: unauthorized + message: Access Token Invalid + schema: + "$ref": "#/components/schemas/error" + put: + summary: Stage an article draft + parameters: + - name: Intercom-Version + in: header + schema: + "$ref": "#/components/schemas/intercom_version" + - name: id + in: path + required: true + description: The unique identifier for the article which is given by Intercom. + example: 123 + schema: + type: integer + tags: + - Articles + operationId: stageArticleDraft + description: | + Stage changes to a published article as a draft by making a PUT request to + `https://api.intercom.io/articles//draft`. The live article remains + unchanged until the draft is published. + + The article must already be published; staging a draft on an article that + has never been published returns `422`. + responses: + '200': + description: Draft staged + content: + application/json: + examples: + Draft staged: + value: + id: '48' + type: article + workspace_id: this_is_an_id80_that_should_be_at_least_4 + parent_ids: [] + title: Christmas is here! + description: '' + body:

New gifts in store for the jolly season

+ body_markdown: "New gifts in store for the jolly season\n" + author_id: 991267508 + state: published + created_at: 1734537297 + updated_at: 1734537298 + url: http://help-center.test/myapp-80/en/articles/48-christmas-is-here + ai_chatbot_availability: true + ai_copilot_availability: true + ai_sales_agent_availability: true + schema: + "$ref": "#/components/schemas/article" + '404': + description: Article Not Found + content: + application/json: + examples: + Article Not Found: + value: + type: error.list + request_id: f9adccb2-9fca-4b87-bbb7-65f2af5e1d78 + errors: + - code: not_found + message: Resource Not Found + schema: + "$ref": "#/components/schemas/error" + '422': + description: Article must be published before a draft can be staged + content: + application/json: + examples: + Article not published: + value: + type: error.list + request_id: 6f3c2b1a-2d4e-4f6a-9b8c-1a2b3c4d5e6f + errors: + - code: parameter_invalid + message: Article must be published before a draft can be staged + schema: + "$ref": "#/components/schemas/error" + '401': + description: Unauthorized + content: + application/json: + examples: + Unauthorized: + value: + type: error.list + request_id: d1ea223d-bb62-42e3-8bcf-30fdcf7dbd99 + errors: + - code: unauthorized + message: Access Token Invalid + schema: + "$ref": "#/components/schemas/error" + requestBody: + content: + application/json: + schema: + "$ref": "#/components/schemas/update_article_request" + examples: + Draft staged: + summary: Stage a draft + value: + title: Christmas is here! + body: "

New gifts in store for the jolly season

" + "/articles/{id}/draft/publish": + post: + summary: Publish an article draft + parameters: + - name: Intercom-Version + in: header + schema: + "$ref": "#/components/schemas/intercom_version" + - name: id + in: path + required: true + description: The unique identifier for the article which is given by Intercom. + example: 123 + schema: + type: integer + tags: + - Articles + operationId: publishArticleDraft + description: | + Publish a staged draft by making a POST request to + `https://api.intercom.io/articles//draft/publish`, promoting the draft + content to live. + + On a single-language workspace no body is required. On a multilingual + workspace you must list which locales to publish via the `locales` array; + omitting it returns `422`. Returns `422` when there is no staged draft to + publish, or when a requested locale has no pending changes. + responses: + '200': + description: Draft published + content: + application/json: + examples: + Draft published: + value: + id: '48' + type: article + workspace_id: this_is_an_id80_that_should_be_at_least_4 + parent_ids: [] + title: Christmas is here! + description: '' + body:

New gifts in store for the jolly season

+ body_markdown: "New gifts in store for the jolly season\n" + author_id: 991267508 + state: published + created_at: 1734537297 + updated_at: 1734537299 + url: http://help-center.test/myapp-80/en/articles/48-christmas-is-here + ai_chatbot_availability: true + ai_copilot_availability: true + ai_sales_agent_availability: true + schema: + "$ref": "#/components/schemas/article" + '404': + description: Article Not Found + content: + application/json: + examples: + Article Not Found: + value: + type: error.list + request_id: f9adccb2-9fca-4b87-bbb7-65f2af5e1d78 + errors: + - code: not_found + message: Resource Not Found + schema: + "$ref": "#/components/schemas/error" + '422': + description: No draft to publish, or locales not specified on a multilingual workspace + content: + application/json: + examples: + No draft to publish: + value: + type: error.list + request_id: 8a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d + errors: + - code: parameter_invalid + message: Article has no draft to publish + schema: + "$ref": "#/components/schemas/error" + '401': + description: Unauthorized + content: + application/json: + examples: + Unauthorized: + value: + type: error.list + request_id: c6e86ce8-9402-4196-89c5-f1b2912b4bac + errors: + - code: unauthorized + message: Access Token Invalid + schema: + "$ref": "#/components/schemas/error" + requestBody: + required: false + content: + application/json: + schema: + "$ref": "#/components/schemas/publish_article_draft_request" + examples: + Publish specific locales: + summary: Publish specific locales on a multilingual workspace + value: + locales: + - en + - fr "/articles/search": get: summary: Search for articles @@ -33575,6 +33865,25 @@ components: type: role comparison: eq value: user + publish_article_draft_request: + description: | + Optional body for publishing a staged article draft. On a single-language + workspace the body can be omitted. On a multilingual workspace, `locales` + is required and lists which locales' drafts to publish. + type: object + title: Publish Article Draft Request Payload + nullable: true + properties: + locales: + type: array + description: | + The locales whose staged drafts should be published. Required on + multilingual workspaces; each locale must have a pending draft. + items: + type: string + example: + - en + - fr update_article_request: description: You can Update an Article type: object From bf5b43fd10fdcdf624d5afd73c95460ea288281c Mon Sep 17 00:00:00 2001 From: alexpetrash-code Date: Mon, 8 Jun 2026 09:22:11 +0100 Subject: [PATCH 2/4] Note required OAuth scope in draft endpoint descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the required OAuth scope to each draft operation description, matching the convention used by other documented endpoints: - retrieve draft → read_articles_scope - stage / publish draft → read_write_articles_scope _sent by alexbot_ Co-Authored-By: Claude Opus 4.8 (1M context) --- descriptions/0/api.intercom.io.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/descriptions/0/api.intercom.io.yaml b/descriptions/0/api.intercom.io.yaml index cb66dc9..a3b34e2 100644 --- a/descriptions/0/api.intercom.io.yaml +++ b/descriptions/0/api.intercom.io.yaml @@ -1665,6 +1665,8 @@ paths: A draft exists only when a published article has unpublished changes staged on top of it. Returns `404` when the article has no staged draft. + + Requires the `read_articles_scope` OAuth scope. responses: '200': description: Article draft found @@ -1743,6 +1745,8 @@ paths: The article must already be published; staging a draft on an article that has never been published returns `422`. + + Requires the `read_write_articles_scope` OAuth scope. responses: '200': description: Draft staged @@ -1849,6 +1853,8 @@ paths: workspace you must list which locales to publish via the `locales` array; omitting it returns `422`. Returns `422` when there is no staged draft to publish, or when a requested locale has no pending changes. + + Requires the `read_write_articles_scope` OAuth scope. responses: '200': description: Draft published From 6ddf6d311bee6ab14519dd91d53f84d04b705a2f Mon Sep 17 00:00:00 2001 From: alexpetrash-code Date: Mon, 8 Jun 2026 14:22:30 +0100 Subject: [PATCH 3/4] Document draft detection fields and correct draft endpoint examples - Add has_unpublished_changes + draft_updated_at to article_list_item and article_content schemas (Preview-only); show them in the retrieve/stage/publish 200 examples - Fix stage/publish 422 examples to the real {message, status} shape and add the multilingual-locales and locale-without-pending-changes examples - Clarify the GET /draft 404 (empty body when no draft), note that only versioned text content is staged, and state the Intercom-Version: Preview requirement Co-Authored-By: Claude Opus 4.8 (1M context) --- descriptions/0/api.intercom.io.yaml | 74 +++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/descriptions/0/api.intercom.io.yaml b/descriptions/0/api.intercom.io.yaml index a3b34e2..18391bb 100644 --- a/descriptions/0/api.intercom.io.yaml +++ b/descriptions/0/api.intercom.io.yaml @@ -1666,7 +1666,7 @@ paths: A draft exists only when a published article has unpublished changes staged on top of it. Returns `404` when the article has no staged draft. - Requires the `read_articles_scope` OAuth scope. + Requires the `read_articles_scope` OAuth scope. Set `Intercom-Version: Preview`. responses: '200': description: Article draft found @@ -1687,6 +1687,8 @@ paths: state: published created_at: 1734537292 updated_at: 1734537292 + has_unpublished_changes: true + draft_updated_at: 1734537292 url: http://help-center.test/myapp-74/en/articles/45-this-is-the-article-title ai_chatbot_availability: true ai_copilot_availability: true @@ -1694,11 +1696,14 @@ paths: schema: "$ref": "#/components/schemas/article" '404': - description: Article has no draft + description: | + The article does not exist, or it exists but has no staged draft. When the + article exists but has no draft the response body is empty; the example + below shows the article-not-found case. content: application/json: examples: - Article has no draft: + Article not found: value: type: error.list request_id: 79abd27a-1bfb-42ec-a404-5728c76ba773 @@ -1746,7 +1751,11 @@ paths: The article must already be published; staging a draft on an article that has never been published returns `422`. - Requires the `read_write_articles_scope` OAuth scope. + Only versioned text content (such as `title` and `body`) is staged. + Non-versioned fields like AI availability are ignored, leaving the live + values untouched. + + Requires the `read_write_articles_scope` OAuth scope. Set `Intercom-Version: Preview`. responses: '200': description: Draft staged @@ -1767,6 +1776,8 @@ paths: state: published created_at: 1734537297 updated_at: 1734537298 + has_unpublished_changes: true + draft_updated_at: 1734537298 url: http://help-center.test/myapp-80/en/articles/48-christmas-is-here ai_chatbot_availability: true ai_copilot_availability: true @@ -1797,8 +1808,8 @@ paths: type: error.list request_id: 6f3c2b1a-2d4e-4f6a-9b8c-1a2b3c4d5e6f errors: - - code: parameter_invalid - message: Article must be published before a draft can be staged + - message: Article must be published before a draft can be staged + status: 422 schema: "$ref": "#/components/schemas/error" '401': @@ -1854,7 +1865,7 @@ paths: omitting it returns `422`. Returns `422` when there is no staged draft to publish, or when a requested locale has no pending changes. - Requires the `read_write_articles_scope` OAuth scope. + Requires the `read_write_articles_scope` OAuth scope. Set `Intercom-Version: Preview`. responses: '200': description: Draft published @@ -1875,6 +1886,8 @@ paths: state: published created_at: 1734537297 updated_at: 1734537299 + has_unpublished_changes: false + draft_updated_at: null url: http://help-center.test/myapp-80/en/articles/48-christmas-is-here ai_chatbot_availability: true ai_copilot_availability: true @@ -1896,7 +1909,7 @@ paths: schema: "$ref": "#/components/schemas/error" '422': - description: No draft to publish, or locales not specified on a multilingual workspace + description: No draft to publish, locales not specified on a multilingual workspace, or a requested locale has no pending changes content: application/json: examples: @@ -1905,8 +1918,22 @@ paths: type: error.list request_id: 8a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d errors: + - message: Article has no draft to publish + status: 422 + Locales required on a multilingual workspace: + value: + type: error.list + request_id: 9b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e + errors: + - code: parameter_not_found + message: locales must be specified to publish a draft on a multilingual workspace + Locale has no pending changes: + value: + type: error.list + request_id: 0c3d4e5f-6a7b-8c9d-0e1f-2a3b4c5d6e7f + errors: - code: parameter_invalid - message: Article has no draft to publish + message: 'Cannot publish a draft for locale(s) without pending changes: fr' schema: "$ref": "#/components/schemas/error" '401': @@ -23052,6 +23079,20 @@ components: format: date-time description: The time when the article was last updated (seconds). example: 1663597260 + has_unpublished_changes: + type: boolean + description: Whether this locale's published content has unpublished + changes staged as a draft on top of its live content. Only returned on + the `Preview` API version. + example: false + draft_updated_at: + type: integer + format: date-time + nullable: true + description: The time, in seconds, when this locale's staged draft was + last edited, or `null` when there is no staged draft. Only returned on + the `Preview` API version. + example: 1663597260 url: type: string description: The URL of the article. @@ -23274,6 +23315,21 @@ components: articles, this will be the timestamp of last update of the default language's content in seconds. example: 1672928610 + has_unpublished_changes: + type: boolean + description: Whether the published article has unpublished changes staged + as a draft on top of its live content. Only returned on the `Preview` + API version. For multilingual articles this reflects the default + language's content; a pure draft (never published) reports `false`. + example: false + draft_updated_at: + type: integer + format: date-time + nullable: true + description: The time, in seconds, when the staged draft was last edited, + or `null` when there is no staged draft. Only returned on the `Preview` + API version. + example: 1672928610 url: type: string nullable: true From 64e30352423bcbb227661d5b2bd6ad00d53aecfa Mon Sep 17 00:00:00 2001 From: alexpetrash-code Date: Mon, 8 Jun 2026 15:07:16 +0100 Subject: [PATCH 4/4] Address review: shared error $refs and schema-conformant 422 examples - Use Pattern B shared responses ($ref) for 401 (Unauthorized) and 404 (ObjectNotFound) per openapi-conventions.md - Resolve the GET /draft 404 empty-body/schema contradiction by referencing ObjectNotFound (the no-draft trigger is already in the operation description) - Revert the stage/publish 422 examples to the schema-conformant {code, message} shape (the error schema requires code; status was non-conformant) Co-Authored-By: Claude Opus 4.8 (1M context) --- descriptions/0/api.intercom.io.yaml | 95 +++-------------------------- 1 file changed, 10 insertions(+), 85 deletions(-) diff --git a/descriptions/0/api.intercom.io.yaml b/descriptions/0/api.intercom.io.yaml index 18391bb..7f9c031 100644 --- a/descriptions/0/api.intercom.io.yaml +++ b/descriptions/0/api.intercom.io.yaml @@ -1696,36 +1696,9 @@ paths: schema: "$ref": "#/components/schemas/article" '404': - description: | - The article does not exist, or it exists but has no staged draft. When the - article exists but has no draft the response body is empty; the example - below shows the article-not-found case. - content: - application/json: - examples: - Article not found: - value: - type: error.list - request_id: 79abd27a-1bfb-42ec-a404-5728c76ba773 - errors: - - code: not_found - message: Resource Not Found - schema: - "$ref": "#/components/schemas/error" + "$ref": "#/components/responses/ObjectNotFound" '401': - description: Unauthorized - content: - application/json: - examples: - Unauthorized: - value: - type: error.list - request_id: 2eab07fb-5092-49a4-ba74-44094f31f264 - errors: - - code: unauthorized - message: Access Token Invalid - schema: - "$ref": "#/components/schemas/error" + "$ref": "#/components/responses/Unauthorized" put: summary: Stage an article draft parameters: @@ -1785,19 +1758,7 @@ paths: schema: "$ref": "#/components/schemas/article" '404': - description: Article Not Found - content: - application/json: - examples: - Article Not Found: - value: - type: error.list - request_id: f9adccb2-9fca-4b87-bbb7-65f2af5e1d78 - errors: - - code: not_found - message: Resource Not Found - schema: - "$ref": "#/components/schemas/error" + "$ref": "#/components/responses/ObjectNotFound" '422': description: Article must be published before a draft can be staged content: @@ -1808,24 +1769,12 @@ paths: type: error.list request_id: 6f3c2b1a-2d4e-4f6a-9b8c-1a2b3c4d5e6f errors: - - message: Article must be published before a draft can be staged - status: 422 + - code: parameter_invalid + message: Article must be published before a draft can be staged schema: "$ref": "#/components/schemas/error" '401': - description: Unauthorized - content: - application/json: - examples: - Unauthorized: - value: - type: error.list - request_id: d1ea223d-bb62-42e3-8bcf-30fdcf7dbd99 - errors: - - code: unauthorized - message: Access Token Invalid - schema: - "$ref": "#/components/schemas/error" + "$ref": "#/components/responses/Unauthorized" requestBody: content: application/json: @@ -1895,19 +1844,7 @@ paths: schema: "$ref": "#/components/schemas/article" '404': - description: Article Not Found - content: - application/json: - examples: - Article Not Found: - value: - type: error.list - request_id: f9adccb2-9fca-4b87-bbb7-65f2af5e1d78 - errors: - - code: not_found - message: Resource Not Found - schema: - "$ref": "#/components/schemas/error" + "$ref": "#/components/responses/ObjectNotFound" '422': description: No draft to publish, locales not specified on a multilingual workspace, or a requested locale has no pending changes content: @@ -1918,8 +1855,8 @@ paths: type: error.list request_id: 8a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d errors: - - message: Article has no draft to publish - status: 422 + - code: parameter_invalid + message: Article has no draft to publish Locales required on a multilingual workspace: value: type: error.list @@ -1937,19 +1874,7 @@ paths: schema: "$ref": "#/components/schemas/error" '401': - description: Unauthorized - content: - application/json: - examples: - Unauthorized: - value: - type: error.list - request_id: c6e86ce8-9402-4196-89c5-f1b2912b4bac - errors: - - code: unauthorized - message: Access Token Invalid - schema: - "$ref": "#/components/schemas/error" + "$ref": "#/components/responses/Unauthorized" requestBody: required: false content: