Skip to content

Preview: conversation part type filtering parameters - #653

Open
robertlangner-fin wants to merge 7 commits into
mainfrom
robertlangner/conversation-part-type-filtering
Open

Preview: conversation part type filtering parameters#653
robertlangner-fin wants to merge 7 commits into
mainfrom
robertlangner/conversation-part-type-filtering

Conversation

@robertlangner-fin

@robertlangner-fin robertlangner-fin commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Why?

Conversation part events (assignments, snoozes, workflow steps, etc.) get mixed in with the real messages on a conversation, and the parts limit means those events can crowd out the messages a caller actually wants. There was previously no way to ask for just the part types you care about.

How?

Adds two optional, mutually exclusive query parameters to the Preview spec for retrieving a single conversation: one to keep only the part types you name, the other to drop them. Both accept up to 50 comma-separated values and are applied before the parts limit, so you get the newest matching parts.

Available on Preview only; any other version returns a 422.

Generated with Claude Code

robertlangner-fin and others added 5 commits September 2, 2026 11:13
Adds include_part_types and exclude_part_types query parameters to
GET /conversations/{id} in the Preview spec, mirroring
intercom/intercom#568321.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The filter is gated on a Preview-only version change, not the 2.6 part
type change, so it is not available on released versions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Matches the comma-separated query params on /content/search, so generated
clients get a list rather than one opaque string. maxItems encodes the
50-value cap the endpoint already enforces.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The parameters accepted any string with no indication of what the 115 valid
names are, and a wrong value is a hard 422. State the rule instead of an enum:
the values are the names this version returns in part_type, which stays true as
part types are added, since name_to_type_ids derives them from subclass_types
rather than a maintained list.

Call out the two names that surprise callers. "comment" is the fallback the
read path uses for any id it does not recognise, so filtering on it matches a
broader set than its name suggests. Type 13 serializes as note_and_unsnooze
here but note_and_reopen below 2.6, so a pinned integration moving to Preview
hits a 422 on the name it has been receiving.

Also point conversation_part.part_type at the filters, since that field is
where a caller discovers the vocabulary.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The parameter descriptions said an invalid filter returns a 422, but the
operation only declared 200, 404, 401 and 403, so the generated contract had
no shape for the error a caller is most likely to hit.

Adds a 422 with the four messages part_type_filter actually raises, all
carrying the parameter_invalid code that raise_invalid_param emits, and the
shared error schema.

Also carries over the conversation parts limit note that only landed in
developer-docs, so the source of truth is not missing a sentence its
downstream copy has.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@anubhav-intercom

Copy link
Copy Markdown
Contributor

Drop the version number from both parameter descriptions — say Preview-only instead.

AddConversationPartTypeFiltering lands with define_is_ready_for_release false, so the 2.17 cut won't pick it up and "until the 2.17 release" goes stale the day it ships. Suggest: "Available on the Preview version; a 422 is returned on any other version." A version can be named later, once the change is actually marked ready for release.

~ Automated via Claude

AddConversationPartTypeFiltering ships with define_is_ready_for_release
false, so the 2.17 cut will not pick it up and naming that version would
go stale on release day. A version can be named once the change is
marked ready.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Follows the monolith change in intercom/intercom#568321: unrecognised
conversation part types now serialize as "unknown" on Preview rather than
"comment", so "comment" is no longer an open-ended bucket.

Both filter parameter descriptions now state the unknown rule instead, the
part_type field documents unknown vs the earlier comment behaviour, and the
422 block gains an example for filtering on "unknown", whose error message
reads confusingly without one.

Companion to intercom/intercom#568321 and intercom/developer-docs#1132

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@anubhav-intercom anubhav-intercom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve — four minor spec-accuracy comments inline, none blocking.

Merge order: land and deploy intercom#568321 first; the parameters documented here do not exist on monolith master yet.
The YAML hunk is byte-identical to developer-docs#1132, so these four fixes should land in both PRs together.

~ Automated via Claude

example: comment,note
schema:
type: array
maxItems: 50

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add minItems: 1 to both parameter schemas.
?include_part_types= returns 422 include_part_types must name at least one conversation part type (intercom#568321 controller diff line 70); the schema currently says an empty array is valid. Same at line 12362.

content:
application/json:
examples:
Unknown part type name:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add 422 examples for the empty-value and non-string cases.
The controller raises six parameter_invalid messages; this block lists four. Missing: must name at least one conversation part type and must be a comma-separated list of conversation part types (intercom#568321 diff lines 67, 70), both asserted by its specs.

- name: include_part_types
in: query
required: false
description: A comma-separated list of conversation part types to keep; only parts of these types are returned. Values are the names this version returns in a part's `part_type` field, such as `assignment`, `note` or `snoozed`; an unrecognised name returns a 422 rather than being silently ignored, so a typo fails loudly instead of filtering nothing. Two names need care — a part type this version does not recognise is returned as `unknown`, and `unknown` is not itself an accepted filter value, so those parts are removed by naming the types you do want rather than by filtering them out directly; and the part type that versions below 2.6 return as `note_and_reopen` is named `note_and_unsnooze` here. Up to 50 values are accepted, and `include_part_types` cannot be combined with `exclude_part_types`; both cases return a 422. The filter is applied before the conversation parts limit, so the newest matching parts are returned. Available on the Preview version; a 422 is returned on any other version.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

State that repeated include_part_types parameters are not supported; only one comma-separated value is read.
?include_part_types=comment&include_part_types=note parses to "note" (Rack keeps the last value), so the request succeeds and silently drops comment. Neighbouring /content/search array params say they accept "repeated params"; these do not. Same for exclude_part_types at line 12358.


{% admonition type="warning" name="Hard limit of 500 parts" %}
The maximum number of conversation parts that can be returned via the API is 500. If you have more than that we will return the 500 most recent conversation parts.
The maximum number of conversation parts that can be returned via the API is 500. If you have more than that we will return the 500 most recent conversation parts. `include_part_types` and `exclude_part_types` are applied before this limit, so filtering returns the 500 most recent matching parts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Say that conversation_parts.total_count counts parts after filtering.
total_count is model_parts.count on the filtered relation (versioned_conversation_part_list_response.rb:58; intercom#568321 spec line 470 asserts 1 under a filter). A caller using total_count > 500 to detect truncation, as this admonition invites, gets a post-filter number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants