{"openapi":"3.1.0","info":{"title":"tikklip API","version":"1.0.0","description":"REST access to TikTok data: resolve links, search posts, list comments, and page a profile."},"servers":[{"url":"https://tikklip.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your tikklip API key."}}},"paths":{"/resolve":{"get":{"summary":"Resolve one TikTok URL to its watermark-free media and metadata.","operationId":"getResolve","parameters":[{"name":"url","in":"query","required":true,"description":"Any TikTok video or photo URL, including short links.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"bad_request: A required parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"unauthorized: Missing, malformed, unknown, or revoked key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"forbidden: Your plan doesn't include API access.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"not_found: The handle, video, or URL doesn't resolve.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"rate_limited: More than 10 requests in one second. Retry after the Retry-After header. / quota_exhausted: Your monthly budget is spent. It resets on the 1st.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"upstream_error: TikTok or our provider failed. Retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/user-posts":{"get":{"summary":"One page of a profile's posts. Paginate with the returned cursor.","operationId":"getUserPosts","parameters":[{"name":"handle","in":"query","required":false,"description":"TikTok @handle. Costs the same one unit as any other request — we resolve it to a numeric id internally and cache that for 24 hours.","schema":{"type":"string"}},{"name":"userId","in":"query","required":false,"description":"The id echoed by a previous response. Passing it skips our internal handle lookup, so the call returns faster — it costs the same one unit either way.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from the previous response. Starts at \"0\".","schema":{"type":"string"}},{"name":"count","in":"query","required":false,"description":"Items per page, max 35.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"bad_request: A required parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"unauthorized: Missing, malformed, unknown, or revoked key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"forbidden: Your plan doesn't include API access.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"not_found: The handle, video, or URL doesn't resolve.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"rate_limited: More than 10 requests in one second. Retry after the Retry-After header. / quota_exhausted: Your monthly budget is spent. It resets on the 1st.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"upstream_error: TikTok or our provider failed. Retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/search":{"get":{"summary":"One page of keyword or hashtag video search results.","operationId":"getSearch","parameters":[{"name":"keyword","in":"query","required":true,"description":"Search term or hashtag (without the #).","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"Offset from the previous response. Starts at \"0\".","schema":{"type":"string"}},{"name":"count","in":"query","required":false,"description":"Items per page, max 20. Values above 20 are clamped — TikTok returns nothing above that.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"bad_request: A required parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"unauthorized: Missing, malformed, unknown, or revoked key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"forbidden: Your plan doesn't include API access.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"not_found: The handle, video, or URL doesn't resolve.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"rate_limited: More than 10 requests in one second. Retry after the Retry-After header. / quota_exhausted: Your monthly budget is spent. It resets on the 1st.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"upstream_error: TikTok or our provider failed. Retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/comments":{"get":{"summary":"One page of a video's top-level comments.","operationId":"getComments","parameters":[{"name":"url","in":"query","required":false,"description":"TikTok video URL. Costs the same one unit as any other request — we resolve it to a numeric aweme id internally and cache that for 24 hours.","schema":{"type":"string"}},{"name":"awemeId","in":"query","required":false,"description":"The id echoed by a previous response. Passing it skips our internal URL lookup, so the call returns faster — it costs the same one unit either way.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"Offset from the previous response. Starts at \"0\".","schema":{"type":"string"}},{"name":"count","in":"query","required":false,"description":"Comments per page, max 50.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"bad_request: A required parameter is missing or invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"unauthorized: Missing, malformed, unknown, or revoked key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"forbidden: Your plan doesn't include API access.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"not_found: The handle, video, or URL doesn't resolve.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"rate_limited: More than 10 requests in one second. Retry after the Retry-After header. / quota_exhausted: Your monthly budget is spent. It resets on the 1st.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"502":{"description":"upstream_error: TikTok or our provider failed. Retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","bad_request","not_found","rate_limited","quota_exhausted","upstream_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}}},"webhooks":{"job.completed":{"post":{"summary":"A scrape job finished. Carries row count, truncation reason, and signed export URLs.","operationId":"onJobCompleted","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"Stable message id. Also the idempotency key — identical across retries.","schema":{"type":"string"}},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds, re-stamped on every attempt. Reject if more than 5 minutes from now, in either direction.","schema":{"type":"string"}},{"name":"webhook-signature","in":"header","required":true,"description":"Space-delimited list of `v1,<base64>` signatures. Accept if ANY matches.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"2XX":{"description":"Any 2xx acknowledges the event. Anything else is retried."}}}},"job.failed":{"post":{"summary":"A scrape job failed. Carries the error message; no export URLs.","operationId":"onJobFailed","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"Stable message id. Also the idempotency key — identical across retries.","schema":{"type":"string"}},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds, re-stamped on every attempt. Reject if more than 5 minutes from now, in either direction.","schema":{"type":"string"}},{"name":"webhook-signature","in":"header","required":true,"description":"Space-delimited list of `v1,<base64>` signatures. Accept if ANY matches.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"2XX":{"description":"Any 2xx acknowledges the event. Anything else is retried."}}}},"webhook.test":{"post":{"summary":"Sent when an endpoint is created and on demand. Not subscribable, never retried.","operationId":"onWebhookTest","parameters":[{"name":"webhook-id","in":"header","required":true,"description":"Stable message id. Also the idempotency key — identical across retries.","schema":{"type":"string"}},{"name":"webhook-timestamp","in":"header","required":true,"description":"Unix seconds, re-stamped on every attempt. Reject if more than 5 minutes from now, in either direction.","schema":{"type":"string"}},{"name":"webhook-signature","in":"header","required":true,"description":"Space-delimited list of `v1,<base64>` signatures. Accept if ANY matches.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"2XX":{"description":"Any 2xx acknowledges the event. Anything else is retried."}}}}}}