Public API · v1

Programmatic
LinkedIn outreach.

REST API for OutPilot, campaigns, lead lists, leads, accounts, inbox, and outbound webhooks. X-API-KEY auth, 300 req/min, HMAC-signed deliveries.

Quickstart

From zero to first call in 60 seconds

  1. 1.

    Create a key

    Sign in → Settings → Developers → Create API key. Copy the op_live_… string. It's shown once.

  2. 2.

    Verify it works

    curl -H "X-API-KEY: op_live_..." \
      https://api.getbanyan.co/v1/auth/check

    Expect {"success":true,"data":{"valid":true,"workspaceId":N,"scopes":[]}}

  3. 3.

    Pull your data

    curl -H "X-API-KEY: op_live_..." \
      "https://api.getbanyan.co/v1/campaigns?limit=10"
Endpoints

34 endpoints across 8 surfaces

Full reference at https://api.getbanyan.co/v1/docs (Swagger UI). Or import the spec directly into Postman: https://api.getbanyan.co/v1/openapi.json.

Auth

Verify your key.

  • GET /v1/auth/check

Stats

Account-wide rollups.

  • GET /v1/stats/overview

Campaigns

List, get, pause, resume, add leads.

  • GET /v1/campaigns
  • GET /v1/campaigns/:id
  • GET /v1/campaigns/:id/leads
  • POST /v1/campaigns/:id/pause
  • POST /v1/campaigns/:id/resume
  • POST /v1/campaigns/:id/archive
  • POST /v1/campaigns/:id/unarchive
  • POST /v1/campaigns/:id/leads

Lead Lists

Create lists, add leads, read.

  • GET /v1/lead-lists
  • POST /v1/lead-lists
  • GET /v1/lead-lists/:id
  • GET /v1/lead-lists/:id/leads
  • POST /v1/lead-lists/:id/leads

Leads

Per-lead access.

  • GET /v1/leads
  • GET /v1/leads/:id
  • POST /v1/leads/:id/connect

Accounts

Connect sender accounts, resolve 2FA, read.

  • GET /v1/accounts
  • GET /v1/accounts/:id
  • POST /v1/accounts
  • POST /v1/accounts/:id/solve-checkpoint
  • POST /v1/accounts/:id/resend-checkpoint

Inbox

Read and reply to LinkedIn DMs.

  • GET /v1/inbox/conversations
  • GET /v1/inbox/conversations/:id/messages
  • POST /v1/inbox/conversations/:id/messages
  • POST /v1/inbox/conversations/:id/seen

Webhooks

Subscribe to events with HMAC-signed deliveries.

  • GET /v1/webhooks
  • POST /v1/webhooks
  • GET /v1/webhooks/:id
  • PATCH /v1/webhooks/:id
  • DELETE /v1/webhooks/:id
  • POST /v1/webhooks/:id/test
  • GET /v1/webhooks/:id/deliveries
Accounts

Connect a LinkedIn sender account

LinkedIn almost always challenges a brand-new login, so connecting is a two-step handshake: submit credentials, then submit the code LinkedIn sends. This is the same flow the OutPilot dashboard uses, with the same seat limit and connect-attempt throttle — an API key can't bypass either.

1. Submit credentials

curl -H "X-API-KEY: op_live_..." \
  -H "Content-Type: application/json" \
  -d '{"email":"you@company.com","password":"...","country":"IN"}' \
  https://api.getbanyan.co/v1/accounts

A clean login returns 201 with checkpointRequired: false — the account is ready to send. Most first-time logins instead come back with checkpointRequired: true and a checkpointType: LinkedIn wants a code.

2. Solve the checkpoint

curl -H "X-API-KEY: op_live_..." \
  -H "Content-Type: application/json" \
  -d '{"code":"482913"}' \
  https://api.getbanyan.co/v1/accounts/{'{id}'}/solve-checkpoint

Code didn't arrive? POST /v1/accounts/{id}/resend-checkpoint asks LinkedIn to send a new one (30s cooldown). A verification window that's fully expired returns CHECKPOINT_EXPIRED — call POST /v1/accounts again to start fresh.

Then, reach out

Once an account is active, send a connection request to any lead directly:

curl -H "X-API-KEY: op_live_..." \
  -H "Content-Type: application/json" \
  -d '{"note":"Enjoyed your post on GTM in India"}' \
  https://api.getbanyan.co/v1/leads/{'{id}'}/connect
Webhooks

Realtime events, signed and retried

Subscribe a URL to receive HMAC-signed POSTs whenever events happen in your account. Failed deliveries retry up to 8 times with exponential backoff (30s → ~1h).

Available events

  • lead.replied A lead in one of your campaigns replied on LinkedIn.
  • connection.accepted A campaign connection request was accepted.

Subscribe

curl -H "X-API-KEY: op_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/hooks/outpilot",
    "eventTypes": ["lead.replied", "connection.accepted"],
    "secret": "a-shared-hmac-secret-you-pick"
  }' \
  https://api.getbanyan.co/v1/webhooks

Verify a delivery

Each delivery carries an x-outpilot-signature header in the form t=<unix>,v1=<hex>. Recompute the HMAC and timing-compare:

// Node.js
import crypto from "node:crypto";

function verify(rawBody, header, secret) {
  const m = /^t=(\d+),v1=([0-9a-f]+)$/.exec(header);
  if (!m) return false;
  const [, t, v1] = m;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(v1, "hex"),
    Buffer.from(expected, "hex")
  );
}

Event payload

{
  "id": "evt_3f6a…",
  "type": "lead.replied",
  "createdAt": "2026-05-01T14:32:11.123Z",
  "data": {
    "campaign": { "id": 421, "name": "Q2 founder outreach" },
    "lead": {
      "id": 8821,
      "linkedinUrl": "https://www.linkedin.com/in/...",
      "fullName": "...", "company": "...", "jobTitle": "...",
      "emailAddress": null
    },
    "accountId": 17,
    "occurredAt": "2026-05-01T14:32:11.000Z",
    "conversationId": "...",
    "messageId": "..."
  }
}
Limits

300 req/min/key

Sliding-window rate limit. 429s return a Retry-After header in seconds. Generate multiple keys (one per service / environment) to fan out your call budget.

Errors

Predictable envelope

Every response, success or failure, has the shape {success, data, error}. Failed responses include a stable error.code like RATE_LIMITED or NOT_FOUND.

Build on OutPilot.

Get an API key and start automating in minutes.