Brand key required

Contracts

Contracts start as drafts, get sent as a public signing link (no creator account needed), and lock once signed. Signature status syncs back automatically when you read the contract.

List contracts

GET/v1/contracts

ParameterTypeDescription
statusstringFilter: draft, sent, signed.
page / limitintegerStandard pagination.

request

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

response 200

{
  "data": [
    {
      "id": "contract_001",
      "name": "Summer Skincare Campaign Agreement",
      "template_id": "ugc-one-time",
      "creator_name": "Emma Chen",
      "creator_email": "emma@example.com",
      "amount": "250",
      "pay_structure": "one-time",
      "video_type": "organic",
      "payment_frequency": "one-time",
      "status": "sent",
      "share_code": "9f2c…",
      "signed_at": null,
      "signed_by": null,
      "created_at": "2026-05-20T10:00:00Z",
      "updated_at": "2026-05-20T10:05:00Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 34, "has_more": true }
}

Create a contract

POST/v1/contracts

FieldTypeDescription
namestringRequired. Contract title.
contentstringThe contract text/HTML the creator will sign.
creator_name / creator_emailstringCounterparty. Email is lowercased.
amountstring | numberCompensation amount; stored as a string.
template_idstringTemplate identifier. Default "ugc-one-time".
pay_structurestringe.g. "one-time". Default one-time.
video_typestringe.g. "organic". Default organic.
payment_frequencystringe.g. "one-time". Default one-time.

request

curl -X POST "https://api.ugcroster.com/v1/contracts" \
  -H "Authorization: Bearer rsk_brand_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Fall Collection UGC Agreement",
    "creator_name": "Emma Chen",
    "creator_email": "emma@example.com",
    "amount": "300",
    "content": "This agreement covers two TikTok videos…"
  }'

response 200

{
  "data": {
    "id": "contract_new001",
    "name": "Fall Collection UGC Agreement",
    "creator_email": "emma@example.com",
    "amount": "300",
    "status": "draft",
    "created_at": "2026-06-13T16:20:00Z"
  }
}

Contracts are always created as drafts. Sending is a separate call.

Send for signature

POST/v1/contracts/{id}

Body must be { "action": "send" }. This mints a share code (idempotent: resending reuses the same code), marks the contract sent, and emails the creator their signing link. The creator signs at the public URL with no account.

request

curl -X POST "https://api.ugcroster.com/v1/contracts/contract_new001" \
  -H "Authorization: Bearer rsk_brand_key" \
  -H "Content-Type: application/json" \
  -d '{ "action": "send" }'

response 200

{
  "data": {
    "id": "contract_new001",
    "share_code": "b41c0f95ce9e03af2b61f95ce9e03af1",
    "status": "sent",
    "sign_url": "https://www.ugcroster.com/sign/b41c0f95ce9e03af2b61f95ce9e03af1",
    "email_sent": true,
    "email_error": null
  }
}

Get a contract

GET/v1/contracts/{id}

Returns the full contract including content. If the contract was sent and the creator has signed since your last read, the status syncs to signed here, with signed_at and signed_by populated.

Update or delete a draft

PATCH/v1/contracts/{id}

FieldTypeDescription
name / content / amountstringCore contract fields. amount also accepts a number.
creator_name / creator_emailstringCounterparty details.
pay_structure / video_type / payment_frequencystringTerms metadata.

DELETE/v1/contracts/{id}

response 200

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

Signed contracts are immutable: PATCH and DELETE on a signed contract both return 409 CONTRACT_SIGNED. Deleting a sent contract also invalidates its signing link.