vlayer logovlayer
API reference

Campaigns

Campaign listing and management

List campaigns

GET
/campaigns

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Query Parameters

pageinteger
Default: 1Minimum: 1
limitinteger
Default: 20Minimum: 1Maximum: 100
curl -X GET "//campaigns" \
  -H "Authorization: Bearer <token>"

Paginated campaign list

{
  "data": [
    {
      "id": 1,
      "brandId": 1,
      "title": "Summer Giveaway 2026",
      "description": "Comment on our post to win!",
      "imageUrl": "string",
      "pointsReward": 100,
      "isActive": true,
      "startsAt": "2019-08-24T14:15:22Z",
      "endsAt": "2019-08-24T14:15:22Z",
      "createdAt": "2019-08-24T14:15:22Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 150
  }
}

Get campaign details

GET
/campaigns/{id}

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Path Parameters

idRequiredinteger
curl -X GET "//campaigns/{id}" \
  -H "Authorization: Bearer <token>"

Campaign details with challenge info

{
  "data": {
    "id": 1,
    "brandId": 1,
    "title": "Summer Giveaway 2026",
    "description": "Comment on our post to win!",
    "imageUrl": "string",
    "pointsReward": 100,
    "isActive": true,
    "startsAt": "2019-08-24T14:15:22Z",
    "endsAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z",
    "challenge": {
      "id": 1,
      "campaignId": 1,
      "platform": "instagram",
      "contentType": "post",
      "contentId": "ABC123",
      "canonicalUrl": "https://www.instagram.com/p/ABC123/",
      "instructionText": "Leave a comment with #SummerVibes"
    },
    "myAttempt": {
      "id": 0,
      "state": "string",
      "retryCount": 0,
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  }
}

Create campaign with challenge

POST
/admin/campaigns

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Request Body

application/jsonRequired
brandIdRequiredinteger
titleRequiredstring
descriptionstring
imageUrlstring
Format: "uri"
pointsRewardRequiredinteger
startsAtstring
Format: "date-time"
endsAtstring
Format: "date-time"
challengeRequiredobject
curl -X POST "//admin/campaigns" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "brandId": 1,
    "title": "Summer Challenge 2026",
    "description": "Comment on our Instagram post",
    "imageUrl": "https://example.com/image.jpg",
    "pointsReward": 100,
    "startsAt": "2019-08-24T14:15:22Z",
    "endsAt": "2019-08-24T14:15:22Z",
    "challenge": {
      "targetUrl": "https://www.instagram.com/p/ABC123/",
      "instructionText": "Leave a comment with #SummerVibes",
      "action": "comment"
    }
  }'

Campaign created

{
  "data": {
    "campaign": {
      "id": 1,
      "brandId": 1,
      "title": "Summer Giveaway 2026",
      "description": "Comment on our post to win!",
      "imageUrl": "string",
      "pointsReward": 100,
      "isActive": true,
      "startsAt": "2019-08-24T14:15:22Z",
      "endsAt": "2019-08-24T14:15:22Z",
      "createdAt": "2019-08-24T14:15:22Z"
    },
    "challenge": {
      "id": 1,
      "campaignId": 1,
      "platform": "instagram",
      "contentType": "post",
      "contentId": "ABC123",
      "canonicalUrl": "https://www.instagram.com/p/ABC123/",
      "instructionText": "Leave a comment with #SummerVibes"
    }
  }
}

Get campaign summary stats

Returns attempt counts by state, total verified, rewarded, and points issued.

GET
/admin/campaigns/{id}/summary

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Path Parameters

idRequiredinteger
curl -X GET "//admin/campaigns/{id}/summary" \
  -H "Authorization: Bearer <token>"

Campaign summary

{
  "data": {
    "campaignId": 1,
    "totalAttempts": 250,
    "byState": {
      "created": 10,
      "verified": 50,
      "rewarded": 180,
      "failed_terminal": 10
    },
    "totalVerified": 230,
    "totalRewarded": 180,
    "totalPointsIssued": 18000
  }
}

Get campaign participant results

GET
/admin/campaigns/{id}/results

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Path Parameters

idRequiredinteger

Query Parameters

pageinteger
Default: 1
limitinteger
Default: 20
statestring

Filter by attempt state

Value in: "created" | "target_opened" | "awaiting_claim" | "verification_pending" | "verified" | "rewarded" | "failed_retryable" | "failed_terminal"
curl -X GET "//admin/campaigns/{id}/results?state=created" \
  -H "Authorization: Bearer <token>"

Participant results

{
  "data": [
    {}
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 150
  }
}

Batch verify and reward creators

Matches verified creators who have post comments matching their username but no existing attempt. Creates attempts in verified state, schedules the rewards, and dispatches creator.verified webhooks (followed by reward.issued once the reward is issued).

POST
/admin/campaigns/{id}/verify-and-reward

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Path Parameters

idRequiredinteger
curl -X POST "//admin/campaigns/{id}/verify-and-reward" \
  -H "Authorization: Bearer <token>"

Batch result

{
  "data": {
    "matched": 15,
    "verified": 14,
    "rewarded": 14
  }
}

End campaign

Soft-finish a campaign: sets isActive = false and endsAt to now (or keeps earlier endsAt if already past). Existing attempts and rewards are preserved. Idempotent.

POST
/admin/campaigns/{id}/end

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Path Parameters

idRequiredinteger
curl -X POST "//admin/campaigns/{id}/end" \
  -H "Authorization: Bearer <token>"

Campaign ended

{
  "data": {
    "id": 1,
    "isActive": false,
    "endsAt": "2019-08-24T14:15:22Z"
  }
}

Delete campaign

Hard-deletes a campaign and its challenge, including scraped post comments and metrics. Only permitted when the challenge has zero attempts. If any attempts exist, returns 409 — end the campaign instead.

DELETE
/admin/campaigns/{id}

Authorization

AuthorizationRequiredBearer <token>

API token. Send it as Authorization: Bearer <API_TOKEN>.

In: header

Path Parameters

idRequiredinteger
curl -X DELETE "//admin/campaigns/{id}" \
  -H "Authorization: Bearer <token>"

Campaign deleted

{
  "data": {
    "id": 1
  }
}