Campaigns
List existing campaigns or create a new one. Campaigns auto-generate UTM tracking links for each selected channel. Results are cursor-paginated.
GET
/api/v1/sites/:siteId/campaignsList campaigns
Returns all campaigns for a site with click and session totals, channel breakdown, and a 30-day click sparkline. Results are cursor-paginated.
Paginated — supports
cursor and limitRequest
bash
curl -X GET \
'https://letoseo.com/api/v1/sites/:siteId/campaigns' \
-H 'Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'Path parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
siteId | uuid | required | The site UUID. | — |
Query parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
status | "draft" | "active" | "paused" | "completed" | optional | Filter campaigns by lifecycle status. | — |
cursor | string | optional | Opaque pagination cursor from a previous response. | — |
limit | integer | optional | Number of items per page. Min 1, max 100. | 25 |
Responses
200Paginated list of campaigns.
json
{
"data": {
"items": [
{
"id": "00000000-0000-0000-0000-000000000010",
"name": "Acme Q1 Launch",
"slug": "acme-q1-launch",
"status": "active",
"description": "Q1 product launch campaign.",
"destination_url": "https://acme-demo.example/launch",
"starts_at": "2025-01-06T00:00:00.000Z",
"ends_at": "2025-03-31T23:59:59.000Z",
"created_at": "2025-01-05T12:00:00.000Z",
"total_clicks": 342,
"total_sessions": 187,
"channels": [
"organic",
"email",
"social"
],
"sparkline": [
{
"date": "2025-01-14",
"value": 28
},
{
"date": "2025-01-15",
"value": 34
}
]
}
],
"total_count": 1
},
"_meta": {
"generated_at": "2025-01-15T10:30:00.000Z",
"site_id": "00000000-0000-0000-0000-000000000001"
}
}404Site not found.
json
{
"error": "Site not found"
}POST
/api/v1/sites/:siteId/campaignsCreate a campaign
Creates a new campaign and auto-generates UTM tracking links for each selected channel. destination_url must be HTTPS and must not already contain UTM parameters. Returns the created campaign row at 201.
Request
bash
curl -X POST \
'https://letoseo.com/api/v1/sites/:siteId/campaigns' \
-H 'Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{
"name": "Acme Q1 Launch",
"destination_url": "https://acme-demo.example/launch",
"description": "Q1 product launch campaign.",
"starts_at": "2025-01-06T00:00:00.000Z",
"ends_at": "2025-03-31T23:59:59.000Z",
"channels": [
"organic",
"email",
"social"
]
}'Path parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
siteId | uuid | required | The site UUID. | — |
Request body (application/json)
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
name | string | required | Human-readable campaign name. | — |
destination_url | string (URL) | required | HTTPS destination URL. Must not contain existing UTM parameters. | — |
description | string | optional | Optional longer description. | — |
starts_at | string (ISO 8601) | optional | Campaign start date. If provided, status is set to "active". | — |
ends_at | string (ISO 8601) | optional | Campaign end date. | — |
channels | string[] | optional | Channel keys to generate UTM links for. Defaults to the system default channel set. | — |
Example
json
{
"name": "Acme Q1 Launch",
"destination_url": "https://acme-demo.example/launch",
"description": "Q1 product launch campaign.",
"starts_at": "2025-01-06T00:00:00.000Z",
"ends_at": "2025-03-31T23:59:59.000Z",
"channels": [
"organic",
"email",
"social"
]
}Responses
201Campaign created. Body contains the new campaign row.
json
{
"data": {
"id": "00000000-0000-0000-0000-000000000010",
"site_id": "00000000-0000-0000-0000-000000000001",
"user_id": "00000000-0000-0000-0000-000000000099",
"name": "Acme Q1 Launch",
"slug": "acme-q1-launch",
"utm_id": "acme01",
"description": "Q1 product launch campaign.",
"destination_url": "https://acme-demo.example/launch",
"status": "active",
"starts_at": "2025-01-06T00:00:00.000Z",
"ends_at": "2025-03-31T23:59:59.000Z",
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
},
"_meta": {
"generated_at": "2025-01-15T10:30:00.000Z",
"site_id": "00000000-0000-0000-0000-000000000001"
}
}400name or destination_url missing, or destination_url contains UTM params or is not HTTPS.
json
{
"error": "name and destination_url are required"
}404Site not found.
json
{
"error": "Site not found"
}