> ## Documentation Index
> Fetch the complete documentation index at: https://modem.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Plain

> Capture support threads and customer messages from Plain

export const Prompt = ({text, variant = 'accent'}) => {
  const [copied, setCopied] = useState(false);
  const handleCopy = async () => {
    try {
      await navigator.clipboard.writeText(text);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch {}
  };
  const clipboardIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <title>Copy</title>
            <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
            <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
        </svg>;
  const checkIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <title>Copied</title>
            <polyline points="20 6 9 17 4 12" />
        </svg>;
  const promptIcon = <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style={{
    flexShrink: 0,
    opacity: 0.4
  }}>
            <title>Prompt</title>
            <path d="M20 2H2v20h2V4h16v12H6v2H4v2h2v-2h16V2zM6 7h12v2H6zm8 4H6v2h8z" />
        </svg>;
  return <div className={`prompt prompt-${variant}`} style={{
    marginTop: '12px',
    marginBottom: '12px'
  }}>
            {promptIcon}
            <span className="prompt-text">{text}</span>
            <button className="prompt-copy" onClick={handleCopy} title="Copy to clipboard" type="button">
                {copied ? checkIcon : clipboardIcon}
            </button>
        </div>;
};

The Plain integration captures support threads from your Plain workspace in real time. Customer emails, chat messages, and your team's internal notes flow into Modem, where they are grouped into [topics](/docs/guides/topics), classified by type, and linked to the [people and companies](/docs/guides/people) behind them.

<Warning>
  Plain is currently in **beta** and access is rolled out per organization. If you don't see it under **Settings** → **Integrations**,
  email [support@modem.dev](mailto:support@modem.dev) to request access.
</Warning>

<Info>
  Plain is **capture-only** and read-only. Modem ingests thread messages, thread metadata, and customer profiles; it never writes anything
  back to Plain, and the Modem Agent has no tools for taking action inside Plain. You query captured Plain conversations from the [Modem
  Agent on the web](/docs/features/agent), where the agent can still act on what it finds in your other connected tools.
</Info>

## How it works

Modem connects to Plain with a **machine-user API key** you create in your Plain workspace. When you paste the key, Modem validates it, fetches your workspace's Request signing secret, and registers a webhook target in Plain automatically. From then on Plain pushes thread activity to Modem as it happens; every delivery is verified against the signing secret before it's processed.

API keys in Plain don't expire, so there's no re-authorization cycle. Capture is webhook-based and real-time: a new customer message typically shows up in Modem within a few minutes.

## Prerequisites

* **Owner or admin** role in your Modem organization, to connect and manage the integration
* Access to create machine users and API keys in your Plain workspace
* Beta access enabled for your Modem organization (see the note above)

## Setup

<Steps>
  <Step title="Create a machine-user API key in Plain">
    In Plain, go to **Settings** → **Machine users / API keys** and create a key. See [Permissions](#permissions) below for what it
    needs.
  </Step>

  <Step title="Paste the key into Modem">
    Go to **Settings** → **Integrations** → **Plain** in your Modem dashboard, paste the key, and click **Connect Plain**. Modem
    encrypts the key before storing it.
  </Step>

  <Step title="Modem registers its webhook">
    Modem validates the key, reads your workspace's Request signing secret, and registers a webhook target in Plain. New thread activity
    starts flowing immediately.
  </Step>

  <Step title="Optionally run a backfill">
    Import recent existing threads so ongoing conversations show up too. See [Historical Backfill](#historical-backfill) below.
  </Step>
</Steps>

## Permissions

The machine-user API key needs:

| Permission                          | Why Modem needs it                                            |
| ----------------------------------- | ------------------------------------------------------------- |
| Read access to threads and messages | Ingest thread timelines (emails, chats, notes)                |
| Read access to customers            | Link messages to the people behind them                       |
| `webhookTarget:create`              | Register Modem's webhook target automatically                 |
| `workspaceHmac:read`                | Fetch the Request signing secret used to verify each delivery |

<Note>
  If your key can't be granted `workspaceHmac:read`, use the **enter it manually** option on the connect form and paste the secret from
  Plain under **Settings** → **Request signing** instead.
</Note>

## What Gets Captured

### Thread messages

For each Plain thread, Modem captures the timeline as a single conversation:

* **Customer emails** received and support replies sent
* **Chat messages** from both sides
* **Internal notes** written by your team, marked as internal

Email bodies are cleaned before they're stored: quoted-reply chains and signature blocks are stripped, and inline attachment data is collapsed to a short placeholder. Attachment files themselves are not ingested.

### Thread metadata

Each thread's title, status, priority, labels, assignee, and a link back to the thread in Plain. Status, priority, and label changes are recorded on the conversation timeline for context, but these housekeeping entries don't feed topic analysis; only real messages do.

### Customers

Plain customer profiles (name and email) sync as they're created and updated, and message authors are resolved to Modem [people](/docs/guides/people) by email address. Your own teammates are matched to their real email addresses too, so support replies link to existing team members instead of creating duplicates. Plain's automation and system actors are flagged as bots.

## Historical Backfill

Connecting only captures activity from that point forward. To pull in recent history, run the optional backfill from **Settings** → **Integrations** → **Plain**: it imports threads created in the **last 30 days**, up to **500 threads**, along with their messages.

The backfill runs in the background and doesn't block real-time capture. Plain's API is rate-limited, so a busy workspace can take a while; the card shows progress and you can re-run it if it fails.

## Analyzing Plain Conversations

Once threads are flowing, ask the [Modem Agent](/docs/features/agent) about them from the web dashboard like any other source.

<Prompt text="What are customers writing in about in Plain this week?" />

<Prompt text="Summarize the highest-priority open support threads" />

<Prompt text="Create a Linear ticket for the recurring billing complaints from Plain" />

## Troubleshooting

<AccordionGroup>
  <Accordion title="I don't see Plain in Integrations">
    The integration is in beta and enabled per organization. Email [support@modem.dev](mailto:support@modem.dev) to request access. Once
    enabled, the Plain card appears under **Settings** → **Integrations**.
  </Accordion>

  <Accordion title="Connecting fails with a permission error">
    The most common gap is `workspaceHmac:read`: without it Modem can't fetch the Request signing secret automatically. Grant the
    permission to the machine user, or use the manual fallback on the connect form and paste the secret from Plain under **Settings** →
    **Request signing**. Also confirm the key has read access to threads and customers plus `webhookTarget:create`.
  </Accordion>

  <Accordion title="New threads aren't appearing">
    Confirm the integration shows as connected in **Settings** → **Integrations** → **Plain**, then allow a few minutes for webhook
    delivery and processing. Modem only captures activity that happens after you connect; run the [backfill](#historical-backfill) for
    recent existing threads. If nothing arrives, disconnecting and reconnecting registers a fresh webhook target.
  </Accordion>

  <Accordion title="The backfill seems incomplete">
    The backfill covers threads created in the last 30 days, up to 500 threads, so older or excess threads aren't imported. If a run
    failed, the card shows the error and a **Run again** button; re-running is safe and won't duplicate messages. If it still looks
    wrong, contact [support@modem.dev](mailto:support@modem.dev).
  </Accordion>

  <Accordion title="Authors aren't linking to people">
    Message authors are matched to Modem people by email address. If a Plain customer has no email on their profile, their activity
    won't be linked automatically.
  </Accordion>
</AccordionGroup>

## Disconnecting

To disconnect Plain:

1. Go to **Settings** → **Integrations** → **Plain**
2. Click **Disconnect** and confirm

Modem stops accepting deliveries from the workspace and attempts to remove the webhook target it registered in Plain. Removal is best-effort: if the stored API key has already been revoked or Plain's API is unavailable, the disconnect still completes and you may need to delete the target in Plain yourself. Historical data remains in Modem after disconnecting.

## Related

<CardGroup cols={2}>
  <Card title="The Modem Agent" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/bot.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=2496f9106cb54fa9f4e27ad1f8f3a171" href="/docs/features/agent" width="22" height="22" data-path="icons/bot.svg">
    Query and act on your captured Plain conversations from the web.
  </Card>

  <Card title="Topics" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/label-alt-multiple.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=e7fbaf23c28396ac670b89cf38e1e4a6" href="/docs/guides/topics" width="24" height="24" data-path="icons/label-alt-multiple.svg">
    See how support threads are grouped into themes and classified.
  </Card>

  <Card title="Companies & People" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/contact.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=727cb0ef6c8547993c6acfdaa30bd837" href="/docs/guides/people" width="24" height="24" data-path="icons/contact.svg">
    Understand how Plain customers are linked into unified profiles.
  </Card>

  <Card title="All Integrations" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/link.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=e774d33588635d44c6c935b78ed55f13" href="/docs/integrations/overview" width="24" height="24" data-path="icons/link.svg">
    Browse every data source and agent tool.
  </Card>
</CardGroup>
