# Connect your gifting workflow

GTM Swag helps go-to-market teams get meetings by sending personalized, thoughtful gifts to the people your GTM tools name, at moments such as a new role, an event or webinar follow-up, a funding round, a product launch, a closed deal or a renewal. Your tool or AI agent adds people; an owner or admin on your team approves each gift, or sets an auto-approve rule with limits. Web version: https://gtmswag.com/guides/connect

You need a GTM Swag account: create one at https://gtmswag.com/login (signing up creates your workspace). Until GTM Swag enables delivery for your workspace, `get_workflow_guide` reports `mode: "test"`: everything works end to end, but no gift ships and no real payment is taken, so don't send those gift links to real prospects. To enable delivery, email eric@betterswag.com (https://gtmswag.com/support).

## Start with a playbook

A playbook is an always-on campaign: one gift, one note template and a monthly budget. Each time a trigger fires (a new role, a signup, a closed deal), your tool adds one person, who waits until an owner or admin approves the gift. An owner or admin can instead turn on auto-approve for the playbook with a per-gift limit and a monthly budget: gifts within those limits and the balance are approved and paid from the balance right away, and anything else waits.

1. Choose a gift: MCP `search_gifts`, then `get_gift`; or REST `GET /api/v1/catalog`.
2. Create the playbook: `create_campaign` with `mode: "always_on"`, or `POST /api/v1/campaigns`. It is saved as a draft.
3. A teammate opens `https://gtmswag.com/campaigns/CAMPAIGN_ID?review=1` and selects **Turn on playbook**. An owner or admin may turn on auto-approve there too.
4. On each trigger: `add_to_playbook`, or `POST /api/v1/playbooks/CAMPAIGN_ID/people` with `{"recipient": {...}}`. Read `approval.state`: `waiting` (with a `reason`), `auto_approved`, `approved`, `scheduled` or `skipped`.
5. An owner or admin approves each waiting gift from the `approvalUrl` in the response, or from `list_queue` / `GET /api/v1/queue`.
6. Keep funds in the balance: `get_balance` / `GET /api/v1/balance`. When `lowBalance` is true, or a gift waits with reason `low_balance`, an owner or admin adds funds at `topUpUrl` (**Settings → Billing & invoices**).

Use a batch campaign (`mode: "batch"`) for a fixed list and a single gift (`mode: "single"`) for one person.

## Connect an AI agent (MCP)

MCP endpoint: `https://gtmswag.com/mcp`. Connect with GTM Swag sign-in (OAuth) or a workspace key.

### Claude (claude.ai, Claude Desktop, Cowork)

1. Open **Customize → Connectors**, select **+ Add**, then **Add custom connector**.
2. Enter the name GTM Swag and the URL `https://gtmswag.com/mcp`, follow the prompts and select **Add**.
3. Select **Connect**, sign in to GTM Swag, check the workspace shown and select **Connect workspace**.
4. In a chat, open the **+** menu, choose **Connectors** and make sure GTM Swag is on.

On a Team or Enterprise plan, an owner first adds the connector in **Organization settings → Connectors** (**Add → Custom → Web**); members then find it in **Customize → Connectors** and select **Connect**. To remove it, use **Remove** next to the connector in **Customize → Connectors**.

### ChatGPT

ChatGPT uses its own endpoint, `https://gtmswag.com/chatgpt/mcp`, and its own tool set (no playbooks). Follow https://gtmswag.com/guides/chatgpt.md.

### Claude Code

```sh
claude mcp add --transport http gtm-swag https://gtmswag.com/mcp
```

Run `/mcp` in Claude Code and sign in to GTM Swag. Signing in is the recommended way: there is no key to store, and you can end access at any time.

To use a workspace key instead, keep it in an environment variable named `GTM_SWAG_KEY`, set from your password manager or shell, never in a chat, and add GTM Swag to your project's `.mcp.json`. Claude Code expands `${GTM_SWAG_KEY}` when it loads the file, so the key itself is never written there:

```json
{
  "mcpServers": {
    "gtm-swag": {
      "type": "http",
      "url": "https://gtmswag.com/mcp",
      "headers": { "Authorization": "Bearer ${GTM_SWAG_KEY}" }
    }
  }
}
```

Avoid `claude mcp add … --header "Authorization: Bearer $GTM_SWAG_KEY"`: your shell expands the variable first, so Claude Code saves the key itself in `~/.claude.json`.

### Other MCP clients

Use Streamable HTTP at `https://gtmswag.com/mcp` with OAuth, or send a workspace key from the client's secret settings:

```json
{
  "mcpServers": {
    "gtm-swag": {
      "type": "http",
      "url": "https://gtmswag.com/mcp",
      "headers": { "Authorization": "Bearer YOUR_GTM_SWAG_KEY" }
    }
  }
}
```

A key at `https://gtmswag.com/mcp` sees the full API-key list of 46 tools; `https://gtmswag.com/mcp?profile=gifting` gives a key the same 31 focused gifting tools that sign-in connections get. Approving, paying, adding funds, and team and webhook changes are never listed for a key or connection: a person does them on gtmswag.com.

