REST API

    API Documentation

    Pull your campaigns, replies, interested replies, booked meetings and infrastructure health straight into your CRM, your reporting stack, or your own agents. Every request is scoped to a single workspace and requires an active subscription.

    Introduction

    The Ever Outbound API gives you programmatic access to the same data shown in your dashboard. Pull your campaigns, replies, interested replies, booked meetings and infrastructure health into your CRM, your reporting stack or your own agents.

    Every request is scoped to a single workspace and requires an active subscription. All responses are JSON.

    All response examples below use fictional placeholder data.

    Base URL
    https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1

    Authentication

    Authenticate with an API key sent in the x-api-key header. Keys are created inside your dashboard under Settings, and are shown once at creation. Store the key somewhere safe. If it leaks, revoke it and issue a new one.

    shell
    curl https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/me \
      -H "x-api-key: eo_live_xxxxxxxxxxxxxxxx"

    Free sandbox key

    Want to try the API before subscribing? Create a free test key, no account or payment needed. It starts with eo_test_, lasts 30 days and works on every endpoint with sample data. Pausing or resuming a campaign is simulated, so nothing real changes. You can create up to 5 per day.

    shell
    curl -X POST https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/sandbox/keys

    Keys are bound to the workspace they were created in and stop working the moment the subscription lapses or the key is revoked. Never expose a key in browser code.

    Quickstart

    1. Sign in to your dashboard and open Settings.
    2. Under API keys, create a key for the workspace you want to read.
    3. Copy the key. It is displayed only once.
    4. Call the API with the key in the x-api-key header.
    node
    const res = await fetch("https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/campaigns", {
      headers: { "x-api-key": process.env.EVEROUTBOUND_API_KEY },
    });
    const data = await res.json();
    console.log(data);

    Errors and rate limits

    Errors return a JSON body with an error field and a matching HTTP status code.

    StatusMeaning
    400Invalid or missing parameters.
    401Missing, invalid or revoked API key.
    402The workspace does not have an active subscription.
    404Unknown endpoint or workspace.
    409Workspace is not fully provisioned yet.
    429Rate limit exceeded. Wait for the Retry-After header, then retry.
    502Upstream sending platform error. Retry shortly.

    Each key may make 120 requests per 60 seconds. Every response includes the standard RateLimit, RateLimit-Policy, RateLimit-Remaining and RateLimit-Reset headers, and a 429 response adds Retry-After in seconds. Campaign and infrastructure data refreshes on the order of minutes, so polling once every five minutes is plenty.

    Versioning and deprecation

    The Ever Outbound API is versioned in the URL path (/v1) and every response carries an API-Version header. Within v1 we only add fields and endpoints, never remove or rename them. Before any endpoint is retired, its responses carry a Deprecation header and a Sunset header (RFC 8594) at least 90 days ahead, and the change is listed here. No endpoint is currently deprecated.

    Command-line tool

    The official Ever Outbound CLI wraps every endpoint so you can script your workspace from a terminal. It needs Node 18 or newer and has no other dependencies. Output is a readable table in a terminal and JSON when piped or with --json.

    Install and use
    npm install -g everoutbound-cli
    # or from the hosted tarball:
    npm install -g https://everoutbound.io/cli/everoutbound-cli-latest.tgz
    export EO_API_KEY=eo_live_your_key
    
    eo me
    eo campaigns
    eo replies --interested --since 2026-10-01T00:00:00Z
    eo meetings --json
    eo infrastructure
    eo pause <campaign-id>    # needs a write-scope key
    eo --help

    Get workspace

    GET/v1/me

    Returns the workspace the key belongs to. Useful as a health check.

    shell
    curl https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/me -H "x-api-key: $EVEROUTBOUND_API_KEY"
    200 response
    {
      "workspace": {
        "id": "00000000-0000-4000-8000-000000000000",
        "name": "Example Workspace",
        "company": "Example Company",
        "email": "api-user@example.invalid",
        "status": "Active",
        "launch_date": "2026-06-02"
      }
    }

    List campaigns

    GET/v1/campaigns

    Returns your campaigns, the same list shown in your dashboard. Optional query parameter status filters by campaign status. Results are not paginated.

    Add optional since and until (ISO 8601) to make prospects_reached count only prospects first contacted in that period. Dates are applied as whole UTC days, both inclusive. Without them, the value is all-time. If a campaign's count can't be retrieved, its value is null.

    shell
    curl "https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/campaigns?status=active" \
      -H "x-api-key: $EVEROUTBOUND_API_KEY"
    
    curl "https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/campaigns?since=2026-09-01T00:00:00Z&until=2026-09-30T23:59:59Z" \
      -H "x-api-key: $EVEROUTBOUND_API_KEY"
    200 response
    {
      "data": [
        {
          "id": 1234,
          "name": "Example campaign",
          "status": "active",
          "created_at": "2026-05-29T17:02:35Z",
          "updated_at": "2026-09-24T00:08:26Z",
          "total_prospects": 5000,
          "prospects_reached": 3200
        }
      ]
    }

    List replies

    GET/v1/replies

    Returns the genuine prospect replies shown in your dashboard, newest first. Out of office, auto replies, bounces and warmup mail are excluded. Each reply has a stable id and an interested flag. Interested replies are always a subset of all replies.

    statusOmit for all replies, or interested for interested replies only. Other values return 400.
    sinceISO 8601. Replies received at or after this time (UTC).
    untilISO 8601. Replies received before this time (UTC).
    pagePage number, starting at 1.
    per_page1 to 100, default 50.

    Dates filter on when the reply was received. Every response includes a pagination object with total, total_pages and has_more. To collect everything without gaps, fix a since/until window, page until has_more is false, and dedupe on id.

    shell
    curl "https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/replies?status=interested&since=2026-09-01T00:00:00Z&until=2026-10-01T00:00:00Z&page=1" \
      -H "x-api-key: $EVEROUTBOUND_API_KEY"
    200 response
    {
      "data": [
        {
          "id": "1001",
          "lead_id": 5678,
          "campaign_id": 1234,
          "prospect_name": "Sample Prospect",
          "prospect_email": "prospect@example.invalid",
          "company": "Sample Company",
          "replied_at": "2026-09-23T20:56:20Z",
          "interested": true,
          "crm_status": null
        }
      ],
      "pagination": { "page": 1, "per_page": 50, "total": 1, "total_pages": 1, "has_more": false }
    }

    List booked meetings

    GET/v1/meetings

    Returns the booked calls shown in your dashboard. Accepts since, until, page and per_page, filtered on when the call was booked.

    shell
    curl https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/meetings -H "x-api-key: $EVEROUTBOUND_API_KEY"

    Infrastructure health

    GET/v1/infrastructure

    Returns the same infrastructure health shown in your dashboard: overall health, its label, and the status of each sending domain.

    shell
    curl https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/infrastructure -H "x-api-key: $EVEROUTBOUND_API_KEY"
    200 response
    {
      "health_pct": 100,
      "label": "Excellent",
      "totals": { "domains": 2, "healthy": 2, "replace": 0, "reconnecting": 0 },
      "domains": [{ "domain": "example.info", "health": "healthy" }]
    }

    Recipes

    Sync interested replies into your CRM

    Poll /v1/replies?status=interested every few minutes with a since timestamp of your last successful run, then upsert by reply id.

    node
    const since = (await store.get("last_sync")) ?? new Date(Date.now() - 864e5).toISOString();
    const until = new Date().toISOString();
    
    for (let page = 1; ; page++) {
      const res = await fetch(
        `https://tviccnbeurbqkeeiykbs.supabase.co/functions/v1/api/v1/replies?status=interested&since=${since}&until=${until}&page=${page}`,
        { headers: { "x-api-key": process.env.EVEROUTBOUND_API_KEY } },
      );
      const { data, pagination } = await res.json();
      for (const reply of data) {
        await crm.upsertContact({ id: reply.id, email: reply.prospect_email, name: reply.prospect_name });
      }
      if (!pagination.has_more) break;
    }
    
    await store.set("last_sync", until);

    Support

    Need an endpoint that is not here? Email Team@EverOutbound.io and tell us what you are building. We add endpoints based on what clients actually ask for.