# Create a campaign

`POST https://api.tryscouty.com/v1/campaigns`

Creates a draft campaign for this brand. A draft is not live and nothing is sent to anybody: use scouty_request_publish when it is ready and the team will review it.

- Scope: `campaigns:write`
- Kind: write
- Safe to retry with the same idempotency key: no
- MCP tool: `scouty_create_campaign`

## Authorization

Send `Authorization: Bearer $SCOUTY_TOKEN`. The token needs the `campaigns:write` scope.

## Headers

| Name | Type | Required | Description |
|---|---|---|---|
| `Idempotency-Key` | `string` | Optional | The same key the body's idempotencyKey carries. Send one or the other, or both with the same value. |

## Body parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `idempotencyKey` | `string` | Required | A key you choose for this call, 8 to 128 characters of letters, digits, dot, underscore, colon or hyphen. Sending the same key with the same arguments replays the first answer and changes nothing, so a retry after a timeout is safe. |
| `title` | `string` | Required | The campaign's name, as creators read it. |
| `overview` | `string` | Required | A short description of what the campaign is. |
| `payLine` | `string` | Optional | What the campaign pays, in one line, exactly as a creator is shown it. |
| `deliverables` | `string[]` | Required | What a creator is asked to make. |
| `requirements` | `string[]` | Required | What a creator has to be or do to take part. |
| `marketCountryCodes` | `string[]` | Required | Two-letter country codes for the markets. An empty list reaches everywhere. |
| `applicationDeadline` | `string \| null` | Optional | The last day to apply, as YYYY-MM-DD, or null for no deadline. |

## Request

### cURL

```bash
curl -s -X POST https://api.tryscouty.com/v1/campaigns \
  -H "Authorization: Bearer $SCOUTY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"idempotencyKey":"create-acme-spring-1","title":"Acme Spring launch","overview":"Short videos showing how you use the Acme water bottle on a normal day.","payLine":"$150 per approved video, paid by Acme","deliverables":["One 30 to 60 second TikTok","One Instagram Reel"],"requirements":["18 or older","Based in the US"],"marketCountryCodes":["US"],"applicationDeadline":"2026-10-31"}'
```

### JavaScript

```js
const response = await fetch("https://api.tryscouty.com/v1/campaigns", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SCOUTY_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    idempotencyKey: "create-acme-spring-1",
    title: "Acme Spring launch",
    overview: "Short videos showing how you use the Acme water bottle on a normal day.",
    payLine: "$150 per approved video, paid by Acme",
    deliverables: [
      "One 30 to 60 second TikTok",
      "One Instagram Reel"
    ],
    requirements: [
      "18 or older",
      "Based in the US"
    ],
    marketCountryCodes: [
      "US"
    ],
    applicationDeadline: "2026-10-31"
  }),
});
console.log(await response.json());
```

### Python

```python
import os

import requests

token = os.environ["SCOUTY_TOKEN"]
response = requests.post(
    "https://api.tryscouty.com/v1/campaigns",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "idempotencyKey": "create-acme-spring-1",
        "title": "Acme Spring launch",
        "overview": "Short videos showing how you use the Acme water bottle on a normal day.",
        "payLine": "$150 per approved video, paid by Acme",
        "deliverables": ["One 30 to 60 second TikTok", "One Instagram Reel"],
        "requirements": ["18 or older", "Based in the US"],
        "marketCountryCodes": ["US"],
        "applicationDeadline": "2026-10-31",
    },
)
print(response.json())
```

## Responses

### 200 OK

```json
{
  "status": "created",
  "campaignId": 42,
  "campaignStatus": "draft",
  "note": "This campaign is a draft. Nothing has been sent to anybody."
}
```

### 400 Bad Request

```json
{
  "error": {
    "code": "invalid_request",
    "message": "Those arguments are not the shape this capability takes: idempotencyKey."
  }
}
```

### 401 Unauthorized

```json
{
  "error": {
    "code": "missing_token",
    "message": "This API needs an Authorization header carrying a bearer token."
  }
}
```

### 403 Forbidden

```json
{
  "error": {
    "code": "insufficient_scope",
    "message": "This token does not carry the campaigns:write scope. Ask the team for one that does."
  }
}
```

### 409 Conflict

```json
{
  "error": {
    "code": "idempotency_conflict",
    "message": "That idempotency key was already used for a different request. Use a new key."
  }
}
```

### 429 Too Many Requests

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Please wait for the current minute to end."
  }
}
```

## Errors

| Status | `error.code` | Meaning |
|---|---|---|
| 400 Bad Request | `invalid_request` | The request was not the shape this capability takes, or its body was not JSON. |
| 401 Unauthorized | `missing_token`, `invalid_token`, `token_revoked`, `token_expired`, `token_orphaned` | No token, or one that is not recognized, revoked or expired. |
| 403 Forbidden | `insufficient_scope`, `wrong_principal` | The token does not carry the scope this capability needs. |
| 409 Conflict | `idempotency_conflict` | That idempotency key was already used for a different request. Nothing was changed. |
| 429 Too Many Requests | `rate_limited` | Too many requests this minute. Retry-After says how long is left. |

Full reference: https://docs.tryscouty.com/reference
