Quickstart & agent integration guide

Use the same workspace key for REST and MCP. Agents can read OpenAPI 3.1 for request and response schemas, or the complete plain-text reference for workflow instructions. API requests use https://app.pumpgtm.com/api/v1.

Check whether a lead follows your account

const base = "https://app.pumpgtm.com/api/v1";
const headers = {
  Authorization: `Bearer ${process.env.PUMP_API_KEY}`,
  "Content-Type": "application/json",
  "X-Eve-Client": process.env.PUMP_WORKSPACE_ID!,
};

const response = await fetch(base + "/x/eligibility", {
  method: "POST",
  headers,
  body: JSON.stringify({
    account: "mastra",
    leads: [{ reference: "crm-123", xUsername: "example_handle" }],
  }),
});
if (!response.ok) throw new Error(`Pump HTTP ${response.status}`);
const { results } = await response.json();
const lead = results[0];
if (lead.followsAccount === true) {
  // Offer X through Pump in your channel selector.
  // Enroll separately only when outreach is intended.
} else if (lead.followsAccount === null) {
  // Unknown: retain other channels; retry later if useful.
}

One workspace key. REST or MCP.

Use the workspace key from the Connect MCP page as Authorization: Bearer <key>. Store it in your server's secret manager. It is the same credential used for MCP; never put it in browser code, URLs, logs, prompts or vendor requests.

Call GET /api/v1/workspaces without X-Eve-Client first. A workspace key uses its own workspace by default. A Team owner key can select a returned workspace with X-Eve-Client: <workspace UUID>. A selector cannot grant access to another tenant. Use the selected workspace consistently for discovery, checks, imports and webhooks.

All API calls require a key. This guide, the OpenAPI schema and Markdown reference are public and require no session. Keep numeric X user IDs as strings to avoid loss of precision.

From an existing lead to an outreach option

1. Discover the workspace and connected sender with GET /workspaces and GET /x/accounts. Read GET /x/readiness for saved account, billing and Energy state. This snapshot does not contact X or prove delivery is possible.

2. If your lead has a known X handle, call POST /x/eligibility directly. If you also need the numeric ID for import, call POST /x/users/resolve. Email-only leads require your own verified email-to-X enrichment provider; Pump does not currently offer complete email-to-X matching.

3. Inspect followsAccount: true means the lead follows your selected account; false is a verified negative from a direct handle relationship check; null means unknown. Missing IDs in a public follower snapshot remain unknown. Check checkedAt for freshness. A lead following you is different from your account following them.

4. Offer X through Pump only when your workflow's channel policy allows it. The eligibility call never enrolls or sends. A positive follower result is not a guarantee that the recipient can receive a DM.

5. When you intend outreach, discover an existing Play with GET /x/plays, check its reviewApiEnabled flag, and look up candidates. Import any missing numeric identities, then fetch current Play/sequence revisions and explicitly enroll selected candidate IDs. Enrollment into an active eligible sequence may send on its next engine run.

6. Track lead status and activity, receive signed webhooks, and stop the lead when needed. Reply handling already freezes automated follow-ups. X reply sending and sequence/Play authoring are outside this core release; use the product and X to manage them.

Import safely, then enroll deliberately

POST /plays/{id}/import stages 1โ€“100 unique numeric X identities as review candidates. requestId is required (8โ€“120 letters, digits, periods, underscores, colons or hyphens; first character alphanumeric). Scope it to one logical import. Retry an identical request after a timeout; changing its payload or revision with the same requestId returns 409. The transaction commits the whole import or nothing.

Use the returned candidate IDs, or POST /plays/{id}/candidates/lookup, to avoid duplicates. Existing candidates keep their review state. Import names are caller-provided labels; import never asserts that a lead follows you. Resolve a public handle first if you do not have the numeric ID.

