Brand key required

Campaigns

A campaign is a public application form creators apply to. New campaigns pass an automated quality review before going live; your first campaign is included, additional ones consume a campaign credit.

List campaigns

GET/v1/campaigns

ParameterTypeDescription
statusstringFilter by status: live, pending_review, or any status you have set.
page / limitintegerStandard pagination (default 20, max 100).

request

curl "https://api.ugcroster.com/v1/campaigns?status=live" \
  -H "Authorization: Bearer rsk_brand_key"

response 200

{
  "data": [
    {
      "id": "form_xyz789",
      "title": "Summer Skincare Launch",
      "status": "live",
      "brand_name": "Glow Skincare",
      "campaign_type": "organic_ugc",
      "compensation_label": "$250 per video",
      "applications_closed": false,
      "applicant_count": 47,
      "hired_count": 8,
      "created_at": "2026-05-20T09:00:00Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 12, "has_more": false }
}

Create a campaign

POST/v1/campaigns

FieldTypeDescription
titlestringRequired. Campaign title.
questionsarrayRequired, at least one. Each item: { id, type, question }, plus options: string[] when type is "single_choice".
campaign_typestringorganic / ugc / organic_ugc → organic_ugc; paid / paid_ads → paid_ads; influencer; affiliate. Default organic_ugc.
full_descriptionstringLong-form campaign description shown to creators.
compensation_labelstringHuman-readable pay line, e.g. "$300 per video".
compensation_amountstringNumeric amount as a string.
brand_name / websitestringDefaults to your brand profile when omitted.
creator_type / niche / platformstringTargeting labels for the marketplace listing.
content_needed / budget_per_creator / timelinestringOptional listing details.
start_date / end_datestringISO dates for the campaign window.
ships_productbooleanWhether product is shipped to creators.

request

curl -X POST "https://api.ugcroster.com/v1/campaigns" \
  -H "Authorization: Bearer rsk_brand_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Fall Collection UGC",
    "campaign_type": "ugc",
    "full_description": "We need authentic unboxing content for our fall line.",
    "compensation_label": "$300 per video",
    "platform": "tiktok",
    "questions": [
      { "id": "q1", "type": "text", "question": "Link your best UGC example" },
      { "id": "q2", "type": "single_choice", "question": "Preferred platform",
        "options": ["TikTok", "Instagram"] }
    ]
  }'

response 200

{
  "data": {
    "id": "form_new456",
    "title": "Fall Collection UGC",
    "status": "pending_review",
    "campaign_type": "organic_ugc",
    "auto_approved": false
  }
}

Every submission goes through the same deterministic quality gate as the brand portal. Failures return 400 VALIDATION_ERROR with an issues array explaining each problem. If the automated review passes, status comes back live and auto_approved: true; otherwise the campaign stays pending_review until manually approved. Creating a second campaign without a purchased credit returns 402 campaign_credit_required.

Get a campaign

GET/v1/campaigns/{id}

Returns the campaign plus its raw applicants and hired creators in one call.

response 200

{
  "data": {
    "campaign": {
      "id": "form_xyz789",
      "title": "Summer Skincare Launch",
      "status": "live",
      "brand_name": "Glow Skincare",
      "campaign_type": "organic_ugc",
      "compensation_label": "$250 per video",
      "compensation_amount": "250",
      "full_description": "Authentic skincare content for summer.",
      "applications_closed": false,
      "questions": [ { "id": "q1", "type": "text", "question": "…" } ],
      "created_at": "2026-05-20T09:00:00Z"
    },
    "applicants": [
      {
        "id": "app_001",
        "respondent_email": "emma@example.com",
        "user_id": "user_123",
        "responses": { "q1": "https://instagram.com/p/abc123" },
        "submitted_at": "2026-06-01T12:00:00Z"
      }
    ],
    "hired_creators": [
      { "id": "hire_001", "creator_email": "emma@example.com",
        "creator_name": "Emma Chen", "hired_at": "2026-06-03T09:00:00Z" }
    ]
  }
}

Update a campaign

PATCH/v1/campaigns/{id}

FieldTypeDescription
titlestringNew title (non-empty).
full_descriptionstringNew description; empty string clears it.
applications_closedbooleanClose or reopen applications without archiving.
applicant_capinteger | nullOptional positive cap on applicants; null clears it.
compensation_label / compensation_amountstringPay line and amount.
campaign_typestringSame accepted values as create.
website / brand_name / creator_type / niche / platformstringListing fields.
content_needed / budget_per_creator / timelinestringListing details.
start_date / end_datestring | nullISO dates; null clears.
ships_productbooleanProduct shipping flag.

request

curl -X PATCH "https://api.ugcroster.com/v1/campaigns/form_xyz789" \
  -H "Authorization: Bearer rsk_brand_key" \
  -H "Content-Type: application/json" \
  -d '{ "applications_closed": true, "compensation_label": "$350 per video" }'

response 200

{
  "data": {
    "id": "form_xyz789",
    "applications_closed": true,
    "compensation_label": "$350 per video",
    "updated_at": "2026-06-13T14:35:00Z"
  }
}

Archive a campaign

DELETE/v1/campaigns/{id}

Soft-deletes the campaign: it is hidden from the marketplace and excluded from listings, but its applications and hires remain readable. Archived campaigns no longer count against your included campaign.

request

curl -X DELETE "https://api.ugcroster.com/v1/campaigns/form_xyz789" \
  -H "Authorization: Bearer rsk_brand_key"

response 200

{ "data": { "id": "form_xyz789", "deleted": true } }

List a campaign’s applications

GET/v1/campaigns/{id}/applications

ParameterTypeDescription
statusstringFilter: pending, approved, rejected, hired.
page / limitintegerStandard pagination.

response 200

{
  "data": [
    {
      "id": "app_001",
      "respondent_email": "emma@example.com",
      "creator_name": "Emma Chen",
      "user_id": "user_123",
      "name": "Emma Chen",
      "email": "emma@example.com",
      "portfolio": "https://emmachen.com",
      "social_link": "https://instagram.com/emmachen",
      "responses": { "q1": "https://instagram.com/p/abc123" },
      "status": "pending",
      "submitted_at": "2026-06-01T12:00:00Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 47, "has_more": true }
}

name, email, portfolio and social_linkare extracted from the applicant’s answers by matching question labels. The raw answers are always available under responses. Creators who were hired report status: "hired" regardless of the stored application status.