v1 · Base URL: https://clipsave.app · Pro feature · Manage your keys →
{ success, data | error, requestId }.Keys look like csk_live_xxxxxxxx_yyyyyyyy… and are shown once at creation. Only the prefix is stored visibly — the full secret is hashed. Keys can be rotated and revoked from the developer dashboard.
| Method | Path | Scope | Description |
|---|---|---|---|
| POST | /api/v1/analyze | extract | Detect a URL and list downloadable variants |
| POST | /api/v1/download | download | Mint a short-lived signed download URL |
| POST | /api/v1/bulk | bulk | Queue up to 25 URLs (deduplicated) |
| GET | /api/v1/account | account | Tier, key metadata, allowed scopes |
| GET | /api/v1/usage | usage | 24h request counts, per-endpoint + top sources |
| GET | /api/v1/sources | account | Live source capability registry |
curl -X POST https://clipsave.app/api/v1/analyze \
-H "Authorization: Bearer csk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.youtube.com/watch?v=jNQXAC9IVRw"}'Response:
{
"success": true,
"data": {
"source": "youtube",
"title": "Me at the zoo",
"duration": 19,
"variants": [{ "id": "f18-230", "quality": "240p", "container": "mp4" }]
},
"requestId": "req_abc123"
}const res = await fetch("https://clipsave.app/api/v1/download", {
method: "POST",
headers: {
Authorization: "Bearer csk_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://www.youtube.com/watch?v=jNQXAC9IVRw", quality: "720p" }),
});
const { data } = await res.json();
console.log(data.deliveryMode, data.downloadUrl);The response includes a deliveryMode (SERVER_STREAM, DIRECT_REDIRECT, DIRECT_BROWSER or PROCESSING) and a signed downloadUrl that expires in 30 minutes.
import requests
r = requests.post(
"https://clipsave.app/api/v1/bulk",
headers={"Authorization": "Bearer csk_live_YOUR_KEY"},
json={"urls": ["https://vimeo.com/76979871", "https://x.com/user/status/123"]},
)
for item in r.json()["data"]["items"]:
print(item["url"], "->", item["status"])For long-running operations, register a webhook in the developer dashboard. ClipSave signs every delivery with HMAC-SHA256 — verify before trusting the payload.
X-ClipSave-Signature: t=<unix_seconds>,v1=<hmac_sha256(timestamp + "." + body)>
| Event | Fires when |
|---|---|
bulk.completed | A bulk request finished processing |
bulk.failed | A bulk request failed |
job.completed | A queued job finished (also used for usage alerts / test events) |
job.failed | A queued job failed |
Deliveries retry up to 5 times with exponential backoff (1m → 5m → 30m → 2h → 6h). A 10-second timeout applies per attempt. Delivery history with status codes is visible in the dashboard. Replay protection: check the delivery-id header (X-ClipSave-Delivery-Id) and ignore duplicates.
Expensive operations accept an Idempotency-Key header. If a request is retried with the same key within 24 hours, ClipSave returns the original response instead of processing twice — safe to retry on network errors:
curl -X POST {BASE{'}'}/api/v1/bulk \
-H "Authorization: Bearer csk_live_YOUR_KEY" \
-H "Idempotency-Key: order-12345" \
-H "Content-Type: application/json" \
-d '{"urls":["https://vimeo.com/76979871"]}'Replayed responses carry the X-Idempotent-Replay: true header. Supported on /api/v1/bulk today; download and distribution actions follow the same pattern.
Live system health is published at /status and available programmatically at GET https://clipsave.app/api/status — real health checks only, never a faked uptime number.
| Plan | API access | Limit |
|---|---|---|
| Free | — | No API access |
| Pro | Included | 120 req/min · 10,000 req/day |
Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. Exceeding the limit returns 429 RATE_LIMITED.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_URL | URL malformed or not http(s) |
| 400 | SSRF_BLOCKED | URL targets internal networks |
| 401 | UNAUTHORIZED | Missing, invalid, revoked or expired key |
| 402 | PRO_REQUIRED | Plan does not include API access |
| 403 | FORBIDDEN | Key lacks the required scope |
| 429 | RATE_LIMITED | Plan rate limit exceeded |
| 502 | EXTRACTION_FAILED | Source could not be extracted (often private/login-only content) |
The API enforces the same source policy, SSRF protection and legal rules as the website. Reselling access, sharing keys, or evading limits gets keys revoked — see Developer API Terms and Acceptable Use.