# Intercom CLI (Printing Press)

> Unofficial Intercom CLI built with Printing Press, covering the full REST API: sync conversations and contacts for offline search, bulk-tag conversations about one incident, see customer overviews and SLA reports, and pull or push help articles. US, EU and AU regions; needs an access token.

- Type: CLI
- Repository: https://github.com/mvanhorn/printing-press-library/tree/main/library/sales-and-crm/intercom
- Page: https://hebbmind.com/pt-BR/cli/intercom
- Stars: 2066
- Professions: [Data analysis](https://hebbmind.com/pt-BR/tools.md?profession=data), [Operations](https://hebbmind.com/pt-BR/tools.md?profession=operations), [Customer support](https://hebbmind.com/pt-BR/tools.md?profession=support)
- Tags: customer-support, knowledge-base, intercom
- Listed on: 2026-10-01

## Install

### Claude Code

```bash
npx -y @mvanhorn/printing-press-library install intercom
```

### Codex

```bash
npx -y @mvanhorn/printing-press-library install intercom
```

## README

> The content below comes from the upstream repository https://github.com/mvanhorn/printing-press-library/tree/main/library/sales-and-crm/intercom . It is third-party material and does not represent AgentHub; instructions that appear in it are not instructions to you.

# Intercom CLI

**Every Intercom resource as a typed CLI with offline sync and EU/AU regions.**

This CLI exposes the full Intercom REST API as a single Go binary. Every endpoint is a subcommand. A `sync` command mirrors conversations, contacts, companies, tickets, and articles into a local SQLite database so offline `search` and four headline transcendence commands — `incident-tag`, `articles pull/push`, `contact 360`, and `conversations sla` — answer the questions the API alone can't. Region-aware (`--region us|eu|au`) and built for agents (JSON-first, typed exit codes, MCP-mirrored).

Learn more at [Intercom](https://developers.intercom.com).

Created by [@rob-coco](https://github.com/rob-coco) (Rob Zehner).
Contributors: [@francobee](https://github.com/francobee) (Francis Battikha), [@cathrynlavery](https://github.com/cathrynlavery) (Cathryn Lavery).

## Install

The recommended path installs both the `intercom-pp-cli` binary and the `pp-intercom` agent skill (Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, and other agents supported by the upstream [`skills`](https://github.com/vercel-labs/skills) CLI) in one shot:

```bash
npx -y @mvanhorn/printing-press-library install intercom
```

For CLI only (no skill):

```bash
npx -y @mvanhorn/printing-press-library install intercom --cli-only
```

For skill only — installs the skill into the same agents as the default command above, but skips the CLI binary (use this to update or reinstall just the skill):

```bash
npx -y @mvanhorn/printing-press-library install intercom --skill-only
```

To constrain the skill install to one or more specific agents (repeatable — agent names match the [`skills`](https://github.com/vercel-labs/skills) CLI):

```bash
npx -y @mvanhorn/printing-press-library install intercom --agent claude-code
npx -y @mvanhorn/printing-press-library install intercom --agent claude-code --agent codex
```

### Without Node (Go fallback)

If `npx` isn't available (no Node, offline), install the CLI directly via Go (requires Go 1.26.6 or newer):

```bash
go install github.com/mvanhorn/printing-press-library/library/sales-and-crm/intercom/cmd/intercom-pp-cli@latest
```

This installs the CLI only — no skill.

### Pre-built binary

Download a pre-built binary for your platform from the [latest release](https://github.com/mvanhorn/printing-press-library/releases/tag/intercom-current). On macOS, clear the Gatekeeper quarantine: `xattr -d com.apple.quarantine <binary>`. On Unix, mark it executable: `chmod +x <binary>`.

<!-- pp-hermes-install-anchor -->
## Install for Hermes

Install the CLI binary first. The installer writes binaries to a per-user managed bin directory by default: `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows.

```bash
npx -y @mvanhorn/printing-press-library install intercom --cli-only
```

Then install the focused Hermes skill.

From the Hermes CLI:

```bash
hermes skills install mvanhorn/printing-press-library/cli-skills/pp-intercom --force
```

Inside a Hermes chat session:

```bash
/skills install mvanhorn/printing-press-library/cli-skills/pp-intercom --force
```

Restart the Hermes session or gateway if the newly installed skill is not visible immediately.

## Install for OpenClaw
Install both the CLI binary and the focused OpenClaw skill. The installer defaults binaries to a per-user bin directory (`$HOME/.local/bin` on macOS/Linux, `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows):

```bash
npx -y @mvanhorn/printing-press-library install intercom --agent openclaw
```

Restart the OpenClaw session or gateway if the newly installed skill is not visible immediately.

## Use with Claude Desktop

This CLI ships an [MCPB](https://github.com/modelcontextprotocol/mcpb) bundle — Claude Desktop's standard format for one-click MCP extension installs (no JSON config required).

To install:

1. Download the `.mcpb` for your platform from the [latest release](https://github.com/mvanhorn/printing-press-library/releases/tag/intercom-current).
2. Double-click the `.mcpb` file. Claude Desktop opens and walks you through the install.
3. Fill in `INTERCOM_ACCESS_TOKEN` when Claude Desktop prompts you.

Requires Claude Desktop 1.0.0 or later. Pre-built bundles ship for macOS Apple Silicon (`darwin-arm64`) and Windows (`amd64`, `arm64`); for other platforms, use the manual config below.

<details>
<summary>Manual JSON config (advanced)</summary>

If you can't use the MCPB bundle (older Claude Desktop, unsupported platform), install the MCP binary and configure it manually.


```bash
go install github.com/mvanhorn/printing-press-library/library/sales-and-crm/intercom/cmd/intercom-pp-mcp@latest
```

Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "intercom": {
      "command": "intercom-pp-mcp",
      "env": {
        "INTERCOM_ACCESS_TOKEN": "<your-key>"
      }
    }
  }
}
```

</details>

## Authentication

Intercom uses Bearer access tokens (PAT-style). Export `INTERCOM_ACCESS_TOKEN` or run `intercom-pp-cli auth set-token "<token>"` to save it to your config. The CLI pins the `Intercom-Version: 2.13` header on every request. Tokens are workspace-scoped; pick the right region with `--region us|eu|au` or `INTERCOM_REGION`.

## Quick Start

```bash
# Save your access token; or just export INTERCOM_ACCESS_TOKEN; verify with `doctor`.
intercom-pp-cli auth set-token "$INTERCOM_ACCESS_TOKEN"

# Confirm auth + reachability before anything destructive.
intercom-pp-cli doctor

# Mirror the four big resources into the local store so offline queries work.
intercom-pp-cli sync --resources contacts,conversations,companies --since 30d

# One nested payload joining a contact's companies, conversations, tickets, notes, and tags.
intercom-pp-cli contact 360 user@example.com --agent

# SLA metrics computed locally from synced conversations + parts.
intercom-pp-cli conversations sla --group-by team --metric first-response,resolution --since 7d --agent

```

## Unique Features

These capabilities aren't available in any other tool for this API.

### Incident response and bulk ops
- **`conversations incident-tag`** — Tag every conversation mentioning a phrase in a time window with one safe-by-default command.

  _When an incident hits, tagging 50 conversations by hand is the bottleneck; this is the single command that closes the loop without spreadsheets._

  ```bash
  intercom-pp-cli conversations incident-tag --mentions "checkout fails" --since 24h --tag incident-2026-05-24 --apply
  ```

### Help center as code
- **`articles pull`** — Flatten every help-center article into a markdown tree you can edit in git, then push changes back.

  _Lets docs teams version-control help-center content alongside product code; multilingual articles land as sibling files._

  ```bash
  intercom-pp-cli articles pull --to ./articles/
  ```

### Local-only analytics
- **`contact 360`** — One nested payload joining a contact across companies, conversations, tickets, notes, and tags.

  _Replaces 4-6 separate API calls and a mental merge; this is the lookup an agent makes before every triage decision._

  ```bash
  intercom-pp-cli contact 360 mei@example.com --agent
  ```
- **`conversations sla`** — First-response and resolution-time metrics grouped by team or admin, computed over the local store.

  _Replaces the weekly export-to-spreadsheet ritual; the API alone can't compute this in one call._

  ```bash
  intercom-pp-cli conversations sla --group-by team --metric first-response,resolution --since 7d --agent
  ```

## Recipes

### Tag every conversation mentioning an outage

```bash
intercom-pp-cli conversations incident-tag --mentions "checkout fails" --since 24h --tag incident-2026-05-24 --apply
```

Search server-side, dry-run by default, --apply fans out tag mutations through the adaptive limiter.

### Find slow-response teams this week

```bash
intercom-pp-cli conversations sla --group-by team --metric first-response,resolution --since 7d --agent --select team,first_response_p50_minutes,resolution_p90_hours
```

Local SQL over conversations + parts; --select narrows the nested payload so agents don't burn context.

### Pull every help-center article into a git-managed tree

```bash
intercom-pp-cli articles pull --to ./articles/
```

Each article lands as `<id>-<slug>.<locale>.md` with YAML frontmatter; commit the directory to git, edit locally, then run `intercom-pp-cli articles push --from ./articles/` to sync diffs back.

### Resolve a contact before triaging

```bash
intercom-pp-cli contact 360 mei@example.com --agent --select contact.id,companies,open_conversations,recent_tickets
```

Joins five entities locally; replaces 4-6 separate API calls and removes the agent's need to template Intercom's nested search predicate.

### List conversations updated this week with --select to keep payload small

```bash
intercom-pp-cli conversations list --agent --select conversations.id,conversations.state,conversations.assignee.id,conversations.tags.id,conversations.title
```

Generated endpoint mirror; `--select` uses dotted paths to walk Intercom's nested envelope so agents don't load 30 KB per conversation.

## Usage

Run `intercom-pp-cli --help` for the full command reference and flag list.

## Paths & environment variables

This CLI separates local files into four path kinds:

| Kind | Contents |
|------|----------|
| `config` | User-editable settings such as `config.toml` and saved profiles |
| `data` | Durable local data: `credentials.toml`, `data.db`, cookies, browser-session proof files, and other auth sidecars |
| `state` | Runtime state such as persisted queries, jobs, and `teach.log` |
| `cache` | Regenerable HTTP/cache files |

Each kind resolves independently. The ladder is:

1. Per-kind env var: `INTERCOM_CONFIG_DIR`, `INTERCOM_DATA_DIR`, `INTERCOM_STATE_DIR`, or `INTERCOM_CACHE_DIR`
2. `--home <dir>` for this invocation
3. `INTERCOM_HOME` for a flat relocated root
4. XDG env vars: `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`, `XDG_CACHE_HOME`
5. Platform defaults matching existing installs

For containers and agent sandboxes, prefer a single relocated root:

```bash
export INTERCOM_HOME=/srv/intercom
intercom-pp-cli doctor
```

Under `INTERCOM_HOME=/srv/intercom`, the four dirs resolve to `/srv/intercom/config`, `/srv/intercom/data`, `/srv/intercom/state`, and `/srv/intercom/cache`.

MCP servers do not receive CLI flags from the host. Put relocation in the host `env` block:

```json
{
  "mcpServers": {
    "intercom": {
      "command": "intercom-pp-mcp",
      "env": {
        "INTERCOM_HOME": "/srv/intercom"
      }
    }
  }
}
```

Precedence matters in fleets: an ambient per-kind variable such as `INTERCOM_DATA_DIR` overrides an explicit `--home` for that kind. Use `INTERCOM_HOME` or the per-kind variables for durable fleet relocation; treat `--home` as the weaker per-invocation lever.

Relocation is one-way. Unsetting `INTERCOM_HOME` does not move files back to platform defaults, and `doctor` cannot find credentials left under a former root. Move the files manually before unsetting relocation variables.

Existing installs keep working because the platform-default rung matches the legacy layout. On the first auth write, stored secrets leave `config.toml` and are consolidated into `credentials.toml` under the data directory. Run `intercom-pp-cli doctor --fail-on warn` to check path and credential-location warnings in automation.

## Commands

### admins

Everything about your Admins

- **`intercom-pp-cli admins list`** - You can fetch a list of admins for a given workspace.
- **`intercom-pp-cli admins list-activity-logs`** - You can get a log of activities by all admins in an app.
- **`intercom-pp-cli admins retrieve`** - You can retrieve the details of a single admin.

### ai

Manage ai

- **`intercom-pp-cli ai create-content-import-source`** - You can create a new content import source by sending a POST request to this endpoint.
- **`intercom-pp-cli ai create-external-page`** - You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead.
- **`intercom-pp-cli ai delete-content-import-source`** - You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source.
- **`intercom-pp-cli ai delete-external-page`** - Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers.
- **`intercom-pp-cli ai get-content-import-source`** - Retrieve a content import source
- **`intercom-pp-cli ai get-external-page`** - You can retrieve an external page.
- **`intercom-pp-cli ai list-content-import-sources`** - You can retrieve a list of all content import sources for a workspace.
- **`intercom-pp-cli ai list-external-pages`** - You can retrieve a list of all external pages for a workspace.
- **`intercom-pp-cli ai update-content-import-source`** - You can update an existing content import source.
- **`intercom-pp-cli ai update-external-page`** - You can update an existing external page (if it was created via the API).

### articles

Everything about your Articles

- **`intercom-pp-cli articles create`** - You can create a new article by making a POST request to `https://api.intercom.io/articles`.
- **`intercom-pp-cli articles delete`** - You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/<id>`.
- **`intercom-pp-cli articles list`** - You can fetch a list of all articles by making a GET request to `https://api.intercom.io/articles`.

> 📘 How are the articles sorted and ordered?
>
> Articles will be returned in descending order on the `updated_at` attribute. This means if you need to iterate through results then we'll show the most recently updated articles first.
- **`intercom-pp-cli articles retrieve`** - You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/<id>`.
- **`intercom-pp-cli articles search`** - You can search for articles by making a GET request to `https://api.intercom.io/articles/search`.
- **`intercom-pp-cli articles update`** - You can update the details of a single article by making a PUT request to `https://api.intercom.io/articles/<id>`.

### companies

Everything about your Companies

- **`intercom-pp-cli companies create-or-update-company`** - You can create or update a company.

Companies will be only visible in Intercom when there is at least one associated user.

Companies are looked up via `company_id` in a `POST` request, if not found via `company_id`, the new company will be created, if found, that company will be updated.

{% admonition type="warning" name="Using `company_id`" %}
  You can set a unique `company_id` value when creating a company. However, it is not possible to update `company_id`. Be sure to set a unique value once upon creation of the company.
{% /admonition %}
- **`intercom-pp-cli companies delete-company`** - Delete a single company.

This endpoint does not permanently remove the company. It archives the company record and detaches any contacts attached to it; the contacts themselves are not deleted. A `company.deleted` webhook is sent once archival completes.

The endpoint returns `200` with `"deleted": true` as soon as the request is accepted — archival is processed asynchronously.

{% admonition type="warning" %}
Third-party integrations that sync companies into Intercom (for example, Salesforce or Chargebee) will recreate any company deleted through this endpoint on their next sync. To prevent recreation, remove or filter the company at the source integration before deleting it via the API.
{% /admonition %}
- **`intercom-pp-cli companies list-all`** - You can list companies. The company list is sorted by the `last_request_at` field and by default is ordered descending, most recently requested first.

Note that the API does not include companies who have no associated users in list responses.

When using the Companies endpoint and the pages object to iterate through the returned companies, there is a limit of 10,000 Companies that can be returned. If you need to list or iterate on more than 10,000 Companies, please use the [Scroll API](https://developers.intercom.com/reference#iterating-over-all-companies).
{% admonition type="warning" name="Pagination" %}
  You can use pagination to limit the number of results returned. The default is `20` results per page.
  See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param.
{% /admonition %}
- **`intercom-pp-cli companies retrieve-acompany-by-id`** - You can fetch a single company.
- **`intercom-pp-cli companies retrieve-company`** - You can fetch a single company by passing in `company_id` or `name`.

  `https://api.intercom.io/companies?name={name}`

  `https://api.intercom.io/companies?company_id={company_id}`

You can fetch all companies and filter by `segment_id` or `tag_id` as a query parameter.

  `https://api.intercom.io/companies?tag_id={tag_id}`

  `https://api.intercom.io/companies?segment_id={segment_id}`
- **`intercom-pp-cli companies scroll-over-all`** - The `list all companies` functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all companies in a dataset.

- Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app.
- If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail
- If the end of the scroll is reached, "companies" will be empty and the scroll parameter will expire

{% admonition type="info" name="Scroll Parameter" %}
  You can get the first page of companies by simply sending a GET request to the scroll endpoint.
  For subsequent requests you will need to use the scroll parameter from the response.
{% /admonition %}
{% admonition type="danger" name="Scroll network timeouts" %}
  Since scroll is often used on large datasets network errors such as timeouts can be encountered. When this occurs you will see a HTTP 500 error with the following message:
  "Request failed due to an internal network error. Please restart the scroll operation."
  If this happens, you will need to restart your scroll query: It is not possible to continue from a specific point when using scroll.
{% /admonition %}
- **`intercom-pp-cli companies update-company`** - You can update a single company using the Intercom provisioned `id`.

{% admonition type="warning" name="Using `company_id`" %}
  When updating a company it is not possible to update `company_id`. This can only be set once upon creation of the company.
{% /admonition %}

### contacts

Everything about your contacts

- **`intercom-pp-cli contacts create`** - You can create a new contact (ie. user or lead).
- **`intercom-pp-cli contacts delete`** - You can delete a single contact.
- **`intercom-pp-cli contacts list`** - You can fetch a list of all contacts (ie. users or leads) in your workspace.
{% admonition type="info" name="Merged contacts" %}
  Contacts that have been merged (via POST /contacts/merge) will not appear in list results. Only the target contact from the merge remains accessible.
{% /admonition %}
{% admonition type="warning" name="Pagination" %}
  You can use pagination to limit the number of results returned. The default is `50` results per page.
  See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param.
{% /admonition %}
- **`intercom-pp-cli contacts merge`** - You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`.

{% admonition type="warning" name="Merged contacts are not retrievable via the API" %}
  Once a merge is completed, the source contact (`from`) is permanently removed from the active contact list. This means:
  - **GET /contacts/{id}** — Requesting the source contact by its original ID will return a `404 Not Found` error.
  - **POST /contacts/search** — The source contact will not appear in search results, including queries filtered by `updated_at`.
  - **GET /contacts** — The source contact will not appear in list results.

  Only the target contact (`into`) remains accessible. If your application stores contact IDs, update them to use the target contact's ID after a merge.
{% /admonition %}
- **`intercom-pp-cli contacts search`** - You can search for multiple contacts by the value of their attributes in order to fetch exactly who you want.

To search for contacts, you need to send a `POST` request to `https://api.intercom.io/contacts/search`.

This will accept a query object in the body which will define your filters in order to search for contacts.

{% admonition type="warning" name="Optimizing search queries" %}
  Search queries can be complex, so optimizing them can help the performance of your search.
  Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize
  pagination to limit the number of results returned. The default is `50` results per page.
  See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param.
{% /admonition %}
### Merged Contacts

Contacts that have been merged (via POST /contacts/merge) are excluded from search results. If a contact was recently merged into another, it will no longer appear in queries filtered by `updated_at` or any other field. Only the target contact from the merge remains searchable.

### Contact Creation Delay

If a contact has recently been created, there is a possibility that it will not yet be available when searching. This means that it may not appear in the response. This delay can take a few minutes. If you need to be instantly notified it is recommended to use webhooks and iterate to see if they match your search filters.

### Nesting & Limitations

You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4).
There are some limitations to the amount of multiple's there can be:
* There's a limit of max 2 nested filters
* There's a limit of max 15 filters for each AND or OR group

### Searching for Timestamp Fields

All timestamp fields (created_at, updated_at etc.) are indexed as Dates for Contact Search queries; Datetime queries are not currently supported. This means you can only query for timestamp fields by day - not hour, minute or second.
For example, if you search for all Contacts with a created_at value greater (>) than 1577869200 (the UNIX timestamp for January 1st, 2020 9:00 AM), that will be interpreted as 1577836800 (January 1st, 2020 12:00 AM). The search results will then include Contacts created from January 2nd, 2020 12:00 AM onwards.
If you'd like to get contacts created on January 1st, 2020 you should search with a created_at value equal (=) to 1577836800 (January 1st, 2020 12:00 AM).
This behaviour applies only to timestamps used in search queries. The search results will still contain the full UNIX timestamp and be sorted accordingly.

### Accepted Fields

Most key listed as part of the Contacts Model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`).

| Field                              | Type                           |
| ---------------------------------- | ------------------------------ |
| id                                 | String                         |
| role                               | String<br>Accepts user or lead |
| name                               | String                         |
| avatar                             | String                         |
| owner_id                           | Integer                        |
| email                              | String                         |
| email_domain                       | String                         |
| phone                              | String                         |
| external_id                        | String                         |
| created_at                         | Date (UNIX Timestamp)          |
| signed_up_at                       | Date (UNIX Timestamp)          |
| updated_at                         | Date (UNIX Timestamp)          |
| last_seen_at                       | Date (UNIX Timestamp)          |
| last_contacted_at                  | Date (UNIX Timestamp)          |
| last_replied_at                    | Date (UNIX Timestamp)          |
| last_email_opened_at               | Date (UNIX Timestamp)          |
| last_email_clicked_at              | Date (UNIX Timestamp)          |
| language_override                  | String                         |
| browser                            | String                         |
| browser_language                   | String                         |
| os                                 | String                         |
| location.country                   | String                         |
| location.region                    | String                         |
| location.city                      | String                         |
| unsubscribed_from_emails           | Boolean                        |
| marked_email_as_spam               | Boolean                        |
| has_hard_bounced                   | Boolean                        |
| ios_last_seen_at                   | Date (UNIX Timestamp)          |
| ios_app_version                    | String                         |
| ios_device                         | String                         |
| ios_app_device                     | String                         |
| ios_os_version                     | String                         |
| ios_app_name                       | String                         |
| ios_sdk_version                    | String                         |
| android_last_seen_at               | Date (UNIX Timestamp)          |
| android_app_version                | String                         |
| android_device                     | String                         |
| android_app_name                   | String                         |
| andoid_sdk_version                 | String                         |
| segment_id                         | String                         |
| tag_id                             | String                         |
| custom_attributes.{attribute_name} | String                         |

### Accepted Operators

{% admonition type="warning" name="Searching based on `created_at`" %}
  You cannot use the `<=` or `>=` operators to search by `created_at`.
{% /admonition %}

The table below shows the operators you can use to define how you want to search for the value.  The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates).

| Operator | Valid Types                      | Description                                                      |
| :------- | :------------------------------- | :--------------------------------------------------------------- |
| =        | All                              | Equals                                                           |
| !=       | All                              | Doesn't Equal                                                    |
| IN       | All                              | In<br>Shortcut for `OR` queries<br>Values must be in Array       |
| NIN      | All                              | Not In<br>Shortcut for `OR !` queries<br>Values must be in Array |
| >        | Integer<br>Date (UNIX Timestamp) | Greater than                                                     |
| <       | Integer<br>Date (UNIX Timestamp) | Lower than                                                       |
| ~        | String                           | Contains                                                         |
| !~       | String                           | Doesn't Contain                                                  |
| ^        | String                           | Starts With                                                      |
| $        | String                           | Ends With                                                        |
- **`intercom-pp-cli contacts show`** - You can fetch the details of a single contact.

{% admonition type="warning" name="Merged contacts" %}
  If a contact has been merged into another contact via the Merge endpoint (POST /contacts/merge), requesting it by its original ID will return a `404 Not Found` error. Use the merged-into contact's ID instead.
{% /admonition %}
- **`intercom-pp-cli contacts show-by-external-id`** - You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads.
- **`intercom-pp-cli contacts update`** - You can update an existing contact (ie. user or lead).

{% admonition type="info" %}
  This endpoint handles both **contact updates** and **custom object associations**.

  See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format.
{% /admonition %}

### conversations

Everything about your Conversations

- **`intercom-pp-cli conversations create`** - You can create a conversation that has been initiated by a contact (ie. user or lead).
The conversation can be an in-app message only.

{% admonition type="info" name="Sending for visitors" %}
You can also send a message from a visitor by specifying their `user_id` or `id` value in the `from` field, along with a `type` field value of `contact`.
This visitor will be automatically converted to a contact with a lead role once the conversation is created.
{% /admonition %}

This will return the Message model that has been created.
- **`intercom-pp-cli conversations delete`** - {% admonition type="warning" name="Irreversible operation" %}
Deleting a conversation is permanent and cannot be reversed.
{% /admonition %}

Deleting a conversation permanently removes it from the inbox. All sensitive data is deleted, including admin and user replies, conversation attributes, uploads, and related content. The conversation will still appear in reporting, though some data may be incomplete due to the deletion.
- **`intercom-pp-cli conversations list`** - You can fetch a list of all conversations.

You can optionally request the result page size and the cursor to start after to fetch the result.
{% admonition type="warning" name="Pagination" %}
  You can use pagination to limit the number of results returned. The default is `20` results per page.
  See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param.
{% /admonition %}
- **`intercom-pp-cli conversations redact`** - You can redact a conversation part or the source message of a conversation (as seen in the source object).

{% admonition type="info" name="Redacting parts and messages" %}
If you are redacting a conversation part, it must have a `body`. If you are redacting a source message, it must have been created by a contact. We will return a `conversation_part_not_redactable` error if these criteria are not met.
{% /admonition %}
- **`intercom-pp-cli conversations retrieve`** - You can fetch the details of a single conversation.

This will return a single Conversation model with all its conversation parts.

{% 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.
{% /admonition %}

For AI agent conversation metadata, please note that you need to have the agent enabled in your workspace, which is a [paid feature](https://www.intercom.com/help/en/articles/8205718-fin-resolutions#h_97f8c2e671).
- **`intercom-pp-cli conversations search`** - You can search for multiple conversations by the value of their attributes in order to fetch exactly which ones you want.

To search for conversations, you need to send a `POST` request to `https://api.intercom.io/conversations/search`.

This will accept a query object in the body which will define your filters in order to search for conversations.
{% admonition type="warning" name="Optimizing search queries" %}
  Search queries can be complex, so optimizing them can help the performance of your search.
  Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize
  pagination to limit the number of results returned. The default is `20` results per page and maximum is `150`.
  See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param.
{% /admonition %}

### Nesting & Limitations

You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4).
There are some limitations to the amount of multiple's there can be:
- There's a limit of max 2 nested filters
- There's a limit of max 15 filters for each AND or OR group

### Accepted Fields

Most keys listed as part of the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`).
The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result.

| Field                                     | Type                                                                                                                                                   |
| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                                        | String                                                                                                                                                 |
| created_at                                | Date (UNIX timestamp)                                                                                                                                  |
| updated_at                                | Date (UNIX timestamp)                                                                                                                                  |
| source.type                               | String<br>Accepted fields are `conversation`, `email`, `facebook`, `instagram`, `phone_call`, `phone_switch`, `push`, `sms`, `twitter` and `whatsapp`. |
| source.id                                 | String                                                                                                                                                 |
| source.delivered_as                       | String                                                                                                                                                 |
| source.subject                            | String                                                                                                                                                 |
| source.body                               | String                                                                                                                                                 |
| source.author.id                          | String                                                                                                                                                 |
| source.author.type                        | String                                                                                                                                                 |
| source.author.name                        | String                                                                                                                                                 |
| source.author.email                       | String                                                                                                                                                 |
| source.url                                | String                                                                                                                                                 |
| contact_ids                               | String                                                                                                                                                 |
| teammate_ids                              | String                                                                                                                                                 |
| admin_assignee_id                         | Integer                                                                                                                                                |
| team_assignee_id                          | Integer                                                                                                                                                |
| channel_initiated                         | String                                                                                                                                                 |
| open                                      | Boolean                                                                                                                                                |
| read                                      | Boolean                                                                                                                                                |
| state                                     | String                                                                                                                                                 |
| waiting_since                             | Date (UNIX timestamp)                                                                                                                                  |
| snoozed_until                             | Date (UNIX timestamp)                                                                                                                                  |

> The README is long; the above is its first 40000 characters. Full content: https://github.com/mvanhorn/printing-press-library/tree/main/library/sales-and-crm/intercom
