# REST API Overview

> Programmatic access to graph8 CRM, enrichment, and prospecting data

Source: https://docs.graph8.com/developers/

> **Tip: New to graph8?**
> Start with the [Getting Started](https://docs.graph8.com/developers/getting-started/) guide to choose the right integration path (SDK, MCP, CLI, or REST API).

> **Tip:**
> Try the developer tier free - 1,000 credits, no card required. [Get started](https://auth.graph8.com/en/signup).
>
> AI agents: fetch the full doc index at [https://docs.graph8.com/llms.txt](https://docs.graph8.com/llms.txt).

The REST API gives you direct HTTP access to contacts, companies, lists, enrichment, search, sequences, webhooks, deals, tasks, notes, fields, quotes, pipelines, workflows, skills, voice, intent, studio, and more. Any language, any platform.

## Quick Reference

- **Base URL:** `https://be.graph8.com/api/v1`
- **Auth:** `Authorization: Bearer YOUR_API_KEY` ([details](https://docs.graph8.com/developers/authentication/))
- **Format:** JSON request/response
- **Rate limit:** 50 req/s + 1,000 req/min per org ([details](https://docs.graph8.com/developers/rate-limits/))
- **Docs:** [Interactive Swagger →](https://be.graph8.com/api/v1/docs)

## 30-second start

If you can paste a curl, you can start integrating:

**cURL**

```bash
# Will return your stored contacts (or [] if none yet)
curl 'https://be.graph8.com/api/v1/contacts?limit=3' \
  -H "Authorization: Bearer $G8_API_KEY"
```

**TypeScript (SDK)**

```typescript
import { g8 } from '@graph8/sdk';
g8.init({ apiKey: process.env.G8_API_KEY! });

const { data } = await g8.contacts.list({ limit: 3 });
```

**Python**

```python
import httpx, os
r = httpx.get(
    "https://be.graph8.com/api/v1/contacts",
    params={"limit": 3},
    headers={"Authorization": f"Bearer {os.environ['G8_API_KEY']}"},
)
print(r.json())
```

**CLI**

```bash
g8 login
g8 search-contacts --limit 3
```

**MCP**

Configure your AI client per [MCP setup](https://docs.graph8.com/developers/mcp/), then ask:
*"Show me my last 3 contacts."* → calls `g8_search_contacts`.

[Don't have an API key? Get one in 30 seconds →](https://docs.graph8.com/developers/authentication/)

## API Surfaces

graph8 exposes two distinct HTTP surfaces. **Only `/api/v1/*` is for developers** — everything else is internal.

| Surface | Mount | Auth | Use case |
|---|---|---|---|
| **Developer API** | `https://be.graph8.com/api/v1/*` | `Authorization: Bearer` (API key) | What every doc on this site refers to — SDK, CLI, and MCP server all proxy this surface |
| **Internal Studio** | `/v1/*` and `/campaign-builder/*` | PropelAuth session cookie | First-party UI in `app.graph8.com` — not for integrations |
| **Public (write-key)** | `/api/v1/public/*` | Write key (browser-safe) | Visitor tracking, public-form enrich, copilot chat ([details](https://docs.graph8.com/developers/public-endpoints/)) |
| **Intent-search** | `/intent-search/*` (no `/api/v1` prefix) | `Authorization: Bearer` (API key) | The one outlier — see [Intent](https://docs.graph8.com/developers/intent-signals/#account-level-intent-search) |

Stick to `/api/v1/*` unless a doc explicitly tells you otherwise.

**Contacts**

    List, create, update, and delete contacts in your workspace.
    [View reference →](https://docs.graph8.com/developers/contacts/)

**Companies**

    List, update, and delete companies and their associated contacts.
    [View reference →](https://docs.graph8.com/developers/companies/)

**Search**

    Find contacts and companies in graph8's 700M+ / 100M+ global database.
    [View reference →](https://docs.graph8.com/developers/search/)

**Enrichment**

    Look up people and companies, run waterfall enrichment, and verify emails.
    [View reference →](https://docs.graph8.com/developers/enrichment/)

**Lists**

    Create lists, manage membership, and organize contacts for campaigns.
    [View reference →](https://docs.graph8.com/developers/lists/)

**Sequences**

    List, run, and manage automated email sequences.
    [View reference →](https://docs.graph8.com/developers/sequences/)

**CRM:** [Notes](https://docs.graph8.com/developers/notes/) | [Tasks](https://docs.graph8.com/developers/tasks/) | [Fields](https://docs.graph8.com/developers/fields/) | [Deals](https://docs.graph8.com/developers/deals/) | [Assert/Upsert](https://docs.graph8.com/developers/assert/)

**Engage:** [Sequence Lifecycle](https://docs.graph8.com/developers/sequences-lifecycle/) | [Inbox](https://docs.graph8.com/developers/inbox/) | [Meetings](https://docs.graph8.com/developers/meetings/) | [Voice & Dialer](https://docs.graph8.com/developers/voice/) | [Webhooks](https://docs.graph8.com/developers/webhooks/)

**Revenue:** [Quotes](https://docs.graph8.com/developers/quotes/) | [Stage Checklist Pipelines](https://docs.graph8.com/developers/pipelines/)

**Automation:** [Workflows](https://docs.graph8.com/developers/workflows/) | [Skills](https://docs.graph8.com/developers/skills/) | [Landing Pages](https://docs.graph8.com/developers/landing-pages/)

**Intelligence:** [Intent & Signals](https://docs.graph8.com/developers/intent-signals/) | [GTM Campaigns](https://docs.graph8.com/developers/gtm-campaigns/) | [GTM Context](https://docs.graph8.com/developers/gtm-context/)

**Sync:** [Audience Syncs](https://docs.graph8.com/developers/audience-syncs/) | [CRM Syncs](https://docs.graph8.com/developers/crm-syncs/)

**Public (browser, write key):** [Public Endpoints](https://docs.graph8.com/developers/public-endpoints/)

**Reference:** [Pricing](https://docs.graph8.com/developers/pricing/) | [Pagination](https://docs.graph8.com/developers/pagination/) | [Errors](https://docs.graph8.com/developers/errors/) | [Rate Limits](https://docs.graph8.com/developers/rate-limits/) | [REST API FAQ](https://docs.graph8.com/developers/api-faq/)

---

The graph8 Developer API lets you programmatically discover new prospects, manage your CRM data, and enrich contact information - all through a single REST API.

## Events, webhooks & real-time

Subscribe to **40+ event types** and graph8 will `POST` a signed JSON payload to your endpoint as things happen — no polling required.

| Category | Example events |
|---|---|
| Campaigns | `campaign.launched`, `campaign.completed`, `campaign.status_changed` |
| Documents & intelligence | `document.generated`, `intelligence.completed`, `research.completed` |
| Enrichment | `company.enriched`, `person.enriched`, `company_intelligence.completed` |
| Sequences & engagement | `sequence.draft_created`, `sequence.started`, `engagement.email_replied`, … |
| Meetings | `meeting.booked`, `meeting.cancelled`, `meeting.rescheduled` |

- **Signed** — every delivery carries an `X-Studio-Signature` (HMAC-SHA256 over `{X-Studio-Timestamp}.{raw_body}`); verify before processing.
- **Reliable** — failed deliveries retry up to 3× with backoff (10s → 60s → 300s); inspect attempts via `GET /webhooks/{id}/deliveries`.
- **Delivery model** — graph8 uses **webhook push + REST poll** (no SSE/WebSocket today). Full [Webhooks reference →](https://docs.graph8.com/developers/webhooks/).

## Rate limits & errors at a glance

**Rate limits** — `50 req/s` + `1,000 req/min` per org. Every response (success *and* `429`) carries your quota so you can self-pace:

| Header | Meaning |
|---|---|
| `X-RateLimit-Limit-Second` / `-Minute` | The ceilings (`50` / `1000`) |
| `X-RateLimit-Remaining` | Requests left in the current minute window |
| `X-RateLimit-Reset` | Unix epoch when the window frees a slot |
| `Retry-After` | Seconds to wait (sent on `429`) |

Full details + backoff code: [Rate Limits →](https://docs.graph8.com/developers/rate-limits/).

**Errors** — standard HTTP status codes with a JSON `{ "detail": "..." }` body (validation errors return a field-level `detail` array):

| Code | Meaning |
|---|---|
| `400` / `422` | Bad request / validation failure |
| `401` | Missing or invalid API key (JWTs are rejected) |
| `404` | Resource not found |
| `429` | Rate limit exceeded |
| `5xx` | Server error — retry with backoff |

Full catalog + handling examples: [Errors →](https://docs.graph8.com/developers/errors/).

## How Data Works in graph8

graph8 gives you access to **two distinct pools of data**. Understanding the difference is the key to using the API effectively.

### Your data (first-party)

This is data **you own** — contacts and companies that live in your graph8 workspace. They got there through one of these paths:

- You **saved search results** from the open data index (via [`/search/contacts/save`](https://docs.graph8.com/developers/search/#save-contacts-to-list))
- You **imported** contacts from a CSV or CRM integration
- You **created** them manually via the API (via [`POST /contacts`](https://docs.graph8.com/developers/contacts/#create-contact))
- They were **auto-created** during enrichment or campaign workflows

You have full read/write access to your data. Query it, update it, delete it, organize it into lists — no credit cost.

**Endpoints**: [`/contacts`](https://docs.graph8.com/developers/contacts/), [`/companies`](https://docs.graph8.com/developers/companies/), [`/lists`](https://docs.graph8.com/developers/lists/)

### Open data index

This is graph8's **global B2B database** — millions of contacts and companies aggregated from multiple data providers. Think of it as a phonebook for the business world: names, titles, emails, phone numbers, company details, and more.

You can **search** this index with filters (job title, industry, company size, location, etc.) and **save** matching results into your workspace. Once saved, they become your data.

You can also **look up** a single person or company by email, LinkedIn URL, or domain.

Open data queries consume credits.

**Endpoints**: [`/search/contacts`](https://docs.graph8.com/developers/search/), [`/search/companies`](https://docs.graph8.com/developers/search/#search-companies), [`/enrichment/lookup`](https://docs.graph8.com/developers/enrichment/)

### The data flow

The typical workflow moves data from open → owned:

```
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   1. DISCOVER            2. SAVE              3. MANAGE         │
│                                                                 │
│   /search/contacts  ──►  /search/.../save  ──►  /contacts      │
│   /search/companies      (creates a list)       /companies      │
│   /enrichment/lookup                            /lists          │
│                                                                 │
│   Open data index        Moves into your        Full CRUD on    │
│   (read-only, credits)   workspace as a list    your data (free)│
│                                                                 │
│                          4. ENRICH                              │
│                          /enrichment/enrich                     │
│                          Fill missing fields                    │
│                          on your saved contacts                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

## Choosing the Right Endpoint

| I want to... | Use | PAYG | Platform |
|--------------|-----|------|----------|
| Find new contacts matching my ICP | [`POST /search/contacts`](https://docs.graph8.com/developers/search/) | 1 per record returned | **Free** (within 50 rps) |
| Find new companies by industry, size, etc. | [`POST /search/companies`](https://docs.graph8.com/developers/search/#search-companies) | 1 per record returned | **Free** (within 50 rps) |
| Save search results to my workspace | [`POST /search/contacts/save`](https://docs.graph8.com/developers/search/#save-contacts-to-list) | 1 per record saved | **Free** (within 50 rps) |
| Look up one person by email or LinkedIn | [`POST /enrichment/lookup/person`](https://docs.graph8.com/developers/enrichment/) | 2 per lookup | **Free** (within 50 rps) |
| Look up one company by domain | [`POST /enrichment/lookup/company`](https://docs.graph8.com/developers/enrichment/#company-lookup) | 2 per lookup | **Free** (within 50 rps) |
| List contacts I've already saved | [`GET /contacts`](https://docs.graph8.com/developers/contacts/) | Free | Free |
| List companies in my workspace | [`GET /companies`](https://docs.graph8.com/developers/companies/) | Free | Free |
| Manage my lists | [`GET /lists`](https://docs.graph8.com/developers/lists/) | Free | Free |
| Fill missing emails/phones on my contacts (waterfall) | [`POST /enrichment/enrich`](https://docs.graph8.com/developers/enrichment/#start-enrichment-job) | Variable per contact | Variable per contact |
| Verify an email address (internal validator) | [`POST /enrichment/verify-email`](https://docs.graph8.com/developers/enrichment/#verify-email) | 1 per email | **Free** (within 50 rps) |

See [Pricing](https://docs.graph8.com/developers/pricing/) for the full bucket map and plan comparison.

## Base URL

```
https://be.graph8.com/api/v1
```

All endpoints are relative to this base URL. For example, to list contacts:

```
GET https://be.graph8.com/api/v1/contacts
```

## Quick Start

**cURL**

```bash
export API_KEY="YOUR_API_KEY"

# 1. Search the open data index for CTOs at tech companies
curl -X POST "https://be.graph8.com/api/v1/search/contacts" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      {"field": "job_title", "operator": "any_of", "value": ["CTO", "VP Engineering"]},
      {"field": "company_employee_count", "operator": "between", "value": [50, 500]}
    ],
    "limit": 5
  }'

# 2. Save matching contacts to a list in your workspace
curl -X POST "https://be.graph8.com/api/v1/search/contacts/save" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      {"field": "job_title", "operator": "any_of", "value": ["CTO", "VP Engineering"]},
      {"field": "company_employee_count", "operator": "between", "value": [50, 500]}
    ],
    "list_title": "Tech CTOs"
  }'

# 3. Query your saved contacts (free, no credits)
curl "https://be.graph8.com/api/v1/contacts?list_id=42&limit=10" \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://be.graph8.com/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. Search the open data index for CTOs at tech companies
results = requests.post(
    f"{BASE_URL}/search/contacts",
    headers=HEADERS,
    json={
        "filters": [
            {"field": "job_title", "operator": "any_of", "value": ["CTO", "VP Engineering"]},
            {"field": "company_employee_count", "operator": "between", "value": [50, 500]}
        ],
        "limit": 5
    }
).json()

print(f"Found {results['pagination']['total']} matches")

# 2. Save matching contacts to a list in your workspace
save = requests.post(
    f"{BASE_URL}/search/contacts/save",
    headers=HEADERS,
    json={
        "filters": [
            {"field": "job_title", "operator": "any_of", "value": ["CTO", "VP Engineering"]},
            {"field": "company_employee_count", "operator": "between", "value": [50, 500]}
        ],
        "list_title": "Tech CTOs"
    }
).json()

list_id = save["data"]["list_id"]

# 3. Query your saved contacts (free, no credits)
contacts = requests.get(
    f"{BASE_URL}/contacts",
    headers=HEADERS,
    params={"list_id": list_id, "limit": 10}
).json()

for c in contacts["data"]:
    print(f"{c['first_name']} {c['last_name']} - {c['work_email']}")
```

**TypeScript**

```typescript
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://be.graph8.com/api/v1";
const headers = { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" };

// 1. Search the open data index for CTOs at tech companies
const results = await fetch(`${BASE_URL}/search/contacts`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    filters: [
      { field: "job_title", operator: "any_of", value: ["CTO", "VP Engineering"] },
      { field: "company_employee_count", operator: "between", value: [50, 500] }
    ],
    limit: 5
  }),
}).then(r => r.json());

console.log(`Found ${results.pagination.total} matches`);

// 2. Save matching contacts to a list in your workspace
const save = await fetch(`${BASE_URL}/search/contacts/save`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    filters: [
      { field: "job_title", operator: "any_of", value: ["CTO", "VP Engineering"] },
      { field: "company_employee_count", operator: "between", value: [50, 500] }
    ],
    list_title: "Tech CTOs"
  }),
}).then(r => r.json());

// 3. Query your saved contacts (free, no credits)
const contacts = await fetch(
  `${BASE_URL}/contacts?list_id=${save.data.list_id}&limit=10`,
  { headers: { Authorization: `Bearer ${API_KEY}` } }
).then(r => r.json());

contacts.data.forEach(c =>
  console.log(`${c.first_name} ${c.last_name} - ${c.work_email}`)
);
```

## Endpoint Reference

### Discover (open data — credits)

**Search**

    Find contacts and companies in graph8's global B2B database using filters like job title, industry, company size, and location.
    [View reference](https://docs.graph8.com/developers/search/)

**Enrichment**

    Look up a single person or company, run waterfall enrichment across providers, and verify email deliverability.
    [View reference](https://docs.graph8.com/developers/enrichment/)

### Manage (your data — free)

**Contacts**

    List, create, update, and delete contacts in your workspace.
    [View reference](https://docs.graph8.com/developers/contacts/)

**Companies**

    List, update, and delete companies and their associated contacts.
    [View reference](https://docs.graph8.com/developers/companies/)

**Lists**

    Create lists, manage list membership, and organize contacts for campaigns.
    [View reference](https://docs.graph8.com/developers/lists/)

### Reference

**Pricing**

    Plans, credit costs, the unlimited-API bundle, and auto-CRM-capture behavior.
    [View pricing](https://docs.graph8.com/developers/pricing/)

**Authentication**

    Create API keys and authenticate your requests.
    [Get started](https://docs.graph8.com/developers/authentication/)

**Pagination**

    Response envelope and pagination patterns.
    [Learn more](https://docs.graph8.com/developers/pagination/)

**Errors**

    Error codes and handling strategies.
    [Learn more](https://docs.graph8.com/developers/errors/)

**Rate Limits**

    Request limits and backoff strategies.
    [Learn more](https://docs.graph8.com/developers/rate-limits/)

## Interactive API Reference

For a live, interactive view of all endpoints with request/response schemas, visit the OpenAPI docs:

**[Open Interactive API Docs →](https://be.graph8.com/api/v1/docs)**

You can test endpoints directly from the browser — authenticate with your API key and execute requests in real time.

## Response Format

All responses use a standard envelope:

```json
{
  "data": { ... },
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 243,
    "has_next": true
  }
}
```

Single-resource responses include `data` without `pagination`. See [Pagination](https://docs.graph8.com/developers/pagination/) for details.
