# CLI Campaigns

> List, create, update, and launch repo-scoped campaigns via the graph8 Developer API

Source: https://docs.graph8.com/developers/cli-campaigns/

> **Tip: Repo-scoped campaigns**
> These endpoints operate on campaigns that belong to a specific repository (repo). All paths are prefixed with `/repos/{repo_id}/campaigns`. For organisation-wide GTM campaigns, see the [GTM Campaigns](https://docs.graph8.com/developers/gtm-campaigns/) page.

Manage campaigns that live inside a graph8 repository. You can list summaries, retrieve full detail (including all documents), fetch a single campaign document, create a new campaign, apply partial updates, and launch a campaign — all scoped to a `repo_id`.

---

## List Campaigns

`GET /repos/{repo_id}/campaigns`

Returns a paginated array of campaign summaries for the given repository.

### Path Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `repo_id` | string | The repository ID |

### Query Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `page` | integer | `1` | Page number (1-indexed) |
| `limit` | integer | `50` | Items per page |

### Example

**cURL**

```bash
curl "https://be.graph8.com/api/v1/repos/repo_abc123/campaigns?page=1&limit=50" \
  -H "Authorization: Bearer $API_KEY"
```

### Response

```json
[
  {
    "id": "camp_001",
    "name": "Q3 Outbound Push",
    "category": "Outbound",
    "brief": "Drive pipeline for the Q3 push.",
    "core_concept": "Land-and-expand via champions",
    "primary_hook": "Cut your CAC by 40%",
    "target_persona": "VP Sales at Series B SaaS",
    "goal": "50 meetings booked"
  }
]
```

---

## Get Campaign

`GET /repos/{repo_id}/campaigns/{campaign_id}`

Returns full campaign detail, including all associated documents.

### Path Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `repo_id` | string | The repository ID |
| `campaign_id` | string | The campaign ID |

### Example

**cURL**

```bash
curl "https://be.graph8.com/api/v1/repos/repo_abc123/campaigns/camp_001" \
  -H "Authorization: Bearer $API_KEY"
```

### Response

```json
{
  "id": "camp_001",
  "name": "Q3 Outbound Push",
  "category": "Outbound",
  "brief": "Drive pipeline for the Q3 push.",
  "core_concept": "Land-and-expand via champions",
  "primary_hook": "Cut your CAC by 40%",
  "target_persona": "VP Sales at Series B SaaS",
  "goal": "50 meetings booked",
  "documents": [
    {
      "id": "doc_001",
      "title": "Outreach Sequence",
      "content": "..."
    }
  ]
}
```

---

## Get Campaign Document

`GET /repos/{repo_id}/campaigns/{campaign_id}/documents/{document_id}`

Returns a single campaign document with its full content.

### Path Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `repo_id` | string | The repository ID |
| `campaign_id` | string | The campaign ID |
| `document_id` | string | The document ID |

### Example

**cURL**

```bash
curl "https://be.graph8.com/api/v1/repos/repo_abc123/campaigns/camp_001/documents/doc_001" \
  -H "Authorization: Bearer $API_KEY"
```

### Response

```json
{
  "id": "doc_001",
  "title": "Outreach Sequence",
  "content": "Full document content here..."
}
```

---

## Create Campaign

`POST /repos/{repo_id}/campaigns`

Create a new campaign in the given repository.

### Path Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `repo_id` | string | The repository ID |

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | **Yes** | Campaign name |
| `category` | string | No | Campaign category (default: `"Outbound"`) |
| `brief` | string | No | Short campaign brief |
| `core_concept` | string | No | Core strategic concept |
| `primary_hook` | string | No | The primary hook or value proposition |
| `target_persona` | string | No | Description of the target persona |
| `goal` | string | No | Campaign goal or success metric |

### Example

**cURL**

```bash
curl -X POST "https://be.graph8.com/api/v1/repos/repo_abc123/campaigns" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q3 Outbound Push",
    "category": "Outbound",
    "brief": "Drive pipeline for the Q3 push.",
    "core_concept": "Land-and-expand via champions",
    "primary_hook": "Cut your CAC by 40%",
    "target_persona": "VP Sales at Series B SaaS",
    "goal": "50 meetings booked"
  }'
```

### Response

```json
{
  "id": "camp_001",
  "name": "Q3 Outbound Push",
  "category": "Outbound",
  "brief": "Drive pipeline for the Q3 push.",
  "core_concept": "Land-and-expand via champions",
  "primary_hook": "Cut your CAC by 40%",
  "target_persona": "VP Sales at Series B SaaS",
  "goal": "50 meetings booked"
}
```

---

## Update Campaign

`PATCH /repos/{repo_id}/campaigns/{campaign_id}`

Partially update a campaign. Only include the fields you want to change. Uses the same partial-update body as `PATCH /campaigns/{id}` on the GTM surface.

### Path Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `repo_id` | string | The repository ID |
| `campaign_id` | string | The campaign ID |

### Request Body

All fields are optional. Include only the fields to update.

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Campaign name |
| `category` | string | Campaign category |
| `brief` | string | Short campaign brief |
| `core_concept` | string | Core strategic concept |
| `primary_hook` | string | The primary hook or value proposition |
| `target_persona` | string | Description of the target persona |
| `goal` | string | Campaign goal or success metric |

### Example

**cURL**

```bash
curl -X PATCH "https://be.graph8.com/api/v1/repos/repo_abc123/campaigns/camp_001" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "primary_hook": "Reduce churn by 25%",
    "goal": "60 meetings booked"
  }'
```

### Response

```json
{
  "id": "camp_001",
  "name": "Q3 Outbound Push",
  "primary_hook": "Reduce churn by 25%",
  "goal": "60 meetings booked"
}
```

---

## Launch Campaign

`POST /repos/{repo_id}/campaigns/{campaign_id}/launch`

Launch a campaign. No request body is required. The route applies the same
mandatory audience, content, sender, and executable-step checks as
`POST /campaigns/{id}/launch`, then delegates to the canonical Sequencer V2
workflow. Restricted API keys require the fail-closed `campaigns:launch` scope;
legacy keys created without scope restrictions remain unrestricted.

### Path Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `repo_id` | string | The repository ID |
| `campaign_id` | string | The campaign ID |

### Example

**cURL**

```bash
curl -X POST "https://be.graph8.com/api/v1/repos/repo_abc123/campaigns/camp_001/launch" \
  -H "Authorization: Bearer $API_KEY"
```

### Response

```json
{
  "data": {
    "status": "scheduling",
    "campaign_id": "camp_001",
    "sequence_id": "seq_001",
    "execution": {
      "status": "scheduling",
      "job_id": "job_001",
      "polling_url": "/sequencer/sequences/jobs/job_001/status"
    }
  }
}
```

The actual status is `live` after synchronous initialization or `scheduling`
while background initialization is in progress. A partial activation failure
returns `502` with the created `sequence_id`, confirmed sequence state when
available, and a safe recovery instruction.
