# API, MCP & CLI

> Create and manage API keys, connect MCP tools, and set up the CLI.

Source: https://docs.graph8.com/settings/api/

Generate API keys to integrate graph8 with your tools and workflows. Connect AI assistants via MCP, or use the CLI for command-line access.

> **Note:**
> This page is for **org/admin-managed keys** in **Settings**.
>
> If you are setting up MCP or CLI for yourself as an end user, go to **Profile -> Developer** and use your **personal API key** instead. See [Authentication](https://docs.graph8.com/developers/authentication/), [MCP Server](https://docs.graph8.com/developers/mcp/), and [CLI](https://docs.graph8.com/developers/cli/).

## Personal vs Org Credentials

| Type | Where | Best for |
|------|-------|----------|
| Personal API key | Profile -> Developer | Individual user MCP or CLI setup |
| Org API key | Settings -> API (this page) | Shared integrations, backend jobs, admin-managed automation |

## Creating Keys

### Generate a New Key

1. Go to **Settings → API**
2. Click **Create API Key**
3. Name the key (e.g., "CRM Sync", "Internal Dashboard")
4. Select the permission scopes
5. Click **Generate**
6. Copy the key immediately — it won't be shown again

### Permission Scopes

Each key can be limited to specific API areas:

- **Contacts** — read/write contact records
- **Companies** — read/write company records
- **Lists** — read/write lists and audiences
- **Pipeline** — read/write deals and stages
- **Sequences** — read/write sequences and enrollment
- **Analytics** — read analytics data
- **Full Access** — unrestricted access to all endpoints

Grant only the scopes your integration needs.

## Key Management

### Viewing Keys

The API settings page shows all active keys with:

- **Name** — the label you assigned
- **Scopes** — which API areas the key can access
- **Created** — when the key was generated
- **Last Used** — the most recent API call using this key

### Rotating a Key

To replace a key without downtime:

1. Create a new key with the same scopes
2. Update your integration to use the new key
3. Verify the integration works
4. Revoke the old key

### Revoking a Key

1. Find the key in the list
2. Click **Revoke**
3. Confirm

Revoked keys stop working immediately. Any integration using the key will receive authentication errors.

## Rate Limits

API requests are rate-limited per key and plan:

| Plan | Requests/Minute | Requests/Day |
|------|-----------------|--------------|
| Starter | 60 | 10,000 |
| Pro | 120 | 50,000 |
| Enterprise | 300 | Unlimited |

When you exceed the limit, the API returns a `429 Too Many Requests` response with a `Retry-After` header.

## Authentication

Include your API key in the request header:

```
Authorization: Bearer your-api-key-here
```

All API requests must be made over HTTPS.

### Example Request

```bash
curl -H "Authorization: Bearer your-api-key-here" \
     -H "Content-Type: application/json" \
     https://be.graph8.com/v1/contacts
```

## Webhooks

Receive real-time notifications when events happen in graph8.

### Setting Up Webhooks

1. Go to **Settings → API → Webhooks**
2. Click **Add Webhook**
3. Enter your endpoint URL (must be HTTPS)
4. Select the event types to subscribe to
5. Save

### Event Types

- **contact.created** — a new contact is added
- **contact.updated** — a contact record is modified
- **deal.stage_changed** — a deal moves to a new stage
- **deal.won** / **deal.lost** — a deal is closed
- **sequence.completed** — a contact finishes a sequence
- **meeting.booked** — an appointment is scheduled

### Retry Policy

If your endpoint returns a non-2xx response, graph8 retries:

- 3 retry attempts
- Exponential backoff (1 min, 5 min, 30 min)
- After 3 failures, the webhook is paused and you're notified

### Webhook Security

Each webhook includes a signature header for verification. Use the signing secret (shown during webhook creation) to verify that requests come from graph8.

## MCP Server

The graph8 MCP (Model Context Protocol) server lets AI assistants like Claude Desktop, Cursor, Windsurf, and Claude Code interact with your graph8 data directly.

### Modes

graph8 MCP runs in two modes depending on your workflow:

- **Developer Mode** — for developers building products. Includes repo scanning, GTM infrastructure install, campaign generation, and knowledge base search. All tools require a `repo_id`.
- **GTM Mode** — for campaign managers and marketers. Browse campaigns, edit copy, search the knowledge base, enrich contacts, and launch outreach — no `repo_id` needed.

### Remote (Streamable HTTP)

Clients that support remote MCP endpoints (Cursor, Claude Code, Windsurf) can connect directly. Authentication is handled via OAuth — no API key required in the config.

```json
{
  "mcpServers": {
    "graph8": {
      "url": "https://be.graph8.com/mcp/"
    }
  }
}
```

Your client will prompt you to sign in via OAuth when you first connect.

### Local (stdio)

For clients that require a local process (Claude Desktop), install the MCP server and provide your API key:

```bash
pip install g8-mcp-server
```

**Developer Mode:**

```json
{
  "mcpServers": {
    "graph8": {
      "command": "uvx",
      "args": ["g8-mcp-server"],
      "env": {
        "G8_API_KEY": "your-api-key-here",
        "G8_MCP_MODE": "dev"
      }
    }
  }
}
```

**GTM Mode:**

```json
{
  "mcpServers": {
    "graph8": {
      "command": "uvx",
      "args": ["g8-mcp-server"],
      "env": {
        "G8_API_KEY": "your-api-key-here",
        "G8_MCP_MODE": "gtm"
      }
    }
  }
}
```

### Tool Annotations

Every MCP tool is annotated as **read-only**, **write**, or **destructive** so MCP clients (Claude Desktop, Cursor, Claude Code, etc.) can prompt the user before any non-trivial action runs.

| Annotation | Meaning | Example tools |
|------------|---------|---------------|
| **read-only** | Reads data, never modifies | `g8_list_fields`, `g8_voice_get_dialer_stats`, `g8_search_contacts` |
| **write** | Creates or updates data | `g8_create_field`, `g8_set_field_value`, `g8_voice_create_dialer_session` |
| **destructive** | Deletes or stops something | Field deletes, `g8_voice_stop_session` |

Most clients show a confirmation prompt the first time a write or destructive tool is called so you can approve the action before it touches your data.

### Available Tools

#### Shared (all modes)

| Tool | Description |
|------|-------------|
| `g8_search_contacts` | Search contacts by email, name, or list |
| `g8_get_contact` | Get full contact profile |
| `g8_search_companies` | Search companies by domain or industry |
| `g8_get_company` | Get full company profile |
| `g8_lookup_person` | Instant person lookup by email or LinkedIn |
| `g8_lookup_company` | Instant company lookup by domain |
| `g8_enrich_contacts` | Start enrichment for a batch of contacts |
| `g8_verify_email` | Verify email deliverability |
| `g8_create_sequence` | Create a new outreach sequence |
| `g8_get_sequence_preview` | Preview sequence steps before launching |
| `g8_update_sequence` | Update sequence metadata |
| `g8_update_sequence_step` | Update a single step in a sequence |
| `g8_pause_sequence` | Pause a live sequence |
| `g8_resume_sequence` | Resume a paused sequence |
| `g8_get_sequence_analytics` | Get sequence performance metrics |
| `g8_delete_sequence` | Archive a sequence (soft delete) |
| `g8_list_inbox` | List reply threads across email, SMS, LinkedIn |
| `g8_get_reply` | Get a single reply thread with messages |
| `g8_assign_reply` | Assign a reply to a team member |
| `g8_tag_reply` | Tag a reply thread |
| `g8_get_reply_draft` | Generate an AI reply draft (charges credits) |
| `g8_send_reply` | Send a reply via email, SMS, or LinkedIn |
| `g8_list_audience_syncs` | List audience sync configs |
| `g8_create_audience_sync` | Create audience sync to ad platform |
| `g8_get_audience_sync` | Get audience sync config details |
| `g8_update_audience_sync` | Update audience sync config |
| `g8_delete_audience_sync` | Delete an audience sync (soft delete) |
| `g8_trigger_audience_sync` | Manually trigger a sync run |
| `g8_get_audience_sync_runs` | View sync run history |
| `g8_get_audience_sync_errors` | View sync error logs |
| `g8_list_crm_syncs` | List connected CRM integrations |
| `g8_push_to_crm_contact` | Push contacts to a CRM |
| `g8_push_to_crm_company` | Push companies to a CRM |
| `g8_push_to_crm_list` | Push list memberships to a CRM |
| `g8_get_crm_fields` | Discover CRM field mappings |
| `g8_get_crm_status` | Check CRM connection health |
| `g8_list_fields` | Discover custom columns/fields on contacts and companies |
| `g8_create_field` | Create a new custom column on contacts or companies |
| `g8_set_field_value` | Set a custom column value on a specific contact or company |
| `g8_voice_list_dialer_sessions` | List parallel-dialer sessions and their state |
| `g8_voice_get_dialer_stats` | Read dialer analytics (dials, connections, talk time, dispositions) |
| `g8_voice_list_agents` | List voice agents available for calls |
| `g8_voice_create_dialer_session` | Create a new dialer session bound to a list |
| `g8_voice_pause_session` | Pause an active dialer session |
| `g8_voice_resume_session` | Resume a paused dialer session |
| `g8_voice_stop_session` | Stop a dialer session permanently |

#### Developer Mode

| Tool | Description |
|------|-------------|
| `g8_connect_repo` | Connect a GitHub/GitLab repository |
| `g8_scan_repo` | Record the tech stack and GTM readiness you read from the code |
| `g8_get_scan_results` | Get scan results for a repo |
| `g8_status` | Get current repo status |
| `g8_doctor` | Report the graph8-side state of a repo's GTM install |
| `g8_install_spine` | Generate GTM install patches |
| `g8_apply_install` | Apply generated patches to the codebase |
| `g8_list_campaigns` | List campaigns for a repo |
| `g8_get_campaign` | Get campaign details |
| `g8_search_kb` | Search the repo knowledge base |
| `g8_list_kb_documents` | List all KB documents |

#### GTM Mode

| Tool | Description |
|------|-------------|
| `g8_list_campaigns` | List campaigns for the organization |
| `g8_get_campaign` | Get full campaign details and documents |
| `g8_get_campaign_document` | Get document content (briefs, copy, etc.) |
| `g8_create_campaign` | Create a new campaign |
| `g8_update_campaign` | Update campaign fields |
| `g8_launch_campaign` | Launch a campaign for outreach |
| `g8_search_kb` | Search the knowledge base |
| `g8_list_kb_documents` | List all KB documents |

## CLI

The graph8 CLI provides the same MCP tools as a command-line interface. Install it alongside the MCP server:

```bash
pip install g8-mcp-server
```

Run a tool directly:

```bash
g8 status --repo-id <repo-id>
g8 scan --repo-id <repo-id>
g8 doctor --repo-id <repo-id>

# Sequence management
g8 create-sequence --name "Q2 Outbound" --steps '[...]'
g8 pause-sequence --sequence-id <id>
g8 sequence-analytics --sequence-id <id>

# Inbox
g8 inbox-list --channel email --limit 20
g8 inbox-draft --reply-id <thread-id>
g8 inbox-send --reply-id <thread-id> --channel email --body "Thanks for your reply"

# Audience & CRM sync
g8 sync-audience-list
g8 sync-audience-trigger --config-id <id>
g8 sync-crm-push --provider hubspot --records '[...]'
```

Set your API key as an environment variable:

```bash
export G8_API_KEY=your-api-key-here
```

## Frequently Asked Questions

### Can I have multiple API keys?

Yes. Create separate keys for each integration or environment (production, staging, testing).

### What happens if I lose my API key?

API keys can't be recovered after creation. Revoke the lost key and generate a new one.

### Are there SDKs available?

Check the graph8 API documentation for available client libraries and SDK references.

### Can I test webhooks locally?

Use a tunneling service to expose your local endpoint during development. Point the webhook URL to your tunnel address.

### Do I need an API key for remote MCP connections?

No. Remote MCP connections (Cursor, Claude Code, Windsurf) use OAuth for authentication. You only need an API key for local stdio mode (Claude Desktop) or direct API calls.

### Which MCP mode should I use?

Use **Developer Mode** if you're building a product and want to scan repos, install GTM infrastructure, and generate campaigns from code. Use **GTM Mode** if you're managing campaigns, writing copy, or doing outreach — it doesn't require a repository.

---

> **Tip:**
> Create separate API keys per integration so you can revoke one without affecting others.
