A deliverable isn’t limited to visual designs — it can be a PDF, video, image, document, press material, or any other file an agency produces for a client. Deliverable review lives on versioned files. Staff can also share a guest link so clients approve without a portal account.
Deliverables & versions
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/deliverables |
List deliverables across projects |
| GET | /v1/projects/:id/deliverables |
List deliverables for a project |
| POST | /v1/projects/:id/deliverables |
Create deliverable |
| GET | /v1/projects/:id/deliverables/:deliverableId |
Deliverable detail |
| DELETE | /v1/projects/:id/deliverables/:deliverableId |
Delete deliverable |
| GET | /v1/deliverables/:deliverableId/versions |
List versions |
| POST | /v1/deliverables/:deliverableId/versions/presign |
Presign upload |
| POST | /v1/deliverables/:deliverableId/versions/confirm |
Confirm upload |
| GET | /v1/deliverables/versions/:versionId |
Version detail |
| PATCH | /v1/deliverables/versions/:versionId/file-type |
Override auto-detected file type |
| POST | /v1/deliverables/versions/:versionId/review |
Portal / staff review decision |
File type (image | pdf | video | audio | document | other) is auto-detected from the upload’s MIME type and file name when a version is confirmed; use the file-type route to correct it after the fact.
Guest review shares (staff)
Create, email, or revoke a share for a pending version:
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/deliverables/versions/:versionId/review-share |
Create share token |
| POST | /v1/deliverables/versions/:versionId/review-share/send |
Email the guest link |
| DELETE | /v1/deliverables/versions/:versionId/review-share |
Revoke share |
curl -X POST "$API/v1/deliverables/versions/$VERSION_ID/review-share" \
-H "Authorization: Bearer fel_..." \
-H "Content-Type: application/json" \
-d '{"email":"client@example.com"}'const { data } = await fetch(
`${API}/v1/deliverables/versions/${versionId}/review-share`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: 'client@example.com' }),
},
).then((r) => r.json())
console.log(data.shareUrl)import requests
r = requests.post(
f"{API}/v1/deliverables/versions/{version_id}/review-share",
headers=headers,
json={"email": "client@example.com"},
)
print(r.json())Guest review flow (public token)
These routes are authenticated by the share token (plus OTP after verify), not by agency API keys:
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/deliverables/review-shares/:token |
Share metadata / branding |
| POST | /v1/deliverables/review-shares/:token/otp |
Request email OTP |
| POST | /v1/deliverables/review-shares/:token/otp/verify |
Verify OTP, open session |
| GET | /v1/deliverables/review-shares/:token/deliverable |
Load deliverable version for review |
| POST | /v1/deliverables/review-shares/:token/review |
Approve or request changes |
Typical UI path: dashboard /review/:token → email → OTP → decision.
A version response includes deliverableId and fileType alongside the usual file metadata:
{
"version": {
"id": "ver_123",
"deliverableId": "del_456",
"version": 2,
"status": "pending",
"fileName": "press-release-final.pdf",
"mimeType": "application/pdf",
"fileType": "pdf",
"fileSize": 284213,
"url": "https://cdn.example.com/..."
}
}
List and detail routes wrap results in { deliverables } / { deliverable }:
{ "deliverables": [{ "id": "del_456", "name": "Q3 press kit", "projectId": "prj_789" }] }
Figma import
After connecting Figma under Settings → Integrations:
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/integrations/figma/frames |
List frames for a file |
| POST | /v1/integrations/figma/import |
Import frames as deliverable versions |
See Integrations & webhooks for OAuth connection endpoints.