vlayer logovlayer

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"
    }
  }'
FieldRequiredNotes
brandIdyesBrand that owns the campaign and receives its webhooks
titleyes
pointsRewardyesPoints issued on reward.issued
challenge.targetUrlyesPublic post URL. The platform, content type, and content id are parsed from it
challenge.actionnocomment (default, Instagram and TikTok) or like (Instagram only)
challenge.instructionTextnoShown to creators by your UI
description, imageUrl, startsAt, endsAtno

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.

StatusMeaning
200Deleted. Body: { "data": { "id": 1 } }
404Campaign not found
409Campaign has attempts. Use end