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

# MCP tools

> Reference for every tool the Paubox MCP Server exposes for sending and scheduling email, receiving inbound mail, Forms, and Email Marketing.

The Paubox MCP Server exposes 45 tools across four areas: [Email](#email), [Receiving](#receiving), [Forms](#forms), and [Email Marketing](#email-marketing). Each tool maps to an underlying Paubox API operation.

All 34 tools are available over both transports — the hosted HTTP server at `https://mcp.paubox.com/mcp` and the `@paubox/mcp` stdio package. How each one receives your API key is the only difference.

<Note>
  **The optional `apiKey` parameter listed on every tool below exists only on the HTTP transport.** Over stdio the key comes from the `PAUBOX_API_KEY` environment variable and the parameter is not accepted; omit it. Over HTTP the key is resolved from the OAuth token, the `x-paubox-api-key` header, or that parameter.

  Parameters use camelCase (`formId`, `subscriptionListId`) even where the underlying REST API uses snake\_case.
</Note>

## Email

### send\_secure\_email

Sends a single HIPAA compliant email through the Paubox Email API. The sender address must belong to a domain you have verified in the Paubox dashboard.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `from` | string | Yes | Sender address. Must be on a verified Paubox domain. |
| `to` | array of strings | Yes | Recipient email addresses. |
| `subject` | string | Yes | Email subject line. |
| `message` | string | Yes | Message body, as plain text. When `html` is omitted, the server also generates an HTML version from it: blank lines become paragraphs, single newlines become line breaks, markup characters are escaped, and bare URLs are made clickable. |
| `html` | string | No | HTML body, used verbatim as the `text/html` part. `message` is still sent as the `text/plain` fallback. Omit it to have `message` rendered to HTML automatically. |
| `cc` | array of strings | No | CC recipients. |
| `bcc` | array of strings | No | BCC recipients. |
| `forceSecureNotification` | boolean | No | Force a secure notification regardless of recipient settings. Defaults to `false`. |
| `attachments` | array of objects | No | File attachments. Each item takes `fileName` (a bare filename such as `report.pdf`), `contentType` (MIME type, e.g. `application/pdf`) and `content` (the file, base64-encoded). 25 MB total across all attachments. |
| `apiKey` | string | No | Paubox API key. Overrides the credential resolved from the connector or headers. |

**Example payload**

```json theme={null}
{
  "from": "provider@clinic.com",
  "to": ["patient@example.com"],
  "subject": "Your appointment summary",
  "message": "Thank you for visiting us today."
}
```

**Example payload with an HTML body**

```json theme={null}
{
  "from": "provider@clinic.com",
  "to": ["patient@example.com"],
  "subject": "Your appointment summary",
  "message": "Thank you for visiting us today. Read your summary at https://clinic.example/summary",
  "html": "<p>Thank you for visiting us today.</p><p><a href=\"https://clinic.example/summary\">Read your summary</a></p>"
}
```

<Note>
  Send `html` when the message is designed as an email — styled headings, linked phrases, an inline logo. Because the automatic HTML version escapes markup characters, markup placed in `message` arrives as literal text; `html` is the way to send real markup. It is used exactly as given and is not sanitized, so send only markup you control, and keep `message` a readable plain-text equivalent for clients that do not render HTML. `schedule_email` accepts `html` in exactly the same form.
</Note>

**Example payload with an attachment**

```json theme={null}
{
  "from": "provider@clinic.com",
  "to": ["patient@example.com"],
  "subject": "Your appointment summary",
  "message": "Your visit summary is attached.",
  "attachments": [
    {
      "fileName": "visit-summary.pdf",
      "contentType": "application/pdf",
      "content": "JVBERi0xLjQKJcfsj6IKNSAwIG9iago8PC9MZW5..."
    }
  ]
}
```

<Note>
  `content` must be the base64 encoding of the file's bytes, with no `data:` URI prefix. `fileName` must be a bare filename — a path such as `reports/visit.pdf` is rejected. `schedule_email` accepts `attachments` in exactly the same form.
</Note>

**Response:** returns a `sourceTrackingId` string you can pass to `check_email_status`.

### check\_email\_status

Retrieves the current delivery status of a message sent via `send_secure_email`.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `sourceTrackingId` | string | Yes | The tracking ID returned by `send_secure_email`. |
| `apiKey` | string | No | Paubox API key. |

**Example payload**

```json theme={null}
{
  "sourceTrackingId": "abc123def456"
}
```

**Response:** returns an object with delivery disposition details and a timestamp.

### schedule\_email

Schedules a HIPAA compliant email for future delivery. The message is queued and sent at the specified time.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `from` | string | Yes | Sender address. Must be on a verified Paubox domain. |
| `to` | array of strings | Yes | Recipient email addresses. |
| `subject` | string | Yes | Email subject line. |
| `message` | string | Yes | Message body, as plain text. When `html` is omitted, the server also generates an HTML version from it: blank lines become paragraphs, single newlines become line breaks, markup characters are escaped, and bare URLs are made clickable. |
| `html` | string | No | HTML body, used verbatim as the `text/html` part. `message` is still sent as the `text/plain` fallback. Omit it to have `message` rendered to HTML automatically. |
| `scheduledAt` | string | Yes | ISO 8601 datetime for when the email should be sent (e.g. `2025-12-25T15:00:00Z`). |
| `cc` | array of strings | No | CC recipients. |
| `bcc` | array of strings | No | BCC recipients. |
| `forceSecureNotification` | boolean | No | Force a secure notification regardless of recipient settings. Defaults to `false`. |
| `attachments` | array of objects | No | File attachments. Each item takes `fileName` (a bare filename such as `report.pdf`), `contentType` (MIME type, e.g. `application/pdf`) and `content` (the file, base64-encoded). 25 MB total across all attachments. |
| `apiKey` | string | No | Paubox API key. |

**Example payload**

```json theme={null}
{
  "from": "provider@clinic.com",
  "to": ["patient@example.com"],
  "subject": "Your appointment reminder",
  "message": "Your appointment is tomorrow at 10am.",
  "scheduledAt": "2025-12-25T15:00:00Z"
}
```

**Response:** returns a `sourceTrackingId`, `scheduledAt`, and `state`. Save the tracking ID to check status, reschedule, or cancel.

### get\_scheduled\_email

Checks the status of a scheduled email.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `sourceTrackingId` | string | Yes | The tracking ID returned by `schedule_email`. |
| `apiKey` | string | No | Paubox API key. |

**Example payload**

```json theme={null}
{
  "sourceTrackingId": "abc123def456"
}
```

**Response:** returns the scheduled email's `state` (e.g. `pending`, `sent`, `cancelled`) and `scheduledAt` time.

### reschedule\_email

Changes the scheduled delivery time of a pending email.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `sourceTrackingId` | string | Yes | The tracking ID returned by `schedule_email`. |
| `scheduledAt` | string | Yes | New ISO 8601 datetime for when the email should be sent. |
| `apiKey` | string | No | Paubox API key. |

**Example payload**

```json theme={null}
{
  "sourceTrackingId": "abc123def456",
  "scheduledAt": "2025-12-26T10:00:00Z"
}
```

**Response:** returns the updated `scheduledAt` and current `state`.

### cancel\_scheduled\_email

Cancels a scheduled email that has not yet been sent.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `sourceTrackingId` | string | Yes | The tracking ID returned by `schedule_email`. |
| `apiKey` | string | No | Paubox API key. |

**Example payload**

```json theme={null}
{
  "sourceTrackingId": "abc123def456"
}
```

**Response:** returns the tracking ID and updated `state` (`cancelled`).

### validate\_credentials

Verifies that the Paubox API credentials are present and valid by making a live check against the Paubox API. Useful as a first step before sending email.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `apiKey` | string | No | Paubox API key. Pass if you want to validate a specific API key rather than the one already configured. |

When connecting via stdio (Claude Code), the API key comes from an environment variable and no parameters are needed.

**Example payload**

```json theme={null}
{}
```

**Response:** returns a confirmation with a masked API key on success, or an error description if the API key is missing or invalid.

## Receiving

Manage inbound email domains, mailboxes, and messages. These tools use the same API key as the email tools.

### list\_receiving\_domains

Lists all receiving domains for the authenticated account.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns an array of receiving domains with `id`, `domain`, and `state`.

### create\_receiving\_domain

Provisions a new receiving domain under `inbound.paubox.email`. DNS is configured automatically.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `slug` | string | No | Custom subdomain slug. Auto-generated if omitted. |
| `apiKey` | string | No | Paubox API key. |

**Example payload**

```json theme={null}
{
  "slug": "support"
}
```

**Response:** returns the created domain, including its full `domain` name and `state`.

### get\_receiving\_domain

Retrieves a receiving domain by ID.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `id` | integer | Yes | Domain ID. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the domain with `id`, `domain`, `state`, and `dns_records`.

### delete\_receiving\_domain

Deletes a receiving domain and all its mailboxes.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `id` | integer | Yes | Domain ID. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns an empty object on success.

### list\_receiving\_mailboxes

Lists all mailboxes on a receiving domain.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `domainId` | integer | Yes | Receiving domain ID. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns an array of mailboxes with `id`, `email`, and `quota_bytes`.

### create\_receiving\_mailbox

Creates a new mailbox on a receiving domain.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `domainId` | integer | Yes | Receiving domain ID. |
| `name` | string | Yes | Local part of the mailbox address. |
| `password` | string | Yes | Mailbox password. |
| `quotaBytes` | integer | No | Storage quota in bytes. |
| `apiKey` | string | No | Paubox API key. |

**Example payload**

```json theme={null}
{
  "domainId": 1,
  "name": "intake",
  "password": "SecurePass123!"
}
```

**Response:** returns the created mailbox, including its full `email` address.

### get\_receiving\_mailbox

Retrieves a mailbox by domain and mailbox ID.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `domainId` | integer | Yes | Receiving domain ID. |
| `mailboxId` | integer | Yes | Mailbox ID. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the mailbox details.

### delete\_receiving\_mailbox

Deletes a mailbox.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `domainId` | integer | Yes | Receiving domain ID. |
| `mailboxId` | integer | Yes | Mailbox ID. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns an empty object on success.

### list\_received\_emails

Lists received emails across all active receiving domains, sorted by most recent.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `limit` | integer | No | Max emails to return (1–100, default 25). |
| `after` | string | No | Cursor for forward pagination. |
| `before` | string | No | Cursor for backward pagination. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns `data` (array of emails), `has_more`, and `object: "list"`.

### get\_received\_email

Retrieves a single received email with full content, headers, and attachment metadata.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `emailId` | string | Yes | Email ID. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the email with `from`, `to`, `subject`, `body` (text and html), and `attachments`.

### get\_received\_email\_attachment

Downloads a received email attachment.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `emailId` | string | Yes | Email ID. |
| `blobId` | string | Yes | Blob ID of the attachment. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the attachment bytes.

## Forms

The two tools below need no credentials. Everything after them manages forms and submissions and requires an API key carrying the `forms` scope, sent as a Bearer token; scoped keys are managed in the Paubox admin dashboard. See [Forms authentication](/forms/authentication).

### get\_form

Retrieves the full definition of a Paubox Form, including its title, description, and field schema, so an agent can present the form questions in a conversation. No authentication is required for active forms. When an API key carrying the `forms` scope is available, inactive and archived forms become retrievable too.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the Paubox Form to retrieve. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. Enables retrieving inactive and archived forms. |

**Example payload**

```json theme={null}
{
  "formId": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Response:** returns a form object including `title`, `description`, `form_json` (field definitions), and metadata fields (`active`, `signable`, `submission_count`, `created_at`, `updated_at`).

### submit\_form

Submits a completed response to a Paubox Form. No authentication is required for this tool.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form being submitted. |
| `formData` | object | Yes | Key-value pairs matching the form's field schema (`form_json`). Structure varies per form. |
| `attachments` | array of objects | No | File attachments. Each object must include `name` (filename) and `content` (base64-encoded file). Max total size: 250 MB. |

**Example payload: text fields only**

```json theme={null}
{
  "formId": "550e8400-e29b-41d4-a716-446655440000",
  "formData": {
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane@example.com"
  }
}
```

**Example payload: with attachment**

```json theme={null}
{
  "formId": "550e8400-e29b-41d4-a716-446655440000",
  "formData": {
    "first_name": "Jane"
  },
  "attachments": [
    {
      "name": "consent.pdf",
      "content": "JVBERi0xLjQ..."
    }
  ]
}
```

**Response:** returns a success confirmation message on success.

### list\_forms

Lists a customer's Paubox Forms with search, filtering, ordering, and pagination.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `customerId` | integer | Yes | Paubox customer ID the forms belong to. |
| `search` | string | No | Search text matched against form title and description. |
| `formId` | string (UUID) | No | Filter to a specific form. |
| `archived` | boolean | No | Filter by archived status. |
| `active` | boolean | No | Filter by active status. |
| `orderBy` | string | No | Sort field: `title`, `updated_at`, or `submission_count`. Defaults to `created_at`. |
| `order` | string | No | `asc` or `desc`. Defaults to `desc`. |
| `page` | integer | No | Page number. Defaults to `1`. |
| `items` | integer | No | Items per page. Defaults to `50`, maximum `100`. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Example payload**

```json theme={null}
{
  "customerId": 1234,
  "active": true,
  "orderBy": "submission_count",
  "order": "desc"
}
```

**Response:** returns a paginated list of form objects with title, status, and submission counts.

### create\_form

Creates a new Paubox Form.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `title` | string | Yes | Form title. |
| `formJson` | object | Yes | Form schema (`form_json`) — an object with a `body` array of components. See [Form schema](#form-schema-formjson) below. Pass the object itself; a JSON-encoded string is also parsed. |
| `customerId` | integer | Yes | Paubox customer ID that owns the form. |
| `description` | string | No | Form description. |
| `formHtml` | string | No | Rendered form HTML. |
| `formCss` | string | No | Form CSS. |
| `recipient` | string | No | Comma-separated email addresses that receive submission notifications. |
| `signable` | boolean | No | Whether the form collects a signature. |
| `signatureConfirmationLabel` | string | No | Label shown next to the signature confirmation checkbox. |
| `subscriptionListId` | string | No | Subscription list to add submitters to. |
| `type` | string | No | Form type, for example `marketing_form`. |
| `active` | boolean | No | Whether the form is active. Defaults to `false`. |
| `version` | integer | No | Form version. Defaults to `1`. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Example payload**

```json theme={null}
{
  "customerId": 1234,
  "title": "Patient intake",
  "recipient": "intake@clinic.com",
  "active": true,
  "formJson": {
    "body": [
      {
        "type": "Text",
        "id": "pi-01",
        "properties": {
          "font": "%{defaultFont}",
          "font_size": "22px",
          "color": "%{defaultLabelColor}",
          "text_align": "left",
          "margin": "4px",
          "text": "<p><strong>Patient intake</strong></p>"
        }
      },
      {
        "type": "TextInput",
        "id": "pi-02",
        "properties": {
          "label_enabled": true,
          "label_position": "Top",
          "label_font": "%{defaultFont}",
          "label_font_size": "16px",
          "label_color": "%{defaultLabelColor}",
          "text_align": "left",
          "margin": "4px",
          "subtext_enabled": false,
          "subtext": "",
          "field_name": "first_name",
          "required": true,
          "text": "<p>First name</p>",
          "placeholder_text": "Enter text here",
          "input_mask": "Any",
          "input_color": "%{defaultInputColor}"
        }
      },
      {
        "type": "Button",
        "id": "pi-03",
        "properties": {
          "margin": "4px",
          "full_width": true,
          "button_position": "Center",
          "button_roundness": "4px",
          "button_color": "%{defaultSelectedColor}",
          "label_enabled": true,
          "text": "<p><strong>Submit</strong></p>",
          "label_position": "Top",
          "label_font": "%{defaultFont}",
          "label_font_size": "16px",
          "label_color": "#fff",
          "text_align": "center",
          "subtext_enabled": false,
          "subtext": ""
        }
      }
    ]
  }
}
```

**Response:** returns the created form, including its UUID.

### Form schema (`formJson`)

`formJson` is **not** a free-form field list. The Paubox form renderer reads exactly one
top-level key, `body`, holding an ordered array of components. Anything else is stored
verbatim and renders as an empty form, with no error (PPD-9105).

Each entry in `body` needs three keys:

| Key | Type | Description |
| :- | :- | :- |
| `type` | string | One of the component types below. Case-sensitive. |
| `id` | string | Unique within the form. Any stable string; the builder uses short random ids. |
| `properties` | object | Per-type settings. Keys are **`snake_case`** on the wire. |

**Component types:** `Text`, `Divider`, `TextInput`, `TextArea`, `Dropdown`, `Checkboxes`,
`Radiobutton`, `FileUpload`, `Signature`, `Button`, `Conditional`, `Logo`.

Note `Radiobutton` — lowercase `b`, unlike the others.

**Input components** (`TextInput`, `TextArea`, `Dropdown`, `Checkboxes`, `Radiobutton`,
`FileUpload`, `Signature`) carry the label block — `label_enabled`, `label_position`,
`label_font`, `label_font_size`, `label_color`, `text_align`, `margin`, `subtext_enabled`,
`subtext` — plus:

| Property | Applies to | Description |
| :- | :- | :- |
| `field_name` | all inputs | The key this field's answer appears under in a submission. Slugified label, e.g. `first_name`. Must be unique within the form. |
| `required` | all inputs | Boolean. |
| `text` | all inputs | The visible label, as HTML: `"<p>First name</p>"`. |
| `placeholder_text` | `TextInput`, `TextArea`, `Signature` | Placeholder copy. |
| `input_mask` | `TextInput` | One of `"Any"` (default, no mask), `"Email"`, `"Phone Number"`, `"Number"`, `"Date"`, `"SSN"`, `"ZIP Code"`. An unrecognized value is silently treated as `"Any"`. |
| `input_color` | `TextInput`, `TextArea` | Usually the `%{defaultInputColor}` token. |
| `choices` | `Dropdown`, `Checkboxes`, `Radiobutton` | Array of `{ "value": "Displayed text", "id": "0" }`. |
| `signature_type` | `Signature` | `"Drawn Signature"`. |

**Static components** (`Text`, `Divider`, `Button`, `Logo`) take no `field_name` and never
appear in submissions. `Text` uses `font`, `font_size`, `color`, `text_align`, `margin`, and
`text` (HTML).

<Note>
  Values like `%{defaultFont}` and `%{defaultLabelColor}` are theming tokens resolved against the
  form's design settings at render time. Copy them as written rather than substituting literal
  fonts and colors, so the form follows the customer's branding.
</Note>

<Tip>An agent can build a `body` array from a fillable PDF's extracted fields and create a matching Paubox Form in a single conversation. Map each PDF field to the component type above that matches it, slugify its label into `field_name`, and append a `Button` to submit.</Tip>

### update\_form

Updates an existing Paubox Form. Only the fields you provide change; omitted fields stay as they are.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form to update. |
| `title` | string | No | New form title. |
| `description` | string | No | New form description. |
| `formJson` | object | No | New form schema (`form_json`), same shape as [create\_form](#form-schema-formjson). Replaces the stored schema wholesale — send the complete `body`, not a partial one. |
| `vanityUrl` | string | No | New vanity URL slug. |
| `recipient` | string | No | Comma-separated email addresses that receive submission notifications. |
| `active` | boolean | No | Set the form's active status. |
| `subscriptionListId` | string | No | Subscription list to add submitters to. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Example payload**

```json theme={null}
{
  "formId": "550e8400-e29b-41d4-a716-446655440000",
  "active": false
}
```

**Response:** returns the updated form.

### archive\_form

Archives a Paubox Form. This sets `archived` to `true` and `active` to `false`.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form to archive. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Response:** returns the archived form.

### unarchive\_form

Restores a previously archived Paubox Form.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form to unarchive. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Response:** returns the restored form.

### copy\_form

Duplicates an existing Paubox Form under a new title.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form to copy. |
| `title` | string | Yes | Title for the new copy. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Response:** returns the new form, including its UUID.

### get\_form\_stats

Returns aggregate Paubox Forms statistics: active form count, total submission count, and submissions in the last 7 days.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `customerId` | integer | No | Paubox customer ID. Defaults to the API key's customer. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Response:** returns `active_form_count`, `submission_count`, and `submissions_last_7_days`.

### list\_form\_submissions

Lists a form's submissions, with each submission's `form_data` parsed into structured key/value pairs.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form. |
| `submissionId` | string (UUID) | No | Filter to a single submission. |
| `orderBy` | string | No | Sort field: `submitter_email`. Defaults to `created_at`. |
| `order` | string | No | `asc` or `desc`. |
| `page` | integer | No | Page number. Defaults to `1`. |
| `items` | integer | No | Items per page. Maximum `100`. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Response:** returns submissions with parsed field data, submitter email, and attachment info.

### export\_submissions\_csv

Exports a form's submissions as CSV text.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form. |
| `submissionId` | string (UUID) | No | Export only this submission. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Response:** returns CSV text.

### export\_submission\_pdf

Exports a single form submission as a PDF.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `formId` | string (UUID) | Yes | UUID of the form. |
| `submissionId` | string (UUID) | Yes | UUID of the submission. |
| `apiKey` | string | No | Paubox API key with the `forms` scope. |

**Response:** returns the PDF, base64-encoded.

## Email Marketing

These tools read and write Paubox Email Marketing data. They use the same API key as the email tools — no additional scope is required — but the account must have Email Marketing provisioned. Call `validate_marketing_access` first if another marketing tool reports that no marketing customer was found.

<Note>This set is read-only plus safe subscriber and list writes. Campaign sending and bulk deletion are deliberately not exposed over MCP.</Note>

Every tool below accepts an optional `apiKey` string parameter, which behaves as described above; it is omitted from the tables that have no other parameters.

### validate\_marketing\_access

Checks whether the account has Email Marketing provisioned and returns the marketing customer profile.

**Example payload**

```json theme={null}
{}
```

**Response:** returns the marketing customer name, `from_name`, `from_email`, physical address, and global unsubscribe setting.

### list\_subscribers

Lists Email Marketing subscribers. Omit `subscriptionListId` to search the account's default "All contacts" list.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `search` | string | No | Search text. Defaults to all subscribers. |
| `subscriptionListId` | integer | No | Restrict to a subscription list. IDs come from `list_subscription_lists`. |
| `dynamicListId` | string (UUID) | No | Restrict to a dynamic list. UUIDs come from `list_dynamic_lists`. |
| `orderBy` | string | No | Sort field. Defaults to `created_at`. |
| `order` | string | No | `asc` or `desc`. Defaults to `desc`. |
| `page` | integer | No | Page number. Defaults to `1`. |
| `items` | integer | No | Items per page. Defaults to `50`, capped at `200`. |
| `withStats` | boolean | No | Include per-subscriber delivery statistics. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns a paginated list of subscribers.

### get\_subscriber

Retrieves one subscriber by UUID, including custom field values and subscription list memberships.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `subscriberId` | string (UUID) | Yes | Subscriber UUID. |
| `subscriptionListId` | integer | No | Report subscribed/unsubscribed relative to this subscription list. |
| `dynamicListId` | string (UUID) | No | Report subscribed/unsubscribed relative to this dynamic list. |
| `withStats` | boolean | No | Include this subscriber's delivery statistics. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the subscriber object.

### create\_subscriber

Adds a subscriber. Requires an email address or a phone number.

The subscriber always joins the default "All contacts" list, plus `subscriptionListId` when given. An existing subscriber matching the same email or phone is updated rather than duplicated. Custom field names that do not exist yet are created automatically.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `email` | string | No\* | Subscriber email address. |
| `phoneNumber` | string | No\* | Subscriber phone number, normalized to E.164. |
| `firstName` | string | No | First name. |
| `lastName` | string | No | Last name. |
| `customFields` | array of objects | No | Custom field values. Each object has `name` and `value`. |
| `subscriptionListId` | integer | No | Additional subscription list to subscribe them to. |
| `apiKey` | string | No | Paubox API key. |

\* One of `email` or `phoneNumber` is required.

**Example payload**

```json theme={null}
{
  "email": "jane@example.com",
  "firstName": "Jane",
  "subscriptionListId": 42,
  "customFields": [{ "name": "clinic", "value": "Downtown" }]
}
```

**Response:** returns the created or updated subscriber.

### update\_subscriber

Updates an existing subscriber by UUID. Only the fields you provide change.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `subscriberId` | string (UUID) | Yes | Subscriber UUID. |
| `email` | string | No | New email address. |
| `phoneNumber` | string | No | New phone number, normalized to E.164. |
| `firstName` | string | No | New first name. |
| `lastName` | string | No | New last name. |
| `customFields` | array of objects | No | Custom field values to set. Each object has `name` and `value`. |
| `subscriptionListId` | integer | No | Subscription list to also subscribe them to. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the updated subscriber.

### get\_subscribed\_count

Counts currently subscribed contacts on a list, excluding unsubscribed and deleted contacts.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `subscriptionListId` | integer | No | Subscription list ID. Defaults to the account's default list. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the subscribed contact count.

### list\_subscriber\_custom\_fields

Lists the custom subscriber field types defined for the account. Use this to discover which custom field names `create_subscriber` and `update_subscriber` can set.

**Example payload**

```json theme={null}
{}
```

**Response:** returns the account's custom field definitions.

### list\_marketing\_lists

Lists all audiences — both static subscription lists and filter-based dynamic lists — in one view with subscriber counts. Use `list_subscription_lists` or `list_dynamic_lists` when you need one kind specifically.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `search` | string | No | Search text matched against list names. |
| `orderBy` | string | No | `name`, `created_at`, `updated_at`, or `subscriber_count`. Defaults to `name`. |
| `order` | string | No | `asc` or `desc`. Defaults to `asc`. |
| `page` | integer | No | Page number. Enables pagination. |
| `items` | integer | No | Items per page. Maximum `200`. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns all audiences with their kind, ID, and subscriber count.

### list\_subscription\_lists

Lists static subscription lists with their integer IDs, subscriber counts, and which one is the default "All contacts" list. The IDs returned here are what `subscriptionListId` expects elsewhere.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `orderBy` | string | No | Sort field. Defaults to `name`. |
| `order` | string | No | `asc` or `desc`. Defaults to `asc`. |
| `page` | integer | No | Page number. Enables pagination. |
| `items` | integer | No | Items per page. Maximum `200`. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns subscription lists with integer IDs and subscriber counts.

### create\_subscription\_list

Creates a new, empty subscription list.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `name` | string | Yes | Name for the new subscription list. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns the new list's integer ID, for use with `create_subscriber` and `list_subscribers`.

### list\_dynamic\_lists

Lists dynamic lists — filter-based segments that recompute their membership — with their UUIDs, filter definitions, and subscriber counts.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `orderBy` | string | No | Sort field. Defaults to `name`. |
| `order` | string | No | `asc` or `desc`. Defaults to `asc`. |
| `page` | integer | No | Page number. Enables pagination. |
| `items` | integer | No | Items per page. Maximum `200`. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns dynamic lists with UUIDs, filter definitions, and subscriber counts.

### list\_campaign\_sends

Lists campaign sends — each time a marketing email went out to a list — with per-send counts for delivered, viewed, clicked, bounced, and unsubscribed.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `search` | string | No | Search text matched against the send. |
| `orderBy` | string | No | Sort field. Defaults to `created_at`. |
| `order` | string | No | `asc` or `desc`. Defaults to `desc`. |
| `page` | integer | No | Page number. Defaults to `1`. |
| `items` | integer | No | Items per page. Maximum `200`. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns campaign sends with their integer IDs and per-send engagement counts.

### list\_campaign\_deliveries

Lists individual deliveries — one row per recipient per campaign — showing what happened to each message.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `campaignMailingId` | integer | No | Restrict to one campaign mailing. |
| `campaignMailingSendId` | integer | No | Restrict to one send of a campaign mailing. IDs come from `list_campaign_sends`. |
| `search` | string | No | Search text. |
| `orderBy` | string | No | Sort field. Defaults to `created_at`. |
| `order` | string | No | `asc` or `desc`. Defaults to `desc`. |
| `page` | integer | No | Page number. Defaults to `1`. |
| `items` | integer | No | Items per page. Maximum `200`. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns per-recipient delivery rows.

### get\_campaign\_analytics

Runs an Email Marketing analytics report.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `report` | string | Yes | Which report to run. See the table below. |
| `campaignMailingId` | integer | No | Scope to one campaign mailing. |
| `campaignMailingSendId` | integer | No | Scope to one campaign send. |
| `dripCampaignId` | integer | No | Scope to one drip campaign. |
| `trackingLinkId` | integer | No | Scope to one tracking link. |
| `emailType` | string | No | Filter by email type. |
| `search` | string | No | Search text. |
| `orderBy` | string | No | Sort field, for example `marketing_email_id`, `sent_at`, or `subscription_list_name`. |
| `order` | string | No | `asc` or `desc`. Defaults to `desc`. |
| `byDate` | boolean | No | For `campaign_mailing_send_totals`: bucket results by date. |
| `startDate` | string | No | Start of the date range. Pair with `endDate`. |
| `endDate` | string | No | End of the date range. Pair with `startDate`. |
| `dateOffset` | integer | No | For `campaign_mailing_send_totals` with `byDate`: look back this many days instead of giving `startDate`/`endDate`. |
| `withStats` | boolean | No | Include summed delivery statistics columns. |
| `apiKey` | string | No | Paubox API key. |

| `report` value | Returns |
| :- | :- |
| `campaign_mailing_sends_table` | Per-send performance rows. |
| `campaign_mailing_send_totals` | Aggregate totals, optionally bucketed by date. |
| `campaign_mailing_deliveries_table` | Per-recipient detail for one campaign or send. |
| `subscribers_by_tracking_link` | Which subscribers clicked a link. |
| `tracking_links_by_unique_link` | Click counts per link. |

**Example payload**

```json theme={null}
{
  "report": "campaign_mailing_send_totals",
  "byDate": true,
  "dateOffset": 30
}
```

**Response:** returns the requested report rows.

### get\_marketing\_bulk\_job

Checks the progress of an asynchronous bulk job. Bulk subscriber imports and CSV exports return a job ID (`jid` or `bid`) instead of a result; pass it here.

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `bulkJobId` | string | Yes | The `bid` or `jid` returned by a bulk operation. |
| `apiKey` | string | No | Paubox API key. |

**Response:** returns total, pending, and failed counts for the job.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.