Low-level Intercom transport: regional base URL, auth and
Intercom-Version headers, HttpError for non-2xx responses, and the
cursor (starting_after) pagination helpers the endpoint namespaces
share.
Per-call credentials. Every API-calling function in this package
takes an optional trailing opts Map, resolved by resolve: opts
first, then context variables, then defaults. Nothing from opts is
written to ctx, so one run can act for many workspaces and parallel
flows don't share credentials. A token from opts is masked in call
records. A token present but blank or null is an error, never a
fallback to intercom.token.
token: the access token for this callregion:us,euoraufor this callversion: theIntercom-Versionfor this calladmin-id: the admin to act as. It's required for acting calls that pass atoken, sinceintercom.admin.idbelongs to the workspace ofintercom.token.
Context Vars
intercom.tokenintercom.admin.idintercom.regionintercom.version
Functions
admin-id
fn (): Str
fn (opts: Map): Str
The admin to act as (see optional-admin-id), or an Err with a hint when there is none: look it up with ::intercom::admins/me().
intercom.admin.id
api-version
fn (): Str
The Intercom-Version to send: intercom.version when set, otherwise the pinned ::intercom/API_VERSION.
intercom.version
base-url
fn (): Str
fn (region: Str?): Str
The regional API host. The 1-arity form takes "us", "eu" or
"au" (case-insensitive; null means us) and returns an Err for
anything else. The 0-arity form reads intercom.region.
intercom.region
build-headers
fn (token: Str, version: Str, has-body: Bool): Map
Request headers: Bearer auth, Intercom-Version, Accept: application/json, and Content-Type only when there is a body. Exposed for testing.
build-search-body
fn (query: Map, options: Map): Map
Build a POST /…/search body: {query, pagination?, sort?}.
options: per_page (max 150), starting_after (the cursor from
the previous page's pages.next.starting_after), and sort
({field, order: "ascending"|"descending"}, contacts only). The
pagination object is omitted when neither is set. Exposed for testing.
collect-pages
fn (fetch: Fn, key: Str, cursor: Str?, limit: Int, acc: Vec): Vec
Follow starting_after cursors, concatenating each page's key
Vec (e.g. "conversations", "contacts", "tickets", "data"),
until limit items or the last page. fetch is a Fn taking the
cursor (null for the first page) and returning one page. Exposed for
testing; the search-all-* functions use it. A failed page comes back as its Err.
compact
fn (body: Map): Map
Drop null-valued keys so unset optionals are omitted rather than sent as JSON null.
next-cursor
fn (page: Any): Str?
The starting_after cursor for the page after page (from pages.next.starting_after), or null on the last page. Works for list and search responses.
non-blank
fn (value: Any): Any
optional-admin-id
fn (opts: Map): Str?
The admin in opts, else intercom.admin.id, else null. intercom.admin.id belongs to the workspace of intercom.token, so it isn't used when opts has its own token.
intercom.admin.id
page-size
fn (limit: Int): Int
The per_page to request when collecting up to limit items: limit clamped to 1..150 (Intercom's maximum).
path-segment
fn (value: Any): Str
Percent-encode one path segment (an id). Ints pass through as text.
query-string
fn (options: Map): Str
Build a ?a=1 suffix from a Map, dropping null values; "" when nothing remains.
request
fn (method: Str, path: Str, body: Any): Any
fn (method: Str, path: Str, body: Any, token: Str): Any
fn (method: Str, path: Str, body: Any, opts: Map): Any
Make an authenticated Intercom request. path is relative to the
regional host (e.g. /contacts); body is a Map, or "" for none.
Returns the decoded body on 2xx (null when empty), or an Err carrying
HttpError (Intercom's errors list is in body). The 4th argument
is per-call opts (see resolve) or an access token.
Example
segments ::intercom::api/request("GET", "/segments", "")
tenant ::intercom::api/request("GET", "/segments", "", {token: "tenant-b-token", region: "eu"})
intercom.token
resolve
fn (opts: Map): Map
Credentials and settings for one call (see resolve-from). A token
from opts is masked in call records with ::hot::ctx/mark-secret,
and opts values are never written to ctx.
Example
::intercom::api/resolve({token: "tenant-b-token", region: "eu"}).base-url // "https://api.eu.intercom.io"
intercom.token, intercom.region, intercom.version
resolve-from
fn (opts: Map, ctx-values: Map): Map
The one resolver, pure: {token, base-url, version} for a call from
opts first, then ctx-values (a Map of context variables), then
defaults. An Err when no token is set, when token is in opts but
blank or null (that never falls back to context), or when the region
isn't us, eu or au. Exposed for testing; resolve feeds it the
context.
response-body
fn (body: Any): Any
Normalize a decoded 2xx body: empty text (202/204 with no content, e.g. data events) becomes null; anything else passes through. Exposed for testing.
send
fn (method: Str, path: Str, body: Any, resolved: Map): Any
with-admin
fn (opts: Map, action: Fn): Any
Run action with the admin to act as. A problem with the call's credentials, or a missing admin, comes back as an Err before anything is sent.
Types
HttpError
HttpError type {
status: Int,
headers: Map,
body: Any
}