Read GET /plays/{id}/candidates to get the latest Play revision and selected sequence revision. POST /plays/{id}/enroll requires both plus candidateIds. Repeated completed good-fit reviews return already_reviewed. Existing enrolled, stopped or replied lead records are preserved; they are not moved to another sequence or reactivated.

Only Plays explicitly enabled for the review API support these operations. Check reviewApiEnabled on /x/plays. Imports require manual review, not autopilot. Sequence state and approvals stay unchanged. A paused sequence stays paused; enrollment alone does not guarantee a send.

Events your agent can act on

Subscribe with POST /webhooks. For X workflows, use reply.received, lead.messaged and x.followed. x.followed represents an inbound follow of your connected account. Successful X DMs emit lead.messaged with channel: x. X replies have no generated draft; encrypted message text can be unavailable.

Save the signing secret from the creation response; it is shown once. Each delivery contains { id, event, createdAt, data }. Validate X-PumpGTM-Signature using HMAC-SHA256 of timestamp + '.' + the exact raw request body. Reject signatures older than five minutes and deduplicate id. X-PumpGTM-Delivery also carries this event ID.

Delivery is best-effort: up to three attempts for network errors, HTTP 429 or 5xx. Other non-2xx responses end delivery; redirects are not followed. There is no durable replay queue or event history endpoint in this release. Poll lead state and activity to reconcile missed events. A test returning 202 means scheduled, not delivered.

Receivers must use HTTPS on port 443 and a public IPv4 DNS address. Private or mixed public/private addresses, URL credentials, fragments, IP literals and redirects are rejected. Return 2xx quickly and do long-running work in your own queue. Registration is not idempotent; list subscriptions before retrying an uncertain creation.

import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody must be the exact bytes received, BEFORE JSON parsing.
export function verify(rawBody: Buffer, header: string, secret: string) {
  const match = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(header);
  if (!match) return false;
  const timestamp = Number(match[1]);
  if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
  const expected = createHmac("sha256", secret)
    .update(match[1] + ".").update(rawBody).digest();
  return timingSafeEqual(expected, Buffer.from(match[2], "hex"));
}
// Verify X-PumpGTM-Signature, then parse the JSON.
// Persist event.id to deduplicate; enqueue work and return 2xx quickly.

Handle uncertainty and retries

401: check or rotate the workspace key. 403: check workspace access or X channel availability. 404: the resource is not accessible in this workspace, or the Play has not enabled review APIs. 409: fetch current state, inspect the conflict, then decide whether a new request is appropriate. Do not blindly change the request ID and repeat a mutation.

On 429, respect Retry-After when provided. Retry read-only calls on transient 5xx with exponential backoff and jitter. Follower checks can return HTTP 200 with individual null results when a provider is unavailable: always inspect each result. Identity resolution returns 503 and status unknown when it cannot verify a profile.

Pagination uses nextCursor: pass it as after, then stop when null. Candidate and enrolled-lead pages support at most 200 rows. Eligibility supports at most 100 inputs, but small batches avoid the bounded execution deadline. The API does not offer a bulk asynchronous job in this release.

POST /x/leads/{id}/stop halts future automation across this lead's sequence lanes. It preserves history, does not permanently suppress the person, and cannot recall actions already dispatched. automationStopped on status means the sequence is done or stopped; it does not identify the reason.

Usage and costs

The key itself is not a separate X credential. Customer costs follow your PumpGTM plan and Energy rules. Read /x/readiness for the current balance and billing state; it is not a quote or reservation for future work.

Known identities supplied through this import API are customer-provided leads, like uploads, and do not count as paid audience discovery. Public identity and relationship reads use Pump's TwitterAPI.io integration and are metered in the provider ledger. This reference does not promise those upstream reads are free or set a new per-request retail price; confirm your commercial allowance with Pump.

Sending still uses the existing X execution engine, its connected account, Energy checks and dispatch limits. Eligibility does not reserve Energy or activate a campaign. No official-X read fallback is used when the public-data provider is unavailable.