Agency API quickstart

Launch your first usable SMTP inboxes by API.

This guide walks from empty account to workspace, domain, DNS records, inboxes, SMTP credentials, readiness checks, and sequencer export using the same response envelope as the public API.

Still choosing between SMTP infrastructure, reseller-backed inboxes, or white-glove vendors? Start with the provider comparisons. They frame GTM as API-first, readiness-gated infrastructure without unsupported deliverability or reseller claims.

Before you start

Create an API key with workflow scopes

In the dashboard, open Settings → API Keys, create a key, and copy it immediately. For this quickstart, grant these scopes:

read:workspaceswrite:workspacesread:domainswrite:domainsread:inboxeswrite:inboxesread:credentialsread:deliverabilitywrite:deliverabilityread:integrationswrite:integrations

Store credentials in environment variables. Do not paste API keys or SMTP passwords into tickets, logs, chat, or customer-visible notes.

export BASE_URL="https://app.gtminboxes.com"
export GTMI_API_KEY="gtmi_live_..."

Optional CLI

Use terminal-friendly read operations

From the repo checkout, the local CLI can run the same read-only workflow checks with compact JSON output by default and --pretty for tables. It reads GTMI_API_KEY or a saved profile and never prints stored keys.

pnpm gtmi commands list
pnpm gtmi workspaces list
pnpm gtmi domains list --workspace-id $WORKSPACE_ID
pnpm gtmi inboxes list --workspace-id $WORKSPACE_ID
pnpm gtmi readiness smtp --workspace-id $WORKSPACE_ID --pretty
pnpm gtmi readiness report --workspace-id $WORKSPACE_ID --pretty

printf '%s' "$GTMI_API_KEY" | pnpm gtmi auth login --api-key-stdin --profile prod
pnpm gtmi auth status --profile prod

For reseller-backed workflows, grant read:reseller-orders and use pnpm gtmi reseller-orders list --workspace-id $WORKSPACE_ID or pnpm gtmi reseller-orders get --order-id order_id to inspect customer-safe order status and mailbox readiness without triggering lifecycle actions.

Optional MCP

Connect an AI assistant safely

The local CLI can also run as a read-only MCP stdio server for Claude, Cursor, or Windsurf. It exposes workspace, domain, inbox, alert, reseller order, deliverability overview, SMTP readiness, workspace readiness report, and warmup readiness tools only. Missing API key permissions return safe tool errors instead of attempting write operations.

{
  "mcpServers": {
    "gtminboxes": {
      "command": "pnpm",
      "args": ["--dir", "/absolute/path/to/gtminboxes-app", "gtmi", "mcp", "serve"],
      "env": {
        "GTMI_API_KEY": "gtmi_live_..."
      }
    }
  }
}

If you saved a profile with pnpm gtmi auth login --api-key-stdin, use "args": ["--dir", "/absolute/path/to/gtminboxes-app", "gtmi", "mcp", "serve", "--profile", "prod"]instead of storing the key in the client config.

Step 1

Create a workspace for the client

Use one workspace per client or operating unit. The default pool choice is safe for a first launch; choose dedicated infrastructure only when it is already provisioned and assigned.

curl -sS -X POST "$BASE_URL/api/v1/workspaces"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "name": "Acme Client",
    "slug": "acme-client",
    "ipPoolType": "shared_established"
  }'
{
  "success": true,
  "data": {
    "id": "workspace_id",
    "name": "Acme Client",
    "slug": "acme-client",
    "ipPoolType": "shared_established"
  }
}
export WORKSPACE_ID="workspace_id"

Step 2

Add, register, or import domains

If you already own a campaign domain, add it directly. Start with a small number of inboxes per domain and increase only after DNS, warmup, and SMTP readiness are clean.

curl -sS -X POST "$BASE_URL/api/v1/domains"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "workspaceId": "'"$WORKSPACE_ID"'",
    "domain": "tryacme-mail.com",
    "registrar": "manual"
  }'
export DOMAIN_ID="domain_id"

To buy a new domain through a configured registrar, check availability first, then start registration.

curl -sS "$BASE_URL/api/v1/domains/availability?domain=tryacme-mail.com&registrar=opensrs"   -H "Authorization: Bearer $GTMI_API_KEY"