First prompt: "Use GTM Swag to list gifts under $60. Don't create a campaign." The agent should call `get_workflow_guide` and `search_gifts`.

### How long a sign-in connection lasts

A sign-in connection stays active while the tool keeps using it. Access tokens last 15 minutes and renew on their own; each renewal keeps the connection for another 30 days, and every connection ends one year after you approved it. Then reconnect and approve the workspace again. Disconnect at any time: Claude and other MCP clients at https://gtmswag.com/oauth/disconnect, ChatGPT at https://gtmswag.com/chatgpt/oauth/disconnect. Access ends immediately. Workspace keys don't expire; revoke them in **Integrations**.

## Connect an HTTP workflow (REST)

Create a workspace key in **Integrations → For developers → Create key**. Store it in your tool's secret store (for example a Clay account or a HubSpot secret), never in a chat, a note or public code. Send it on every request:

```sh
curl https://gtmswag.com/api/v1/campaigns \
  -H "Authorization: Bearer $GTM_SWAG_KEY"
```

A `200` response with a `data` list (even an empty one) confirms access. A key acts with its creator's current role in that workspace. JSON writes also need `Content-Type: application/json`. Success responses are `{"data": ...}`. Errors are `{"error", "code", "nextAction", "url", "retryable", "retryAfterMs"}`; `nextAction` says what to do next.

- Clay: https://gtmswag.com/guides/clay.md
- HubSpot workflows: https://gtmswag.com/guides/hubspot.md
- OpenAPI 3.1 schema: https://gtmswag.com/openapi.json

## Add a person

```json
{
  "recipient": {
    "name": "Jamie Chen",
    "company": "Northstar",
    "sourceSystem": "your-crm",
    "externalId": "contact-123",
    "addressMode": "confirm"
  }
}
```

Each person needs a name, a personal LinkedIn `profileUrl` (`https://www.linkedin.com/in/…`), or both `sourceSystem` and `externalId`. Email and company are optional, unless the playbook's note uses `{{company}}`. Send the same `sourceSystem` and `externalId` on a retry: a repeat returns `alreadyQueued: true` instead of a second gift. For a list without CRM IDs, use the list's name as `sourceSystem` and a value that stays the same per person, such as the LinkedIn profile slug, as `externalId`. When your source has a US shipping address, send `addressMode: "known"` with `address`, `city`, `state` (a two-letter code or the full name) and `zip` (`country` defaults to `US`). With `addressMode: "confirm"`, the recipient confirms their own address through a private gift link that you send in your outreach; once delivery is enabled for your workspace, gifts need the address from you instead.

Without auto-approve, adding a person never charges or ships anything. With it, a gift within the limits an owner or admin set is paid from the balance; a repeat never approves or charges twice. A paused or draft playbook refuses with `409 PLAYBOOK_OFF`; a teammate turns it on at the returned `url`. Change a playbook's settings in GTM Swag: an edit made with a key returns it to draft.

## What needs a person

Keys and sign-in connections can read, prepare drafts and add people. They can't turn a playbook on, approve or skip gifts, pay, add funds, turn on or change auto-approve, manage the team or set up webhooks. Hand the returned URL to a person instead. Any signed-in teammate can turn a playbook on; approving, skipping, paying and adding funds need an owner or admin. Only an auto-approve rule an owner or admin set approves gifts without a person, within its limits.

## Track what happens

Poll `GET /api/v1/events` (MCP `list_tracking_events`) and keep the returned `nextCursor`. `send.created` means a gift exists (fetch its link then), `send.link_opened` means the recipient opened their gift link, and `send.auto_approved` means auto-approve approved a gift. Status and delivery events follow in the same feed. An owner or admin can also add a signed webhook in **Integrations → For developers → Signed webhooks**; webhooks can also receive `playbook.person_waiting` when someone waits for approval.

## Troubleshooting

- `401 AUTH_REQUIRED`: the key is missing, revoked or for another workspace, or the sign-in connection expired.
- `403 HUMAN_APPROVAL_REQUIRED`: a signed-in person must do this; hand the returned `url` to them.
- `409 PLAYBOOK_OFF`: the playbook is paused or still a draft, for example after an edit made with a key.
- `409 PLAYBOOK_BUSY`: other people were being added at the same moment; nothing was saved. Retry after `retryAfterMs` (under a second).
- `409 NOT_ALWAYS_ON`: use `POST /api/v1/campaigns/CAMPAIGN_ID/recipients` for batch campaigns.
- `400 RECIPIENT_MESSAGE_REQUIRED`: the note uses a placeholder, such as `{{company}}`, that this person lacks.
- `429 RATE_LIMIT`: the workspace allows 240 requests per minute; wait `retryAfterMs`, then retry.

Full reference: https://gtmswag.com/api-docs.md. Agent guide: https://gtmswag.com/agent-guide.md
