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
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter: draft, sent, signed. |
| page / limit | integer | Standard 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
| Field | Type | Description |
|---|---|---|
| name | string | Required. Contract title. |
| content | string | The contract text/HTML the creator will sign. |
| creator_name / creator_email | string | Counterparty. Email is lowercased. |
| amount | string | number | Compensation amount; stored as a string. |
| template_id | string | Template identifier. Default "ugc-one-time". |
| pay_structure | string | e.g. "one-time". Default one-time. |
| video_type | string | e.g. "organic". Default organic. |
| payment_frequency | string | e.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}
| Field | Type | Description |
|---|---|---|
| name / content / amount | string | Core contract fields. amount also accepts a number. |
| creator_name / creator_email | string | Counterparty details. |
| pay_structure / video_type / payment_frequency | string | Terms 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.