curl -sS -X POST "$BASE_URL/api/v1/domains/register"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "workspaceId": "'"$WORKSPACE_ID"'",
    "domainName": "tryacme-mail.com",
    "registrationPeriodYears": 1,
    "autoRenew": true,
    "whoisPrivacy": true,
    "registrar": "opensrs",
    "contactInfo": {
      "firstName": "Ops",
      "lastName": "Owner",
      "organization": "Acme",
      "email": "ops@example.com",
      "phone": "+15551234567",
      "address1": "123 Market St",
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94105",
      "country": "US"
    }
  }'

To import Cloudflare zones, connect a domain source with the Cloudflare account email and Global API Key, then trigger a sync when needed.

curl -sS -X POST "$BASE_URL/api/v1/domain-sources"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "workspaceId": "'"$WORKSPACE_ID"'",
    "email": "ops@example.com",
    "apiKey": "cloudflare_global_api_key"
  }'

curl -sS -X POST "$BASE_URL/api/v1/domain-sources/domain_source_id/sync"   -H "Authorization: Bearer $GTMI_API_KEY"

Step 3

Publish and validate DNS records

Fetch the required DNS records, publish SPF, DKIM, DMARC, MX, and return-path at your DNS host, then validate. DNS checks are rate-limited; wait at least 30 seconds between validation attempts.

curl -sS "$BASE_URL/api/v1/domains/$DOMAIN_ID/records"   -H "Authorization: Bearer $GTMI_API_KEY"
curl -sS -X POST "$BASE_URL/api/v1/domains/$DOMAIN_ID/validate"   -H "Authorization: Bearer $GTMI_API_KEY"

Continue only after the domain status is verified. If records are still propagating, create the domain and DNS records now, then return after propagation completes.

Step 4

Create inboxes and capture credentials

For a single inbox, the create response can include a one-time plaintext SMTP password. Save it in your secret store immediately; stored passwords are not returned later. The credentials endpoint requires read:credentialsand returns SMTP/IMAP host, port, username, and redacted password metadata for readiness checks and troubleshooting.

curl -sS -X POST "$BASE_URL/api/v1/inboxes"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "workspaceId": "'"$WORKSPACE_ID"'",
    "domainId": "'"$DOMAIN_ID"'",
    "localPart": "alex",
    "displayName": "Alex from Acme"
  }'
export INBOX_ID="inbox_id"

curl -sS "$BASE_URL/api/v1/inboxes/$INBOX_ID/credentials"   -H "Authorization: Bearer $GTMI_API_KEY"

For a first batch, create a conservative set and keep daily send limits low until warmup and monitoring have enough history.

curl -sS -X POST "$BASE_URL/api/v1/inboxes/bulk"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "workspaceId": "'"$WORKSPACE_ID"'",
    "domainId": "'"$DOMAIN_ID"'",
    "inboxes": [
      { "localPart": "alex", "displayName": "Alex from Acme" },
      { "localPart": "sam", "displayName": "Sam from Acme" }
    ]
  }'

Step 5

Check readiness and seed placement before export

Inbox list responses include smtpReadiness per inbox andreadinessSummary for the current page. Only export inboxes withsmtpReadiness.status === "pass", which requires verified DNS, MX, Return-Path, DKIM sidecar deployment, MTA assignment, credentials, and recent SMTP/IMAP smoke tests.

curl -sS "$BASE_URL/api/v1/inboxes?workspaceId=$WORKSPACE_ID&domainId=$DOMAIN_ID"   -H "Authorization: Bearer $GTMI_API_KEY"

Use the warmup readiness endpoint for a workspace-level pre-flight checklist covering DNS, credentials, IP health, and integration connectivity.

curl -sS "$BASE_URL/api/v1/warmup/readiness?workspaceId=$WORKSPACE_ID"   -H "Authorization: Bearer $GTMI_API_KEY"

Use the workspace readiness report for one redacted proof bundle across domains, inboxes, SMTP/IMAP readiness, launch gate, seed placement, active alerts, and exportability. Inbox rows include a redacted recovery plan with an owner, customer-safe summary, and whether human approval is required before repair. The report also includes 30-day proof metrics with explicit public-safe and customer-safe claim visibility; internal-only metric rows and operator notes are omitted from the API response. It requiresread:inboxes and is safe to share without SMTP passwords, encrypted credentials, password hashes, or provider secrets.

