Developer API
One HTTP call turns a post link into watermark-free download links. It works with TikTok, Douyin, Instagram, Facebook and X, with more apps coming. Download links are signed and expire after 30 minutes, so fetch them soon after resolving.
Authentication and limits
Send your key in the x-api-key header. Each key has a daily quota (resets at 00:00 UTC) and a per-minute rate. Every response that counts against your quota carries x-quota-remaining. A batch costs one request per link.
| Plan | Requests per day | Burst | Batch size |
|---|---|---|---|
| No key | Shared per-IP limit | 30 per 10 min | 10 |
| Developer key | 1,000 | 120 per min | 50 |
| Business key | By agreement | By agreement | 50 |
To get a key, email api@clipkeep.app with your use case.
Resolve one link
POST /api/v1/resolve
curl -s https://www.clipkeep.site/api/v1/resolve \
-H "content-type: application/json" \
-H "x-api-key: $CLIPKEEP_KEY" \
-d '{"url":"https://vm.tiktok.com/ZMh7Qx2pK/"}'{
"platform": "tiktok",
"platformName": "TikTok",
"id": "7431209876543210987",
"type": "video",
"author": { "handle": "harbourlightbakery", "name": "Harbour Light Bakery" },
"caption": "Laminating croissant dough at 5am #baking",
"durationSec": 34,
"formats": [
{ "kind": "video", "quality": "1080p", "codec": "h264", "width": 1080, "height": 1920,
"sizeBytes": 18234112, "watermark": false, "href": "/dl/eyJ1Ijoi…" },
{ "kind": "audio", "quality": "Original audio", "watermark": false, "href": "/dl/eyJ1Ijoi…" }
],
"images": [],
"jobs": { "slideshow": false, "mp3": true }
}href values are relative to the API host. Videos are listed best first, and the watermarked copy that some apps serve is never included.
Resolve several links
POST /api/v1/batch returns one result per link and a zipHref with everything that resolved.
curl -s https://www.clipkeep.site/api/v1/batch \
-H "content-type: application/json" -H "x-api-key: $CLIPKEEP_KEY" \
-d '{"urls":["https://vm.tiktok.com/…","https://www.instagram.com/reel/…"]}'Slideshows and MP3
For a resolved post, POST /api/v1/jobs with { platform, id, kind } where kind is slideshow or mp3. Poll GET /api/v1/jobs/:id about once a second until status is done, then download href.
Node.js example
const res = await fetch("https://www.clipkeep.site/api/v1/resolve", {
method: "POST",
headers: { "content-type": "application/json", "x-api-key": process.env.CLIPKEEP_KEY },
body: JSON.stringify({ url }),
});
if (!res.ok) throw new Error((await res.json()).code);
const post = await res.json();
const best = post.formats.find((f) => f.kind === "video");
const file = await fetch(new URL(best.href, "https://www.clipkeep.site")); // stream it to disk or S3Errors
Errors use application/problem+json with a stable code:
| Code | HTTP | Meaning |
|---|---|---|
| INVALID_URL | 400 | Not a link to a supported post |
| UNSUPPORTED_PLATFORM | 400 | The app is known but not switched on yet |
| INVALID_API_KEY | 401 | Unknown key |
| PRIVATE | 403 | The post is private |
| TOKEN_INVALID | 403 | A download link was changed or has expired |
| NOT_FOUND | 404 | Deleted or never existed |
| RATE_LIMITED / QUOTA_EXCEEDED | 429 | Slow down; see retry-after |
| REGION_LOCKED / BLOCKED_DMCA | 451 | Not available from our servers, or removed after a takedown |
| UPSTREAM_ERROR | 502 | The app didn't answer; retry with backoff |
Reference
Machine-readable spec: /api/v1/openapi.json (OpenAPI 3.1).
Only use the API for content you have the right to download. Keys used to break that rule are revoked.