How GTMRouter thinks
Five mechanics govern every call: authentication, idempotency, human confirmations, async operations, and suppression. Understand these and the whole API is predictable.
Authentication & scopes
Bearer keys (gtmr_sk_…), stored only as hashes, revocable instantly from the console. Keys carry explicit scopes:
| Scope | Unlocks |
|---|---|
| data:read | find_leads, enrich, verify_email, find_intent, state reads |
| llm | metered LLM passthrough |
| campaign:write | creating and editing draft campaigns |
| campaign:launch | launching (still confirmation-gated) |
| assets:purchase | setup_sending purchases (still confirmation-gated) |
| usage:read | usage & billing reads |
Default keys carry every scope — a human still has to approve each purchase and launch in the console, so scopes aren't the safety net; confirmations are. Trim a key's scopes when you want a narrower agent (say, data:read · usage:read for a research-only assistant).
Idempotency & retries
Send an Idempotency-Key header with any verb. A retry with the same key and the same parameters replays the original result without charging again (the response carries "replayed": true). Same key with different parameters → 409 idempotency_conflict. A retry while the original is still running → 202 in_progress.
The header is required on the three send-class verbs — setup_sending (purchase step), create_campaign, launch_campaign — because retry storms must never duplicate real-world side effects. MCP tools expose this as the idempotency_key argument.
Human confirmations
Actions that spend money or contact real people are two-step by design:
- Call the verb without a token → you get a quote/preview and a single-use confirmation_token (15-minute expiry).
- A human opens the console and approves that exact action — the approval is bound to the precise parameters, so nothing can be swapped after the fact.
- Call the verb again with the token → it executes.
This is server-enforced, not a UI convention: an agent alone cannot mint and redeem its own approval. New workspaces also pass a one-time review before their first external action.
Async operations
Purchases return an operation_id. Poll GET /v1/operations/:id: states run queued → running → waiting_external → succeeded | partially_succeeded | failed, with progress counts. Sending capacity typically provisions within hours and up to ~48h; assets activate automatically and the operation completes itself — no babysitting required.
Suppression
Replies, unsubscribes, and hard bounces suppress the address workspace-wide and permanently. Suppression is enforced in three places: drafted leads are filtered at creation (with counts reported), the list is re-checked at launch, and inbound events remove live recipients from active campaigns. It is not configurable — that's the point. If a suppression removal can't be confirmed at launch, the launch aborts and the campaign stays a draft.
Trust & data
- API keys are stored hashed; a key is displayed exactly once.
- Enriched contacts are cached in your workspace only, for 90 days, then expire.
- Suppression lists are permanent and honored across every campaign you run.
- Humans approve every purchase and every launch. Agents cannot spend alone.
- Your data is never resold or shared across workspaces.