curl -sS "$BASE_URL/api/v1/workspaces/$WORKSPACE_ID/readiness-report"   -H "Authorization: Bearer $GTMI_API_KEY"

pnpm gtmi readiness report --workspace-id $WORKSPACE_ID --pretty

Before first prospect traffic, record a seed-placement check with Gmail and Outlook inbox, spam, and missing counts. The launch gate blocks prospects if placement is missing, stale, or below threshold.

curl -sS -X POST "$BASE_URL/api/v1/workspaces/$WORKSPACE_ID/seed-placement/checks"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "domainId": "'"$DOMAIN_ID"'",
    "providerResults": [
      { "provider": "gmail", "inboxCount": 9, "spamCount": 1, "missingCount": 0 },
      { "provider": "outlook", "inboxCount": 9, "spamCount": 0, "missingCount": 1 }
    ],
    "notes": "Pre-launch seed check"
  }'

curl -sS "$BASE_URL/api/v1/workspaces/$WORKSPACE_ID/seed-placement"   -H "Authorization: Bearer $GTMI_API_KEY"

Step 6

Connect and export to a sequencer

Connect Smartlead, Instantly, or EmailBison with that provider's API key. The key is validated before storage. Export is asynchronous and requires a non-empty list of inbox IDs. EmailBison integrations can also discover and import provider accounts into existing GTM Inboxes.

curl -sS -X POST "$BASE_URL/api/v1/integrations"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "workspaceId": "'"$WORKSPACE_ID"'",
    "platform": "smartlead",
    "apiKey": "smartlead_api_key"
  }'
export INTEGRATION_ID="integration_id"

curl -sS -X POST "$BASE_URL/api/v1/integrations/$INTEGRATION_ID/export"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "inboxIds": ["'"$INBOX_ID"'"]
  }'

curl -sS "$BASE_URL/api/v1/integrations/$INTEGRATION_ID/exports"   -H "Authorization: Bearer $GTMI_API_KEY"

Not-ready inboxes are blocked per export row with a redacted readiness reason and next action. Re-read the workspace readiness report before retrying so you can follow the inbox recovery plan and the next export only includes inboxes that are currently exportable while the launch gate is not paused or hard-stopped.

pnpm gtmi readiness report --workspace-id $WORKSPACE_ID --pretty
pnpm gtmi readiness smtp --workspace-id $WORKSPACE_ID --pretty

Shortcut

Chain steps 3–6 with the auto-provision coordinator

For an existing, owned domain you can hand the whole tail to one async job instead of sequencing DKIM provisioning, inbox creation, and export yourself. It returns a provisioningJobId; poll the job for per-step state and redacted errors. It never bypasses a gate: warmup and export are deferred, and the export step stays blocked until the launch gate and per-inbox smtpReadiness pass — exactly like a manual export. It does not register or buy domains, so register the domain first (Step 2).

curl -sS -X POST "$BASE_URL/api/v1/workspaces/$WORKSPACE_ID/auto-provision"   -H "Authorization: Bearer $GTMI_API_KEY"   -H "Content-Type: application/json"   -d '{
    "domainId": "'"$DOMAIN_ID"'",
    "localParts": ["john", "jane"],
    "integrationId": "'"$INTEGRATION_ID"'"
  }'

# Poll per-step status (provision_dkim, create_inboxes, warm, export_to_sequencer)
curl -sS "$BASE_URL/api/v1/provisioning-jobs/PROVISIONING_JOB_ID"   -H "Authorization: Bearer $GTMI_API_KEY"

Idempotent per (workspace, domain): re-POSTing the same domain resumes the in-flight job and retries a gate-blocked export once readiness opens.

Errors

Handle the API response envelope

Successful responses return success: true. Validation, auth, permission, rate-limit, and server errors return success: falsewith a stable code and human-readable message.

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Missing or invalid 'workspaceId' field",
    "details": {}
  }
}

See the API reference for endpoint-level schemas, pagination, rate-limit headers, and all permission scopes.

When a readiness, seed-placement, launch-gate, or export request fails, keep the redacted error.message, readiness reason, and nextAction in customer-facing notes. Do not paste provider payloads, SMTP credentials, encrypted values, password hashes, API keys, or webhook secrets into support tickets or agent prompts.