This audit records the public API decisions made before the v1.0.0 compatibility
promise. It was completed on 2026-07-29 against release v0.2.0.
The compatibility surface consists of every exported identifier in:
github.com/uffejaeger/intercom-gogithub.com/uffejaeger/intercom-go/intercomtest
Repository tools, examples, and tests are excluded. Packages under internal/
are also excluded except for the generated model package described below. Go's
gorelease tool reports that the current module is a valid semantic version
candidate for v1.0.0. A manual review found no high-impact public API redesign
that should delay the v1 compatibility promise.
The review does not claim that every runtime behavior is immutable or that every Intercom workflow has a high-level helper. Behavioral changes, upstream API changes, and operational verification remain governed by the release policy, tests, and live-canary criterion.
The root package intentionally exposes aliases for selected generated request and response models. This keeps generated code internal while avoiding a large, lossy hand-maintained model layer.
Those aliases and the exported shapes they expose are part of the public API. Specification regeneration may add compatible API, but removal, renaming, or type changes must not bypass compatibility review.
Go's API export data does not expand aliases into an internal package during a
normal public-module comparison. To avoid a blind spot, the automated gate also
compares the generated model package directly. This is deliberately
conservative: it can flag a changed generated type that is not currently
reachable through a root-package alias. Maintainers should confirm reachability
during review, but must preserve any shape that is publicly exposed.
RequestOptions and WithRequestOptions remain the extension point for
per-request headers, query values, and retry overrides. Carrying these options
through context.Context preserves the service method signatures while keeping
the options request-local.
The exported fields and validation behavior are part of the compatibility promise. Future request-scoped features should be added compatibly or introduced through a separate API when adding a field would itself be incompatible.
ContactIterator, ConversationIterator, and TicketIterator consistently use
the Next, typed-value accessor, and Err pattern. They provide a small
convenience layer over cursor pagination without hiding terminal errors.
The iterator names, method signatures, and ErrPaginationStalled error contract
are part of the compatibility promise. New resources should follow the same
pattern when an iterator adds material value.
ErrorResponse preserves HTTP status, Intercom error details, request ID,
response headers, and a bounded response body. IsStatus is the general
classifier, with helpers for common status classes.
The error types, wrapped-error classification through errors.As, and existing
predicate semantics are part of the compatibility promise. New predicates may
be added without changing the general classification contract.
Public request interfaces with unexported marker methods intentionally form a closed set of supported variants. This prevents callers from supplying values that the SDK cannot serialize correctly. New supported variants may be added compatibly; opening or otherwise redesigning these interfaces is not required for v1.
Client.NewRequest and Client.Do remain available for Intercom endpoints or
features that do not yet have a high-level wrapper. Their presence lets wrapper
coverage evolve without forcing consumers to wait for an SDK release.
make api-compatibility exports the public module API from the current working
tree and compares it with the pinned released baseline using Go's apidiff
tool. The command fails when an incompatible compile-time change is reported.
CI runs it in the quality job, and make pre-push runs it locally.
The generated OpenAPI client is under Go's internal/ boundary, so downstream
SDK consumers cannot import it. It is verified for reproducibility by make generate-check, rather than treated as a second public API surface.
The checker has a narrow source-compatibility allowance for the reviewed
Contact, Ticket, and Article boundary models: API 2.16 changed Intercom's wire
representation of Contact.owner_id from an integer to a string and Ticket
assignee IDs from strings to integers. The SDK preserves the historical public
field types and converts the wire values at the boundary, including contact
values returned by company and visitor operations. API 2.16 also replaces
Article's historical parent_id and parent_type with parent_ids; the SDK
retains the legacy fields and maps the first parent ID when possible. apidiff reports the
required alias-to-struct change and its dependent methods and iterators as
incompatible, so the checker permits only those exact entries. External
consumer compile and response-conversion regression tests cover the preserved
contracts. No other apidiff finding is suppressed.
The current baseline is v0.2.0. After publishing a release that expands the
public API, maintainers advance API_BASELINE in Makefile to that release so
later removals of newly added API are also detected. The apidiff version is
pinned because compatibility classification changes are themselves reviewable
tooling changes.
The gate is deliberately strict, but it is not a substitute for review:
- It detects compile-time API incompatibilities, not behavior changes.
- It does not prove that Intercom's live API still honors an endpoint contract.
- An intentional incompatible change must be documented and released under the semantic-versioning policy; disabling the check is not an acceptable shortcut.