Create a campaign
Create a campaign and its challenge from a public post URL, then end or delete it.
A campaign is a reward program. It carries one challenge: the public Instagram or TikTok post creators must engage with. You create both in a single call and use the returned challengeId for every later request.
Create
POST /admin/campaigns
curl -X POST {API_BASE_URL}/admin/campaigns \
-H "Authorization: Bearer <API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"brandId": 1,
"title": "Summer Challenge 2026",
"description": "Comment on our Instagram post",
"pointsReward": 100,
"challenge": {
"targetUrl": "https://www.instagram.com/p/ABC123/",
"instructionText": "Leave a comment with #SummerVibes",
"action": "comment"
}
}'| Field | Required | Notes |
|---|---|---|
brandId | yes | Brand that owns the campaign and receives its webhooks |
title | yes | |
pointsReward | yes | Points issued on reward.issued |
challenge.targetUrl | yes | Public post URL. The platform, content type, and content id are parsed from it |
challenge.action | no | comment (default, Instagram and TikTok) or like (Instagram only) |
challenge.instructionText | no | Shown to creators by your UI |
description, imageUrl, startsAt, endsAt | no |
Response 201:
{
"data": {
"campaign": {
"id": 1,
"brandId": 1,
"title": "Summer Challenge 2026",
"pointsReward": 100,
"isActive": true,
"startsAt": null,
"endsAt": null,
"createdAt": "2026-06-01T09:00:00.000Z"
},
"challenge": {
"id": 1,
"campaignId": 1,
"platform": "instagram",
"contentType": "post",
"contentId": "ABC123",
"canonicalUrl": "https://www.instagram.com/p/ABC123/",
"instructionText": "Leave a comment with #SummerVibes"
}
}
}Store data.challenge.id. Comments, metrics, likers, and attempts are all addressed by challengeId; none of those routes take a URL or shortcode.
Set challenge.action to "like" only for Instagram posts. Liker fetching is not available for TikTok, so a like challenge on a TikTok URL cannot be verified.
Read
GET /campaigns lists campaigns; GET /campaigns/{id} returns one with its challenge. Both return the same Campaign and Challenge shapes as the create response.
End
POST /admin/campaigns/{id}/end
Sets isActive to false and endsAt to now (an earlier endsAt is kept). Attempts and rewards are preserved. Calling it again is a no-op.
{ "data": { "id": 1, "isActive": false, "endsAt": "2026-07-01T00:00:00.000Z" } }Delete
DELETE /admin/campaigns/{id}
Hard-deletes the campaign, its challenge, and every scraped comment and metrics snapshot. Allowed only while the challenge has zero attempts; otherwise the call returns 409 and you should end the campaign instead.
| Status | Meaning |
|---|---|
200 | Deleted. Body: { "data": { "id": 1 } } |
404 | Campaign not found |
409 | Campaign has attempts. Use end |