CLIPUS API
Create campaigns from code
Submit a URL and Clipus reads the page, generates demo videos in up to 8 languages, and reports back over a webhook. It is the same pipeline that powers the dashboard — this page documents it with the real limits, read from the same source the billing code uses.
Authentication
Every request needs an API key. Create one in the dashboard under Settings → API key management (owner or admin role). Keys look like sk_live_ followed by 32 hex characters. The full key is shown once at creation — we store only a SHA-256 hash, so copy it then.
Send the key on every request, either way:
Authorization: Bearer sk_live_... # or X-API-Key: sk_live_...
Keys are scoped. The only scope today is campaigns:create, attached to every key automatically. Responses echo the scope in the X-Clipus-Api-Scopes header. How many keys you can hold depends on your plan — see Plans & quotas.
Endpoints
/api/v1/campaignsCreates a campaign: Clipus crawls the URL, captures screens, and starts video generation. The call returns as soon as collection starts — generation continues in the background, so poll status or register a webhook_url.
| url | string, required | Public page to read. https is assumed if you omit the protocol. |
| languages | string[], optional | Target languages. Defaults to ["en", "ja", "ko"]. Your plan caps how many — see quotas. |
| title | string, optional | Campaign title. Defaults to the domain name. |
| webhook_url | string, optional | Public https URL we POST to when the campaign completes or fails. |
curl -X POST https://www.clipus.io/api/v1/campaigns \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourproduct.com",
"languages": ["en", "ja"],
"webhook_url": "https://yourapp.com/hooks/clipus"
}'Response:
{
"success": true,
"campaign_id": "8f6a1c2e-...",
"job_id": "01J...",
"status": "collecting"
}Successful and plan-gated responses include X-RateLimit-Plan and X-RateLimit-Limit headers so you can see your tier from the response itself.
/api/v1/campaigns/:idReturns campaign status and finished videos.
curl https://www.clipus.io/api/v1/campaigns/8f6a1c2e-... \ -H "Authorization: Bearer sk_live_..."
{
"success": true,
"campaign_id": "8f6a1c2e-...",
"status": "review",
"url": "https://yourproduct.com",
"title": "yourproduct.com Campaign",
"languages": ["en", "ja"],
"created_at": "2026-06-11T09:30:00Z",
"videos": [
{
"id": "c91b...",
"platform": "youtube_shorts",
"status": "ready",
"file_url": "https://.../videos/8f6a1c2e/vertical_en_....mp4",
"duration_seconds": 38,
"published_at": null
}
]
}status starts at collecting, moves through processing states (processing, scripting, voiceover, rendering), and lands on review when videos are ready. published and failed are terminal. A campaign typically takes a few minutes; polling every 10–15 seconds stays well inside the rate limits below.
Plans & quotas
There is no per-call price. API usage draws from the same monthly video quota as the dashboard, and API access starts on the Growth plan. The table below is rendered from the same constants the billing code enforces; the pricing page is the canonical source for what each plan costs.
| Plan | Videos / month | Languages per campaign | API rate | API keys |
|---|---|---|---|---|
| Growth $149/mo | 40 | up to 5 | 10 req/min | 2 |
| Scale $499/mo | 100 | up to 8 | 60 req/min | 10 |
| Business $999/mo | 200 | up to 8 | 90 req/min | 20 |
| Enterprise Custom | Custom | up to 8 | 120 req/min | 50 |
Free and Starter plans do not include API access. When a campaign would exceed your monthly video quota, the API returns 429 with the current count — it does not bill overage.
Rate limits
Limits apply at two layers, and the stricter one wins. All use a 60-second sliding window.
| Per plan | campaign creation | The req/min in the quota table, enforced per account at the route. |
| Per IP, authenticated | /api/v1 with a Bearer key | 120 req/min per client IP — set to the top plan rate, so your plan, not the IP limit, is the effective ceiling. |
| Per IP, unauthenticated | /api/v1 without a Bearer key | 10 req/min per client IP, guarding against unauthenticated abuse. |
A limited request returns 429 with { "error": "Too many requests" } and these headers:
X-RateLimit-Limit: 10 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1781234567890 Retry-After: 42
Honor Retry-After (seconds). If the rate-limit backend is unavailable, the API answers 503 rather than letting traffic through unmetered.
Errors
Errors are JSON: { "success": false, "error": "..." } with a human-readable message. Status codes:
| 400 | Bad request | Missing or invalid url, invalid webhook_url, or more languages than your plan allows. |
| 401 | Unauthorized | Missing, invalid, or revoked API key. |
| 403 | Forbidden | Key lacks the required scope, or your plan does not include API access. |
| 404 | Not found | Campaign id does not exist, or belongs to another organization. |
| 422 | Unprocessable | We could not capture the page — it may block automated browsers or require sign-in. |
| 429 | Too many requests | Rate limit hit, or your monthly video quota is used up. |
| 500 | Server error | Something failed on our side. Safe to retry with backoff. |
| 503 | Unavailable | Rate-limit infrastructure unreachable; retry with backoff. |
Webhooks
Pass webhook_url when creating a campaign and we POST to it once the campaign reaches a terminal state:
{
"event": "campaign.completed", // or "campaign.failed"
"campaign_id": "8f6a1c2e-...",
"status": "review",
"videos": [ /* same shape as GET status */ ],
"timestamp": "2026-06-11T09:34:12Z"
}Each delivery carries identifying headers:
X-Clipus-Event-Id: 7d0f... # unique per event — use for deduplication
X-Clipus-Timestamp: 1781234567 # unix seconds
X-Clipus-Signature: a3b1... # HMAC-SHA256 over "{timestamp}.{event_id}.{body}"
X-Clipus-Signature-Alg: HMAC-SHA256Respond with any 2xx within a few seconds. Failed deliveries are retried up to 3 attempts total, so make your handler idempotent — X-Clipus-Event-Id is stable across retries. Webhooks are delivery notifications; treat GET /api/v1/campaigns/:id as the source of truth.
Something unclear, or a limit in your way? Talk to us — the people answering are the people who built the pipeline.