{"openapi":"3.1.0","info":{"title":"Crayo API","version":"1.0.0","description":"Media generation, rendering and View Tracker. Raw: you call, you schedule, you store. Managed: we refresh on your cadence, keep every reading, and push webhooks. Same credits either way. Credits are spent when a request is accepted; View Tracker lookups that fail on our side are refunded. Send the key as Authorization: Bearer <key>."},"servers":[{"url":"https://api.crayo.ai"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Account","description":"Plan, credit balances, storage, and your key's limits."},{"name":"Assets and Uploads","description":"Your media library, plus the two ways to get files into it."},{"name":"Generation","description":"Images, icons, face swaps, narration, and voice changes."},{"name":"Catalogs","description":"Voices, languages, subtitle styles, and background music."},{"name":"Transcripts","description":"Word-level speech-to-text on your own media."},{"name":"Projects","description":"Compose scenes into a video, then render it."},{"name":"Exports","description":"Track renders and collect the finished file."},{"name":"AutoClip","description":"Turn a long video into vertical shorts automatically."},{"name":"Speech Enhancer","description":"Studio-clean speech from any recording, with separate speech, music and background levels."},{"name":"Raw (manage it yourself)","description":"Live lookups. You call, you schedule, you store. 1 credit per request."},{"name":"Managed (our scheduler)","description":"We refresh on your cadence, keep every reading, and push webhooks."},{"name":"Webhooks","description":"Get told when long-running work finishes."}],"paths":{"/v1/account":{"get":{"operationId":"get-account","summary":"Get account","description":"Returns the account behind the API key: plan, credit balances by type, storage usage, and the rate limits that apply to your key. Call it before a batch run to confirm you have the credits and storage the run needs.","tags":["Account"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"account":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"plan":{"type":"string"}},"required":["id","name","email","plan"]},"credits":{"type":"object","properties":{"export":{"type":"integer"},"voiceover":{"type":"integer"},"image":{"type":"integer"},"video":{"type":"integer"},"tracker":{"type":"integer"}},"required":["export","voiceover","image","video","tracker"]},"storage":{"type":"object","properties":{"used_bytes":{"type":"integer"},"trashed_bytes":{"type":"integer"},"allowed_bytes":{"type":"integer"}},"required":["used_bytes","trashed_bytes","allowed_bytes"]},"rate_limit":{"type":"object","properties":{"default":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]},"heavy":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]},"polling":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]},"uploads":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]},"view_tracker":{"type":"object","properties":{"raw":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]},"read":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]},"write":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]},"batch":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"requests_per_minute":{"type":"integer"}},"required":["requests_per_second","requests_per_minute"]}},"required":["raw","read","write","batch"]}},"required":["default","heavy","polling","uploads","view_tracker"]}},"required":["success","account","credits","storage","rate_limit"]},"example":{"success":true,"account":{"id":"cm7x0v8qa0000abcd","name":"Ada Lovelace","email":"ada@example.com","plan":"Creator"},"credits":{"export":4210,"voiceover":9800,"image":320,"video":45,"tracker":1840},"storage":{"used_bytes":5312000,"trashed_bytes":0,"allowed_bytes":107374182400},"rate_limit":{"default":{"requests_per_second":2,"requests_per_minute":50},"heavy":{"requests_per_second":2,"requests_per_minute":10},"polling":{"requests_per_second":2,"requests_per_minute":120},"uploads":{"requests_per_second":2,"requests_per_minute":20},"view_tracker":{"raw":{"requests_per_second":5,"requests_per_minute":200},"read":{"requests_per_second":5,"requests_per_minute":300},"write":{"requests_per_second":2,"requests_per_minute":60},"batch":{"requests_per_second":1,"requests_per_minute":10}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/assets":{"get":{"operationId":"list-assets","summary":"List assets","description":"Lists the media in your library, newest first. Every file you upload, import, or generate lands here, and an asset id is what every other endpoint takes as input.","tags":["Assets and Uploads"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"type","in":"query","required":false,"description":"Filter by media type.","schema":{"type":"string","enum":["image","audio","video"]},"example":"video"},{"name":"category","in":"query","required":false,"description":"Filter by how the asset was made, for example asset for uploads, generation for images, or voiceover for narration.","schema":{"type":"string"},"example":"asset"},{"name":"limit","in":"query","required":false,"description":"Assets per page. 1 to 100.","schema":{"type":"integer","default":50},"example":25},{"name":"offset","in":"query","required":false,"description":"Number of assets to skip.","schema":{"type":"integer","default":0},"example":0}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"hasMore":{"type":"boolean"},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"thumbnail":{"type":"string"},"thumbnailUrl":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","width","height","thumbnail","thumbnailUrl","createdAt"]}}},"required":["success","total","hasMore","assets"]},"example":{"success":true,"total":128,"hasMore":true,"assets":[{"id":"cm7x1k2p40001abcd","name":"hook-clip.mp4","key":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","type":"video","category":"asset","length":12.4,"size":8421376,"width":1080,"height":1920,"thumbnail":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","thumbnailUrl":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","createdAt":"2026-08-21T14:02:11.000Z"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"post":{"operationId":"import-asset","summary":"Import asset from URL","description":"Downloads a file from a public https URL and stores it as an asset. This is the fastest way to bring in media you already host. Files above the import ceiling have to go through the upload flow instead.","tags":["Assets and Uploads"],"x-credits":"Free","x-rate-limit":{"tier":"upload","requests_per_second":2,"requests_per_minute":20},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public https URL of the image, audio, or video file to import. Must be reachable and at most 100MB."},"name":{"type":"string","description":"Display name for the asset. Defaults to the filename in the URL. Max 200 characters."}},"required":["url"],"additionalProperties":false},"example":{"url":"https://example.com/media/hook-clip.mp4","name":"Hook clip"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"thumbnail":{"type":"string"},"thumbnailUrl":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","width","height","thumbnail","thumbnailUrl","createdAt"]}},"required":["success","asset"]},"example":{"success":true,"asset":{"id":"cm7x1k2p40001abcd","name":"hook-clip.mp4","key":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","type":"video","category":"asset","length":12.4,"size":8421376,"width":1080,"height":1920,"thumbnail":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","thumbnailUrl":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","createdAt":"2026-08-21T14:02:11.000Z"}}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The URL could not be fetched, or it is not a public https address."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"STORAGE_LIMIT_EXCEEDED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"STORAGE_LIMIT_EXCEEDED":{"summary":"STORAGE_LIMIT_EXCEEDED","value":{"success":false,"error":{"code":"STORAGE_LIMIT_EXCEEDED","message":"The file would exceed your storage quota."}}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"FILE_TOO_LARGE":{"summary":"FILE_TOO_LARGE","value":{"success":false,"error":{"code":"FILE_TOO_LARGE","message":"The file is larger than 100MB. Use the upload flow."}}}}}}},"415":{"description":"UNSUPPORTED_MEDIA_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNSUPPORTED_MEDIA_TYPE":{"summary":"UNSUPPORTED_MEDIA_TYPE","value":{"success":false,"error":{"code":"UNSUPPORTED_MEDIA_TYPE","message":"The URL does not serve a supported image, audio, or video type."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/assets/{id}":{"get":{"operationId":"get-asset","summary":"Get asset","description":"Returns one asset you own, including its playable url and its duration in seconds. Read length here before building scenes: the project schema is measured in milliseconds and per-second endpoints reject assets with no known duration.","tags":["Assets and Uploads"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The asset id.","schema":{"type":"string"},"example":"cm7x1k2p40001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"thumbnail":{"type":"string"},"thumbnailUrl":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","width","height","thumbnail","thumbnailUrl","createdAt"]}},"required":["success","asset"]},"example":{"success":true,"asset":{"id":"cm7x1k2p40001abcd","name":"hook-clip.mp4","key":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","type":"video","category":"asset","length":12.4,"size":8421376,"width":1080,"height":1920,"thumbnail":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","thumbnailUrl":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","createdAt":"2026-08-21T14:02:11.000Z"}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No asset with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"patch":{"operationId":"rename-asset","summary":"Rename asset","description":"Changes the display name of an asset you own. Only the name changes: the file, its url, and every project that references it stay exactly as they are.","tags":["Assets and Uploads"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The asset id.","schema":{"type":"string"},"example":"cm7x1k2p40001abcd"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The new display name. Non-empty, max 200 characters. Leading and trailing whitespace is trimmed."}},"required":["name"],"additionalProperties":false},"example":{"name":"Hook clip v2"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"thumbnail":{"type":"string"},"thumbnailUrl":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","width","height","thumbnail","thumbnailUrl","createdAt"]}},"required":["success","asset"]},"example":{"success":true,"asset":{"id":"cm7x1k2p40001abcd","name":"Hook clip v2","key":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","type":"video","category":"asset","length":12.4,"size":8421376,"width":1080,"height":1920,"thumbnail":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","thumbnailUrl":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","createdAt":"2026-08-21T14:02:11.000Z"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"name is missing, empty, or too long."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field other than name."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No asset with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"delete":{"operationId":"delete-asset","summary":"Delete asset","description":"Permanently deletes an asset and frees its storage. Projects that already reference the file keep their timeline entry, but the media behind it stops resolving, so delete only what nothing depends on.","tags":["Assets and Uploads"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The asset id.","schema":{"type":"string"},"example":"cm7x1k2p40001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"example":{"success":true}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No asset with that id belongs to your account."}}}}}}},"409":{"description":"ASSET_IN_USE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"ASSET_IN_USE":{"summary":"ASSET_IN_USE","value":{"success":false,"error":{"code":"ASSET_IN_USE","message":"The asset is the source of an AutoClip job that is still running."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/uploads":{"post":{"operationId":"create-upload","summary":"Create upload","description":"Step one of the upload flow. Declare the file you are about to send and get back a signed URL to PUT the bytes to. The URL is single-use and short-lived, so start the transfer right away.\n\nPUT the raw bytes to the returned url with exactly the content-type header it hands back, and begin within 5 minutes.\n\nNothing is stored until you complete the upload. A file that is never completed is discarded.","tags":["Assets and Uploads"],"x-credits":"Free","x-rate-limit":{"tier":"upload","requests_per_second":2,"requests_per_minute":20},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string","description":"Name of the file, used as the asset name. Max 100 characters after sanitizing."},"content_type":{"type":"string","description":"MIME type of the file. It must match the bytes you send. One of the supported image, audio, or video types."},"size_bytes":{"type":"integer","description":"Size of the file in bytes. Images 20MB, audio 100MB, video 1GB."}},"required":["filename","content_type","size_bytes"],"additionalProperties":false},"example":{"filename":"hook-clip.mp4","content_type":"video/mp4","size_bytes":8421376}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"upload":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"method":{"type":"string"},"headers":{"type":"object","properties":{"content-type":{"type":"string"}},"required":["content-type"]},"expires_at":{"type":"string"}},"required":["id","url","method","headers","expires_at"]}},"required":["success","upload"]},"example":{"success":true,"upload":{"id":"5f0c9a1e-7c1b-4a5e-9f0e-6b2a3c4d5e6f","url":"https://uploads.crayo.ai/user-uploads/.../staging/hook-clip.mp4?X-Amz-Signature=...","method":"PUT","headers":{"content-type":"video/mp4"},"expires_at":"2026-08-21T14:07:11.000Z"}}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A field is missing or size_bytes is not a whole number."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"STORAGE_LIMIT_EXCEEDED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"STORAGE_LIMIT_EXCEEDED":{"summary":"STORAGE_LIMIT_EXCEEDED","value":{"success":false,"error":{"code":"STORAGE_LIMIT_EXCEEDED","message":"The file would exceed your storage quota."}}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"FILE_TOO_LARGE":{"summary":"FILE_TOO_LARGE","value":{"success":false,"error":{"code":"FILE_TOO_LARGE","message":"size_bytes is above the cap for that media type."}}}}}}},"415":{"description":"UNSUPPORTED_MEDIA_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNSUPPORTED_MEDIA_TYPE":{"summary":"UNSUPPORTED_MEDIA_TYPE","value":{"success":false,"error":{"code":"UNSUPPORTED_MEDIA_TYPE","message":"content_type is not a supported type."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/uploads/{id}/complete":{"post":{"operationId":"complete-upload","summary":"Complete upload","description":"Step three of the upload flow. Call it once the PUT finishes to have the file checked, measured, and turned into an asset. Size, MIME type, and your storage quota are all enforced here, so a file only becomes an asset if it passes.","tags":["Assets and Uploads"],"x-credits":"Free","x-rate-limit":{"tier":"upload","requests_per_second":2,"requests_per_minute":20},"parameters":[{"name":"id","in":"path","required":true,"description":"The upload id returned by POST /v1/uploads.","schema":{"type":"string"},"example":"5f0c9a1e-7c1b-4a5e-9f0e-6b2a3c4d5e6f"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"thumbnail":{"type":"string"},"thumbnailUrl":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","width","height","thumbnail","thumbnailUrl","createdAt"]}},"required":["success","asset"]},"example":{"success":true,"asset":{"id":"cm7x1k2p40001abcd","name":"hook-clip.mp4","key":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../hook-clip.mp4","type":"video","category":"asset","length":12.4,"size":8421376,"width":1080,"height":1920,"thumbnail":"user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","thumbnailUrl":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/api/9f1.../thumb.jpg","createdAt":"2026-08-21T14:02:11.000Z"}}}}},"400":{"description":"UPLOAD_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPLOAD_NOT_FOUND":{"summary":"UPLOAD_NOT_FOUND","value":{"success":false,"error":{"code":"UPLOAD_NOT_FOUND","message":"No bytes have reached the signed URL yet."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"STORAGE_LIMIT_EXCEEDED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"STORAGE_LIMIT_EXCEEDED":{"summary":"STORAGE_LIMIT_EXCEEDED","value":{"success":false,"error":{"code":"STORAGE_LIMIT_EXCEEDED","message":"The finished file would exceed your storage quota."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The upload id is unknown or older than 2 hours."}}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"FILE_TOO_LARGE":{"summary":"FILE_TOO_LARGE","value":{"success":false,"error":{"code":"FILE_TOO_LARGE","message":"The stored file is larger than the cap or than size_bytes."}}}}}}},"415":{"description":"UNSUPPORTED_MEDIA_TYPE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNSUPPORTED_MEDIA_TYPE":{"summary":"UNSUPPORTED_MEDIA_TYPE","value":{"success":false,"error":{"code":"UNSUPPORTED_MEDIA_TYPE","message":"The stored bytes do not match the content_type you declared."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/image-generator":{"post":{"operationId":"image-generator","summary":"Generate image","description":"Generates an image from a text prompt and stores it as an asset you can drop straight into a project scene. Some models accept a reference image to carry over a look, a subject, or a layout.\n\nOnly the models marked as supporting a reference image read reference_image_url.","tags":["Generation"],"x-credits":"1 image credit","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","description":"What to generate. Max 2,000 characters."},"model":{"type":"string","enum":["black-forest-labs/flux-schnell","bytedance/seedream-4.5","bytedance/seedream-5-lite","ideogram-ai/ideogram-v3-turbo","bria/image-3.2","google/nano-banana","google/nano-banana-pro"],"default":"black-forest-labs/flux-schnell","description":"Which model renders the image."},"aspect_ratio":{"type":"string","enum":["1:1","16:9","9:16","4:3","3:4"],"default":"1:1","description":"Output shape."},"reference_image_url":{"type":"string","description":"Public https URL of an image to steer the result. Must be https on port 443. Plain http and non-standard ports are rejected."}},"required":["prompt"],"additionalProperties":false},"example":{"prompt":"a golden retriever surfing a wave at sunset, cinematic","model":"black-forest-labs/flux-schnell","aspect_ratio":"9:16"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"image":{"type":"string"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"size":{"type":"integer"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","size","createdAt"]}},"required":["image","asset"]},"example":{"image":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","asset":{"id":"cm7x1j0aa0000abcd","name":"image","key":"user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","type":"image","category":"generation","size":482913,"createdAt":"2026-08-21T14:02:11.000Z"}}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"prompt is missing, or aspect_ratio is not a supported value."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no image credits left."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/icon-generator":{"post":{"operationId":"icon-generator","summary":"Generate icon","description":"Generates a single app-style icon on a transparent background from a short concept, for thumbnails, overlays, and channel art. Pass a badge color and an accent color to match a brand palette.","tags":["Generation"],"x-credits":"1 image credit","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"concept":{"type":"string","description":"The idea the icon should depict. Max 200 characters."},"color":{"type":"string","description":"Badge background color as a hex value or a color name. Near-white values are rejected because the glyph would disappear."},"accent_color":{"type":"string","description":"Glyph color drawn on top of the badge. Must contrast with color."},"reference_image_url":{"type":"string","description":"Public https URL of an image to steer the result. Must be https on port 443. Plain http and non-standard ports are rejected."}},"required":["concept"],"additionalProperties":false},"example":{"concept":"rocket launch","color":"#1B2A4A"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"image":{"type":"string"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"size":{"type":"integer"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","size","createdAt"]}},"required":["success","image","asset"]},"example":{"success":true,"image":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/2b8.../icon.png","asset":{"id":"cm7x1j0aa0000abcd","name":"rocket launch","key":"user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","type":"image","category":"icon","size":482913,"createdAt":"2026-08-21T14:02:11.000Z"}}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"concept is empty, or a color value is rejected."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no image credits left."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"GENERATION_FAILED, SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"GENERATION_FAILED":{"summary":"GENERATION_FAILED","value":{"success":false,"error":{"code":"GENERATION_FAILED","message":"The icon could not be produced. The credit stays spent."}}},"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/icon-generator/bulk":{"post":{"operationId":"icon-generator-bulk","summary":"Generate icon set","description":"Generates a matching set of icons in one call. Every icon shares one palette so the set looks like a family. Concepts that fail are listed in the response and the set still returns whatever succeeded.","tags":["Generation"],"x-credits":"1 image credit per concept","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"concepts":{"type":"array","items":{"type":"string"},"description":"The icons to generate. Accepts an array or a comma-separated string. Duplicates are dropped. Omit it to get the default starter set. Max 12 concepts per request, each up to 200 characters."},"color":{"type":"string","description":"Shared badge background color for the whole set."},"accent_color":{"type":"string","description":"Shared glyph color for the whole set."},"reference_image_url":{"type":"string","description":"Public https URL of an image to steer the result. Must be https on port 443. Plain http and non-standard ports are rejected."}},"required":[],"additionalProperties":false},"example":{"concepts":["rocket launch","camera","trophy"],"color":"#1B2A4A"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"requested":{"type":"integer"},"generated":{"type":"integer"},"failed":{"type":"array","items":{}},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"size":{"type":"integer"},"createdAt":{"type":"string"},"concept":{"type":"string"}},"required":["id","name","key","url","type","category","size","createdAt","concept"]}}},"required":["success","requested","generated","failed","assets"]},"example":{"success":true,"requested":3,"generated":3,"failed":[],"assets":[{"id":"cm7x1j0aa0000abcd","name":"rocket launch","key":"user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","type":"image","category":"generation","size":482913,"createdAt":"2026-08-21T14:02:11.000Z","concept":"rocket launch"}]}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"concepts is not a list, or there are more than 12 of them."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Your image balance is below the number of concepts."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"GENERATION_FAILED, SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"GENERATION_FAILED":{"summary":"GENERATION_FAILED","value":{"success":false,"error":{"code":"GENERATION_FAILED","message":"Every concept failed. Credits stay spent."}}},"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/face-swap":{"post":{"operationId":"face-swap","summary":"Face swap","description":"Places the face from one image onto a target image and stores the result as an asset. Both images are read from public https URLs, so host them yourself or import them as assets first and use the asset url.","tags":["Generation"],"x-credits":"1 image credit","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"face_image_url":{"type":"string","description":"Public https URL of the image holding the face to use. Must be https on port 443."},"target_image_url":{"type":"string","description":"Public https URL of the image to place the face into. Must be https on port 443."},"prompt":{"type":"string","description":"Optional direction for the blend, for example lighting or expression."},"clean_up":{"type":"boolean","default":false,"description":"Run an extra pass to smooth blend artifacts."}},"required":["face_image_url","target_image_url"],"additionalProperties":false},"example":{"face_image_url":"https://example.com/faces/host.jpg","target_image_url":"https://example.com/scenes/podcast.jpg"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"image":{"type":"string"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"size":{"type":"integer"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","size","createdAt"]}},"required":["image","asset"]},"example":{"image":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/7d3.../image.png","asset":{"id":"cm7x1j0aa0000abcd","name":"Face Swap","key":"user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/9f1.../image.png","type":"image","category":"face-swap","size":482913,"createdAt":"2026-08-21T14:02:11.000Z"}}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"An image URL is missing or is not a public https URL."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no image credits left."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/voiceover-generator":{"post":{"operationId":"voiceover-generator","summary":"Generate voiceover","description":"Turns a script into narration audio and stores it as an asset. The returned asset id is what you pass as narration.asset_id on a project, and duration_seconds tells you how long to make the visuals.\n\nCost is estimated from the script length at roughly 750 characters per minute, and charged before the audio is produced.","tags":["Generation"],"x-credits":"1 voiceover credit per second of narration","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"script":{"type":"string","description":"The words to speak. Max 5000 characters."},"voice_id":{"type":"string","description":"A voice_id from GET /v1/voices."},"title":{"type":"string","description":"Name for the resulting asset. Trimmed to 25 characters."},"settings":{"type":"object","properties":{"stability":{"type":"integer","default":50,"description":"Higher values read more evenly, lower values vary more. 0 to 100."},"similarity":{"type":"integer","default":75,"description":"How closely the read tracks the original voice. 0 to 100."},"exaggeration":{"type":"integer","default":50,"description":"How much expression to put into the read. 0 to 100."},"speed":{"type":"number","default":1,"description":"Playback speed multiplier. 0.7 to 1.2."}},"required":[],"additionalProperties":false,"description":"Delivery controls for the voice."}},"required":["script","voice_id"],"additionalProperties":false},"example":{"script":"Three habits that quietly ruin your mornings. Number one starts before you even wake up.","voice_id":"v_9f2c41ab77d0e315","title":"Hook narration","settings":{"stability":50,"similarity":75,"exaggeration":50,"speed":1}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","createdAt"]},"duration_seconds":{"type":"number"}},"required":["success","asset","duration_seconds"]},"example":{"success":true,"asset":{"id":"cm7x1j5bb0002abcd","name":"Hook narration","key":"user-uploads/cm7x0v8qa0000abcd/4c2.../hook-narration.mp3","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/4c2.../hook-narration.mp3","type":"audio","category":"voiceover","length":18.4,"size":294912,"createdAt":"2026-08-21T14:03:02.000Z"},"duration_seconds":18.4}}}},"400":{"description":"INVALID_VOICE, VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INVALID_VOICE":{"summary":"INVALID_VOICE","value":{"success":false,"error":{"code":"INVALID_VOICE","message":"voice_id is not in the voice catalog."}}},"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The script is too long, or a setting is out of range."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Your voiceover balance is below the script length."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/voice-changer":{"post":{"operationId":"voice-changer","summary":"Change voice","description":"Re-performs the speech in an audio or video asset you own with a different voice, keeping the original timing and delivery. The source has to be one of your own assets so the duration, and therefore the cost, is known before the job runs.\n\nCredits are charged up front from the asset duration, before the conversion starts.","tags":["Generation"],"x-credits":"1 voiceover credit per second of the source asset","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"asset_id":{"type":"string","description":"An audio or video asset you own, with a known duration. Duration drives the credit charge, so assets with unknown length are rejected."},"voice_id":{"type":"string","description":"A voice_id from GET /v1/voices."},"remove_background_noise":{"type":"boolean","default":false,"description":"Strip background noise from the source before converting."}},"required":["asset_id","voice_id"],"additionalProperties":false},"example":{"asset_id":"cm7x1k2p40001abcd","voice_id":"v_9f2c41ab77d0e315","remove_background_noise":true}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","createdAt"]}},"required":["success","asset"]},"example":{"success":true,"asset":{"id":"cm7x1j5bb0002abcd","name":"voice-changed","key":"user-uploads/cm7x0v8qa0000abcd/4c2.../hook-narration.mp3","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/4c2.../hook-narration.mp3","type":"audio","category":"voice-changer","length":18.4,"size":294912,"createdAt":"2026-08-21T14:03:02.000Z"}}}}},"400":{"description":"INVALID_VOICE, INVALID_ASSET_TYPE, INVALID_ASSET","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INVALID_VOICE":{"summary":"INVALID_VOICE","value":{"success":false,"error":{"code":"INVALID_VOICE","message":"voice_id is not in the voice catalog."}}},"INVALID_ASSET_TYPE":{"summary":"INVALID_ASSET_TYPE","value":{"success":false,"error":{"code":"INVALID_ASSET_TYPE","message":"The asset is an image rather than audio or video."}}},"INVALID_ASSET":{"summary":"INVALID_ASSET","value":{"success":false,"error":{"code":"INVALID_ASSET","message":"The asset has no known duration. Upload it again."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Your voiceover balance is below the media duration."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No asset with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/voices":{"get":{"operationId":"list-voices","summary":"List voices","description":"Lists every narration voice available to your account, with a preview file for each one. Voice ids from this endpoint are the only ids accepted by the voiceover generator and the voice changer, so resolve a voice here before generating audio.","tags":["Catalogs"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"gender","in":"query","required":false,"description":"Filter by voice gender.","schema":{"type":"string"},"example":"female"},{"name":"accent","in":"query","required":false,"description":"Filter by accent, for example american or british.","schema":{"type":"string"},"example":"american"},{"name":"search","in":"query","required":false,"description":"Case-insensitive match against the voice name.","schema":{"type":"string"},"example":"nova"},{"name":"limit","in":"query","required":false,"description":"Voices per page. 1 to 500. Returns every match when omitted.","schema":{"type":"integer"},"example":50},{"name":"offset","in":"query","required":false,"description":"Number of voices to skip.","schema":{"type":"integer","default":0},"example":0}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"voices":{"type":"array","items":{"type":"object","properties":{"voice_id":{"type":"string"},"name":{"type":"string"},"gender":{"type":"string"},"age":{"type":"string"},"accent":{"type":"string"},"description":{"type":"string"},"preview_url":{"type":"string"}},"required":["voice_id","name","gender","age","accent","description","preview_url"]}}},"required":["success","total","voices"]},"example":{"success":true,"total":412,"voices":[{"voice_id":"v_9f2c41ab77d0e315","name":"Nova","gender":"female","age":"young","accent":"american","description":"Bright and conversational","preview_url":"https://cdn-crayo.com/voices/v_9f2c41ab77d0e315.mp3"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/voices/languages":{"get":{"operationId":"list-voice-languages","summary":"List voice languages","description":"Lists the languages narration can be generated in. Voices are multilingual: write the script in the language you want and the voice follows it, so this list is for building language pickers rather than for passing a code to another endpoint.","tags":["Catalogs"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"languages":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"]}}},"required":["success","total","languages"]},"example":{"success":true,"total":32,"languages":[{"code":"en","name":"English"},{"code":"es","name":"Spanish"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/subtitle-styles":{"get":{"operationId":"list-subtitle-styles","summary":"List subtitle styles","description":"Lists the burned-in subtitle styles you can attach to a project. Pass a style_id from this list as subtitles.style_id when creating or updating a project.","tags":["Catalogs"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"styles":{"type":"array","items":{"type":"object","properties":{"style_id":{"type":"string"},"name":{"type":"string"},"font_family":{"type":"string"},"primary_color":{"type":"string"},"has_background":{"type":"boolean"},"animation":{"type":"string"}},"required":["style_id","name","font_family","primary_color","has_background","animation"]}}},"required":["success","total","styles"]},"example":{"success":true,"total":32,"styles":[{"style_id":"9","name":"Bold Bounce","font_family":"Montserrat","primary_color":"#FFFFFF","has_background":false,"animation":"word"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/music":{"get":{"operationId":"list-music","summary":"List music","description":"Lists background music tracks from the Crayo library. Pass a track_id as music.track_id on a project to score it without uploading your own audio.","tags":["Catalogs"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"genre","in":"query","required":false,"description":"Filter by genre. Use recommended for the curated shortlist.","schema":{"type":"string","enum":["recommended","rap","anime","sad","classical","quirky","chill","vlog"]},"example":"vlog"},{"name":"limit","in":"query","required":false,"description":"Tracks per page. 1 to 100.","schema":{"type":"integer","default":50},"example":25},{"name":"offset","in":"query","required":false,"description":"Number of tracks to skip.","schema":{"type":"integer","default":0},"example":0}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"tracks":{"type":"array","items":{"type":"object","properties":{"track_id":{"type":"string"},"name":{"type":"string"},"genre":{"type":"string"},"duration_seconds":{"type":"integer"},"url":{"type":"string"}},"required":["track_id","name","genre","duration_seconds","url"]}}},"required":["success","total","tracks"]},"example":{"success":true,"total":64,"tracks":[{"track_id":"clq0ax9as00d2udfzijarenj2","name":"Sunday Drive","genre":"vlog","duration_seconds":132,"url":"https://cdn-crayo.com/music/sunday-drive.mp3"}]}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"genre is not one of the supported genres."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/transcripts":{"post":{"operationId":"create-transcript","summary":"Create transcript","description":"Transcribes an audio or video asset you own and returns the full text plus word-level timings in milliseconds. Use it to cut scenes on sentence boundaries, build search indexes, or drive your own caption rendering.\n\nTranscripts are cached on the asset. Asking for the same asset again returns the stored transcript and costs nothing.","tags":["Transcripts"],"x-credits":"1 voiceover credit per second of media","x-rate-limit":{"tier":"heavy","requests_per_second":2,"requests_per_minute":10},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"asset_id":{"type":"string","description":"An audio or video asset you own, with a known duration. At most 30 minutes long."}},"required":["asset_id"],"additionalProperties":false},"example":{"asset_id":"cm7x1k2p40001abcd"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"transcript":{"type":"object","properties":{"asset_id":{"type":"string"},"language":{"type":"string"},"text":{"type":"string"},"words":{"type":"array","items":{"type":"object","properties":{"word":{"type":"string"},"start_ms":{"type":"integer"},"end_ms":{"type":"integer"}},"required":["word","start_ms","end_ms"]}}},"required":["asset_id","language","text","words"]}},"required":["success","transcript"]},"example":{"success":true,"transcript":{"asset_id":"cm7x1k2p40001abcd","language":"en","text":"Three habits that quietly ruin your mornings","words":[{"word":"Three","start_ms":120,"end_ms":410},{"word":"habits","start_ms":410,"end_ms":780}]}}}}},"400":{"description":"INVALID_ASSET_TYPE, MEDIA_DURATION_UNKNOWN, MEDIA_TOO_LONG","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INVALID_ASSET_TYPE":{"summary":"INVALID_ASSET_TYPE","value":{"success":false,"error":{"code":"INVALID_ASSET_TYPE","message":"The asset is an image rather than audio or video."}}},"MEDIA_DURATION_UNKNOWN":{"summary":"MEDIA_DURATION_UNKNOWN","value":{"success":false,"error":{"code":"MEDIA_DURATION_UNKNOWN","message":"The duration could not be read. Upload the file again."}}},"MEDIA_TOO_LONG":{"summary":"MEDIA_TOO_LONG","value":{"success":false,"error":{"code":"MEDIA_TOO_LONG","message":"The media runs longer than 30 minutes."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Your voiceover balance is below the media duration."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No asset with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/projects":{"post":{"operationId":"create-project","summary":"Create project","description":"Builds a project from a scene list plus optional narration, music, and captions. The schema is strict and every field is validated up front, so a project either comes back ready to export or comes back with the exact field that was wrong. Creating a project costs nothing on its own: you pay when you export it.\n\nScenes play in order and may not overlap. The end_ms of the last scene is the length of the finished video.\n\nSet a scene's volume to 0 when it plays under narration, otherwise both audio tracks are heard.\n\nCaptions are timed from the narration track, so subtitles without narration are rejected.\n\nOne create or export runs per account at a time. Serialize your calls rather than firing them in parallel.","tags":["Projects"],"x-credits":"Free, unless captions are enabled. Transcribing the narration costs 1 voiceover credit per second.","x-rate-limit":{"tier":"heavy","requests_per_second":2,"requests_per_minute":10},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Name of the project. Max 200 characters."},"scenes":{"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string","description":"A video or image asset you own."},"start_ms":{"type":"integer","description":"When the scene starts on the timeline. 0 or greater, and never before the previous scene ends."},"end_ms":{"type":"integer","description":"When the scene ends on the timeline. Greater than start_ms, and at most 10 minutes."},"trim_start_ms":{"type":"integer","default":0,"description":"How far into the source video the scene starts playing. Video scenes only. The trimmed window must fit inside the source video."},"volume":{"type":"integer","default":100,"description":"Volume of the scene's own audio. Set 0 to mute the source video under narration. 0 to 100."},"fit":{"type":"string","enum":["cover","contain"],"default":"cover","description":"How the asset fills the vertical canvas. cover scales and center-crops it edge to edge; contain shows the whole frame with black bars."}},"required":["asset_id","start_ms","end_ms"],"additionalProperties":false},"description":"The visual timeline, in order. Each scene shows one asset for a window of the finished video. 1 to 50 scenes. Scenes may not overlap, and the last end_ms sets the video length."},"narration":{"type":"object","properties":{"asset_id":{"type":"string","description":"An audio asset you own."},"volume":{"type":"integer","default":100,"description":"Narration volume. 0 to 100."}},"required":["asset_id"],"additionalProperties":false,"description":"Voice track that plays across the whole video."},"music":{"type":"object","properties":{"track_id":{"type":"string","description":"A track_id from GET /v1/music."},"asset_id":{"type":"string","description":"An audio asset you own, to use your own music."},"volume":{"type":"integer","default":50,"description":"Music volume. 0 to 100."}},"required":[],"additionalProperties":false,"description":"Background music bed. Pass exactly one of track_id or asset_id."},"texts":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","description":"The words to show. Max 200 characters."},"start_ms":{"type":"integer","description":"When the text appears. 0 or greater."},"end_ms":{"type":"integer","description":"When the text disappears. Greater than start_ms, and no later than the end of the last scene."},"position":{"type":"string","enum":["top","center","bottom"],"default":"top","description":"Where the text sits on the canvas."},"font_size":{"type":"integer","default":75,"description":"Font size in canvas pixels on the 1080 by 1920 frame. 24 to 200."},"color":{"type":"string","default":"#000000","description":"Text color as a hex value."},"background_color":{"type":"string","default":"#ffffff","description":"Color of the rounded card behind the text, as a hex value or transparent."}},"required":["text","start_ms","end_ms"],"additionalProperties":false},"description":"Text overlays such as hooks and calls to action. They use the same title card as the editor, so they stay editable there. Up to 20 entries. Texts may overlap each other and any scene."},"subtitles":{"type":"object","properties":{"style_id":{"type":"string","description":"A style_id from GET /v1/subtitle-styles."},"enabled":{"type":"boolean","default":true,"description":"Set false to keep the style on the project without rendering captions."},"position":{"type":"string","enum":["top","center","bottom"],"default":"center","description":"Where caption lines sit on the canvas."}},"required":["style_id"],"additionalProperties":false,"description":"Burned-in captions, timed from the narration track. Requires narration."}},"required":["title","scenes"],"additionalProperties":false},"example":{"title":"Morning habits short","scenes":[{"asset_id":"cm7x1k2p40001abcd","start_ms":0,"end_ms":4000,"volume":0},{"asset_id":"cm7x1k2p40002abcd","start_ms":4000,"end_ms":11500,"trim_start_ms":2000,"volume":0,"fit":"cover"}],"narration":{"asset_id":"cm7x1j5bb0002abcd","volume":100},"music":{"track_id":"clq0ax9as00d2udfzijarenj2","volume":35},"texts":[{"text":"3 habits that changed my mornings","start_ms":0,"end_ms":3000,"position":"top"}],"subtitles":{"style_id":"9","enabled":true,"position":"bottom"}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"project":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"duration_ms":{"type":"integer"},"scene_count":{"type":"integer"},"created_at":{"type":"string"},"edit_url":{"type":"string"}},"required":["id","title","duration_ms","scene_count","created_at","edit_url"]}},"required":["success","project"]},"example":{"success":true,"project":{"id":"cm7x1k9r70004abcd","title":"Morning habits short","duration_ms":11500,"scene_count":2,"created_at":"2026-08-21T14:05:44.000Z","edit_url":"https://crayo.ai/edit/cm7x1k9r70004abcd"}}}}},"400":{"description":"UNKNOWN_FIELD, VALIDATION_ERROR, INVALID_SUBTITLE_STYLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field the schema does not define."}}},"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A scene overlaps, runs past the source, or breaks a range; a text runs past the last scene or uses a bad color."}}},"INVALID_SUBTITLE_STYLE":{"summary":"INVALID_SUBTITLE_STYLE","value":{"success":false,"error":{"code":"INVALID_SUBTITLE_STYLE","message":"subtitles.style_id is not in the style catalog."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Captions are on and the transcript cannot be paid for."}}}}}}},"403":{"description":"PROJECT_LIMIT_REACHED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"PROJECT_LIMIT_REACHED":{"summary":"PROJECT_LIMIT_REACHED","value":{"success":false,"error":{"code":"PROJECT_LIMIT_REACHED","message":"You already have 200 projects."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"A referenced asset or music track does not belong to your account."}}}}}}},"429":{"description":"CONCURRENT_REQUEST, RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"CONCURRENT_REQUEST":{"summary":"CONCURRENT_REQUEST","value":{"success":false,"error":{"code":"CONCURRENT_REQUEST","message":"Another create or export for this account is still in flight."}}},"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"get":{"operationId":"list-projects","summary":"List projects","description":"Lists every project on the account, newest first, including ones made in the Crayo editor and clips produced by AutoClip. The source field tells you which is which: api for projects this API created, app for everything else.\n\nBecause app projects are listed too, anything made in the editor or by AutoClip can be exported through this API.","tags":["Projects"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"limit","in":"query","required":false,"description":"Projects per page. 1 to 100.","schema":{"type":"integer","default":25},"example":25},{"name":"offset","in":"query","required":false,"description":"Number of projects to skip.","schema":{"type":"integer","default":0},"example":0}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"hasMore":{"type":"boolean"},"projects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"thumbnail_url":{"type":"string"},"duration_ms":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"source":{"type":"string"}},"required":["id","title","thumbnail_url","duration_ms","created_at","updated_at","source"]}}},"required":["success","total","hasMore","projects"]},"example":{"success":true,"total":42,"hasMore":true,"projects":[{"id":"cm7x1k9r70004abcd","title":"Morning habits short","thumbnail_url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/9f1.../thumb.jpg","duration_ms":11500,"created_at":"2026-08-21T14:05:44.000Z","updated_at":"2026-08-21T14:05:44.000Z","source":"api"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/projects/{id}":{"get":{"operationId":"get-project","summary":"Get project","description":"Returns one project. Projects this API created also return the spec they were built from, which makes it easy to read the current state, change one field, and send it back with PATCH.","tags":["Projects"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"id","in":"path","required":true,"description":"The project id.","schema":{"type":"string"},"example":"cm7x1k9r70004abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"project":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"thumbnail_url":{"type":"string"},"duration_ms":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"source":{"type":"string"},"spec":{"type":"object","properties":{"title":{"type":"string"},"scenes":{"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string"},"start_ms":{"type":"integer"},"end_ms":{"type":"integer"},"volume":{"type":"integer"}},"required":["asset_id","start_ms","end_ms","volume"]}},"narration":{"type":"object","properties":{"asset_id":{"type":"string"},"volume":{"type":"integer"}},"required":["asset_id","volume"]},"music":{"type":"object","properties":{"track_id":{"type":"string"},"volume":{"type":"integer"}},"required":["track_id","volume"]},"texts":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string"},"start_ms":{"type":"integer"},"end_ms":{"type":"integer"},"position":{"type":"string"}},"required":["text","start_ms","end_ms","position"]}},"subtitles":{"type":"object","properties":{"style_id":{"type":"string"},"enabled":{"type":"boolean"},"position":{"type":"string"}},"required":["style_id","enabled","position"]}},"required":["title","scenes","narration","music","texts","subtitles"]}},"required":["id","title","thumbnail_url","duration_ms","created_at","updated_at","source","spec"]}},"required":["success","project"]},"example":{"success":true,"project":{"id":"cm7x1k9r70004abcd","title":"Morning habits short","thumbnail_url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/9f1.../thumb.jpg","duration_ms":11500,"created_at":"2026-08-21T14:05:44.000Z","updated_at":"2026-08-21T14:05:44.000Z","source":"api","spec":{"title":"Morning habits short","scenes":[{"asset_id":"cm7x1k2p40001abcd","start_ms":0,"end_ms":4000,"volume":0},{"asset_id":"cm7x1k2p40002abcd","start_ms":4000,"end_ms":11500,"trim_start_ms":2000,"volume":0,"fit":"cover"}],"narration":{"asset_id":"cm7x1j5bb0002abcd","volume":100},"music":{"track_id":"clq0ax9as00d2udfzijarenj2","volume":35},"texts":[{"text":"3 habits that changed my mornings","start_ms":0,"end_ms":3000,"position":"top"}],"subtitles":{"style_id":"9","enabled":true,"position":"bottom"}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No project with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"patch":{"operationId":"update-project","summary":"Update project","description":"Changes a project in place. Send only the fields you want to change: they are merged over the stored spec and the whole result is validated again. Sending a field as null removes it, which is how you drop music or captions.\n\nThe title can be changed on any project. Scenes, narration, music, texts, and subtitles can only be changed on projects this API created.\n\nEditor projects and AutoClip clips can still be renamed and exported through the API.","tags":["Projects"],"x-credits":"Free, unless the change re-times captions against narration that has not been transcribed yet.","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The project id.","schema":{"type":"string"},"example":"cm7x1k9r70004abcd"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Name of the project. Max 200 characters."},"scenes":{"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string","description":"A video or image asset you own."},"start_ms":{"type":"integer","description":"When the scene starts on the timeline. 0 or greater, and never before the previous scene ends."},"end_ms":{"type":"integer","description":"When the scene ends on the timeline. Greater than start_ms, and at most 10 minutes."},"trim_start_ms":{"type":"integer","default":0,"description":"How far into the source video the scene starts playing. Video scenes only. The trimmed window must fit inside the source video."},"volume":{"type":"integer","default":100,"description":"Volume of the scene's own audio. Set 0 to mute the source video under narration. 0 to 100."},"fit":{"type":"string","enum":["cover","contain"],"default":"cover","description":"How the asset fills the vertical canvas. cover scales and center-crops it edge to edge; contain shows the whole frame with black bars."}},"required":["asset_id","start_ms","end_ms"],"additionalProperties":false},"description":"The visual timeline, in order. Each scene shows one asset for a window of the finished video. 1 to 50 scenes. Scenes may not overlap, and the last end_ms sets the video length."},"narration":{"type":"object","properties":{"asset_id":{"type":"string","description":"An audio asset you own."},"volume":{"type":"integer","default":100,"description":"Narration volume. 0 to 100."}},"required":["asset_id"],"additionalProperties":false,"description":"Voice track that plays across the whole video."},"music":{"type":"object","properties":{"track_id":{"type":"string","description":"A track_id from GET /v1/music."},"asset_id":{"type":"string","description":"An audio asset you own, to use your own music."},"volume":{"type":"integer","default":50,"description":"Music volume. 0 to 100."}},"required":[],"additionalProperties":false,"description":"Background music bed. Pass exactly one of track_id or asset_id."},"texts":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","description":"The words to show. Max 200 characters."},"start_ms":{"type":"integer","description":"When the text appears. 0 or greater."},"end_ms":{"type":"integer","description":"When the text disappears. Greater than start_ms, and no later than the end of the last scene."},"position":{"type":"string","enum":["top","center","bottom"],"default":"top","description":"Where the text sits on the canvas."},"font_size":{"type":"integer","default":75,"description":"Font size in canvas pixels on the 1080 by 1920 frame. 24 to 200."},"color":{"type":"string","default":"#000000","description":"Text color as a hex value."},"background_color":{"type":"string","default":"#ffffff","description":"Color of the rounded card behind the text, as a hex value or transparent."}},"required":["text","start_ms","end_ms"],"additionalProperties":false},"description":"Text overlays such as hooks and calls to action. They use the same title card as the editor, so they stay editable there. Up to 20 entries. Texts may overlap each other and any scene."},"subtitles":{"type":"object","properties":{"style_id":{"type":"string","description":"A style_id from GET /v1/subtitle-styles."},"enabled":{"type":"boolean","default":true,"description":"Set false to keep the style on the project without rendering captions."},"position":{"type":"string","enum":["top","center","bottom"],"default":"center","description":"Where caption lines sit on the canvas."}},"required":["style_id"],"additionalProperties":false,"description":"Burned-in captions, timed from the narration track. Requires narration."}},"required":["scenes"],"additionalProperties":false},"example":{"title":"Morning habits short v2","music":{"track_id":"clq0ax9as00d2udfzijarenj2","volume":20}}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"project":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"duration_ms":{"type":"integer"},"scene_count":{"type":"integer"},"created_at":{"type":"string"},"edit_url":{"type":"string"}},"required":["id","title","duration_ms","scene_count","created_at","edit_url"]}},"required":["success","project"]},"example":{"success":true,"project":{"id":"cm7x1k9r70004abcd","title":"Morning habits short v2","duration_ms":11500,"scene_count":2,"created_at":"2026-08-21T14:05:44.000Z","edit_url":"https://crayo.ai/edit/cm7x1k9r70004abcd"}}}}},"400":{"description":"UNKNOWN_FIELD, VALIDATION_ERROR, INVALID_SUBTITLE_STYLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field the schema does not define."}}},"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A scene overlaps, runs past the source, or breaks a range; a text runs past the last scene or uses a bad color."}}},"INVALID_SUBTITLE_STYLE":{"summary":"INVALID_SUBTITLE_STYLE","value":{"success":false,"error":{"code":"INVALID_SUBTITLE_STYLE","message":"subtitles.style_id is not in the style catalog."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"A referenced asset or music track does not belong to your account."}}}}}}},"409":{"description":"NOT_API_PROJECT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_API_PROJECT":{"summary":"NOT_API_PROJECT","value":{"success":false,"error":{"code":"NOT_API_PROJECT","message":"The project was made in the editor, so its content cannot be rewritten here."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"delete":{"operationId":"delete-project","summary":"Delete project","description":"Permanently deletes a project. Videos already exported from it are separate assets and stay in your library.","tags":["Projects"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The project id.","schema":{"type":"string"},"example":"cm7x1k9r70004abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"example":{"success":true}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No project with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/projects/{id}/export":{"post":{"operationId":"export-project","summary":"Export project","description":"Queues a render of the project and returns immediately with an export id. Credits are charged at this moment, based on the length of the finished video. Register an export.completed webhook to be told when the file is ready.\n\nAny project on the account can be exported, including editor projects and AutoClip clips.\n\nCredits are charged when the render is queued and stay spent if the render fails.","tags":["Projects"],"x-credits":"1 export credit per second of finished video","x-rate-limit":{"tier":"heavy","requests_per_second":2,"requests_per_minute":10},"parameters":[{"name":"id","in":"path","required":true,"description":"The project id.","schema":{"type":"string"},"example":"cm7x1k9r70004abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"export":{"type":"object","properties":{"id":{"type":"string"},"project_id":{"type":"string"},"status":{"type":"string"},"credits_charged":{"type":"integer"}},"required":["id","project_id","status","credits_charged"]}},"required":["success","export"]},"example":{"success":true,"export":{"id":"cm7x1kb2p0007abcd","project_id":"cm7x1k9r70004abcd","status":"queued","credits_charged":12}}}}},"400":{"description":"EMPTY_PROJECT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"EMPTY_PROJECT":{"summary":"EMPTY_PROJECT","value":{"success":false,"error":{"code":"EMPTY_PROJECT","message":"The project has no content to render."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Your export balance is below the video length."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No project with that id belongs to your account."}}}}}}},"429":{"description":"EXPORT_LIMIT_REACHED, CONCURRENT_REQUEST, RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"EXPORT_LIMIT_REACHED":{"summary":"EXPORT_LIMIT_REACHED","value":{"success":false,"error":{"code":"EXPORT_LIMIT_REACHED","message":"You already have 2 exports running."}}},"CONCURRENT_REQUEST":{"summary":"CONCURRENT_REQUEST","value":{"success":false,"error":{"code":"CONCURRENT_REQUEST","message":"Another create or export for this account is still in flight."}}},"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/exports":{"get":{"operationId":"list-exports","summary":"List exports","description":"Lists renders on the account, newest first, with their status and progress. Filter by project_id to see every render of one project.","tags":["Exports"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"project_id","in":"query","required":false,"description":"Only return renders of this project.","schema":{"type":"string"},"example":"cm7x1k9r70004abcd"},{"name":"limit","in":"query","required":false,"description":"Exports per page. 1 to 100.","schema":{"type":"integer","default":25},"example":25},{"name":"offset","in":"query","required":false,"description":"Number of exports to skip.","schema":{"type":"integer","default":0},"example":0}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"hasMore":{"type":"boolean"},"exports":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"project_id":{"type":"string"},"status":{"type":"string"},"progress":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","project_id","status","progress","created_at"]}}},"required":["success","total","hasMore","exports"]},"example":{"success":true,"total":8,"hasMore":false,"exports":[{"id":"cm7x1kb2p0007abcd","project_id":"cm7x1k9r70004abcd","status":"processing","progress":62,"created_at":"2026-08-21T14:06:03.000Z"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/exports/{id}":{"get":{"operationId":"get-export","summary":"Get export","description":"Returns one render. Status moves through queued, processing, and then completed or failed. Once it completes, the response also carries the finished video asset with a downloadable url.\n\nWebhooks are the recommended way to learn that a render finished. Polling here is the fallback when you cannot receive one.\n\nA failed export carries an error field with a plain-language reason. Credits stay spent.","tags":["Exports"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"id","in":"path","required":true,"description":"The export id returned by POST /v1/projects/{id}/export.","schema":{"type":"string"},"example":"cm7x1kb2p0007abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"export":{"type":"object","properties":{"id":{"type":"string"},"project_id":{"type":"string"},"status":{"type":"string"},"progress":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","project_id","status","progress","created_at"]},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","width","height","createdAt"]}},"required":["success","export","asset"]},"example":{"success":true,"export":{"id":"cm7x1kb2p0007abcd","project_id":"cm7x1k9r70004abcd","status":"completed","progress":100,"created_at":"2026-08-21T14:06:03.000Z"},"asset":{"id":"cm7x1kd440009abcd","name":"Morning habits short","key":"user-uploads/cm7x0v8qa0000abcd/3a7.../video.mp4","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/3a7.../video.mp4","type":"video","category":"export","length":11.5,"size":4823104,"width":1080,"height":1920,"createdAt":"2026-08-21T14:07:51.000Z"}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No export with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/autoclip":{"post":{"operationId":"create-autoclip","summary":"Create AutoClip job","description":"Finds the strongest moments in a long video you own and turns each one into a vertical short, cropped to the speaker and captioned. The job runs in the background and every finished clip becomes a project on your account, so you can export clips through the same export endpoint as anything else.\n\nenergy mode only works with edit_level clips, because captions and cropping both need speech.\n\nCredits are charged for the clips you asked for when the job starts, and stay spent if the job finds fewer.","tags":["AutoClip"],"x-credits":"1 video credit per requested clip, charged when the job starts","x-rate-limit":{"tier":"heavy","requests_per_second":2,"requests_per_minute":10},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"asset_id":{"type":"string","description":"A video asset you own to pull clips from. Between 1 minute and 3 hours long."},"clip_count":{"type":"integer","default":5,"description":"How many clips to look for. 2 to 20."},"clip_length":{"type":"integer","enum":["30","60","90"],"default":60,"description":"Target clip length in seconds. Clips still end on natural sentence boundaries."},"edit_level":{"type":"string","enum":["clips","captions","cropped","full"],"default":"full","description":"How much editing to apply: clips cuts only, captions adds subtitles, cropped reframes to vertical, full does both."},"formats":{"type":"array","items":{"type":"string","enum":["streamer","split","black-box","title-subtitles","full-video"]},"default":"[\"streamer\"]","description":"Layouts to render each clip in. 1 to 5 unique values."},"prompt":{"type":"string","description":"Steer what counts as a good moment, for example focus on product demos. Max 500 characters."},"mode":{"type":"string","enum":["speech","energy"],"default":"speech","description":"How moments are found. speech reads the transcript, energy follows audio intensity for footage with little dialogue."},"language":{"type":"string","enum":["en","af","ar","hy","be","bn","bs","bg","ca","zh","hr","cs","da","nl","et","tl","fi","fr","ka","de","el","gu","he","hi","hu","id","it","ja","kn","kk","ko","lv","lt","mk","ms","mr","ne","no","fa","pl","pt","pa","ro","ru","sr","sk","sl","es","sv","ta","te","th","tr","uk","ur","vi"],"description":"Spoken language of the source. Defaults to automatic detection, which can pick the wrong language on videos with a dubbed audio track."}},"required":["asset_id"],"additionalProperties":false},"example":{"asset_id":"cm7x1k2p40001abcd","clip_count":5,"clip_length":60,"edit_level":"full"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"autoclip":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"clip_count":{"type":"integer"},"credits_charged":{"type":"integer"}},"required":["id","status","clip_count","credits_charged"]}},"required":["success","autoclip"]},"example":{"success":true,"autoclip":{"id":"cm7x1m8880001abcd","status":"queued","clip_count":5,"credits_charged":5}}}}},"400":{"description":"UNKNOWN_FIELD, VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field this endpoint does not accept."}}},"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The asset is not a video, the source is too short or too long, or an option is out of range."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Your video balance is below clip_count."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No asset with that id belongs to your account."}}}}}}},"429":{"description":"JOB_LIMIT_REACHED, RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"JOB_LIMIT_REACHED":{"summary":"JOB_LIMIT_REACHED","value":{"success":false,"error":{"code":"JOB_LIMIT_REACHED","message":"You already have 3 AutoClip jobs running."}}},"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"get":{"operationId":"list-autoclips","summary":"List AutoClip jobs","description":"Lists AutoClip jobs on the account, newest first, with the stage each one is in and how many clips are ready so far.","tags":["AutoClip"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"limit","in":"query","required":false,"description":"Jobs per page. 1 to 100.","schema":{"type":"integer","default":25},"example":25},{"name":"offset","in":"query","required":false,"description":"Number of jobs to skip.","schema":{"type":"integer","default":0},"example":0}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"hasMore":{"type":"boolean"},"autoclips":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"stage":{"type":"string"},"progress":{"type":"integer"},"clip_count":{"type":"integer"},"clips_ready":{"type":"integer"},"created_at":{"type":"string"}},"required":["id","status","stage","progress","clip_count","clips_ready","created_at"]}}},"required":["success","total","hasMore","autoclips"]},"example":{"success":true,"total":3,"hasMore":false,"autoclips":[{"id":"cm7x1m8880001abcd","status":"processing","stage":"editing","progress":55,"clip_count":5,"clips_ready":2,"created_at":"2026-08-21T15:11:02.000Z"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/autoclip/{id}":{"get":{"operationId":"get-autoclip","summary":"Get AutoClip job","description":"Returns one AutoClip job and the clips it has finished. Each clip carries a project_id, which is what you pass to the export endpoint to render and download it.\n\nRegister autoclip.completed and autoclip.failed webhooks instead of polling this endpoint on a timer.","tags":["AutoClip"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"id","in":"path","required":true,"description":"The AutoClip job id.","schema":{"type":"string"},"example":"cm7x1m8880001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"autoclip":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"stage":{"type":"string"},"progress":{"type":"integer"},"clip_count":{"type":"integer"},"created_at":{"type":"string"},"clips":{"type":"array","items":{"type":"object","properties":{"project_id":{"type":"string"},"title":{"type":"string"},"thumbnail_url":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["project_id","title","thumbnail_url","duration_ms"]}}},"required":["id","status","stage","progress","clip_count","created_at","clips"]}},"required":["success","autoclip"]},"example":{"success":true,"autoclip":{"id":"cm7x1m8880001abcd","status":"completed","stage":"finalizing","progress":100,"clip_count":5,"created_at":"2026-08-21T15:11:02.000Z","clips":[{"project_id":"cm7x1n0120003abcd","title":"The habit that costs you an hour","thumbnail_url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/6b2.../thumb.jpg","duration_ms":58400}]}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No AutoClip job with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/speech-enhancer":{"post":{"operationId":"create-enhancement","summary":"Create enhancement","description":"Cleans up the speech in an audio or video asset you own. The job runs on GPU in the background and separates the recording into three stems: the cleaned voice, any music, and the room tone and ambience. Poll the job or subscribe to speech_enhancer.completed, then export the mix you want with the levels you want.\n\nA typical recording finishes in one to three minutes.\n\nCredits are charged when the job starts and stay spent if it fails.","tags":["Speech Enhancer"],"x-credits":"1 voiceover credit per second of the source asset, charged when the job starts","x-rate-limit":{"tier":"heavy","requests_per_second":2,"requests_per_minute":10},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"asset_id":{"type":"string","description":"An audio or video asset you own, with a known duration. Up to 10 minutes long. Duration drives the credit charge, so assets with unknown length are rejected."}},"required":["asset_id"],"additionalProperties":false},"example":{"asset_id":"cm7x1k2p40001abcd"}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"enhancement":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"credits_charged":{"type":"integer"}},"required":["id","status","credits_charged"]}},"required":["success","enhancement"]},"example":{"success":true,"enhancement":{"id":"cm7x1p4e10002abcd","status":"queued","credits_charged":72}}}}},"400":{"description":"UNKNOWN_FIELD, INVALID_ASSET_TYPE, INVALID_ASSET, VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field this endpoint does not accept."}}},"INVALID_ASSET_TYPE":{"summary":"INVALID_ASSET_TYPE","value":{"success":false,"error":{"code":"INVALID_ASSET_TYPE","message":"The asset is an image rather than audio or video."}}},"INVALID_ASSET":{"summary":"INVALID_ASSET","value":{"success":false,"error":{"code":"INVALID_ASSET","message":"The asset has no known duration. Upload it again."}}},"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The source is longer than 10 minutes."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Your voiceover balance is below the media duration."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No asset with that id belongs to your account."}}}}}}},"429":{"description":"JOB_LIMIT_REACHED, RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"JOB_LIMIT_REACHED":{"summary":"JOB_LIMIT_REACHED","value":{"success":false,"error":{"code":"JOB_LIMIT_REACHED","message":"You already have 8 enhancements running."}}},"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"get":{"operationId":"list-enhancements","summary":"List enhancements","description":"Lists enhancements on the account, newest first, with the stage and progress of each.","tags":["Speech Enhancer"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size. 1 to 100.","schema":{"type":"integer","default":25},"example":25},{"name":"offset","in":"query","required":false,"description":"Skip this many, newest first.","schema":{"type":"integer","default":0},"example":0}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"total":{"type":"integer"},"hasMore":{"type":"boolean"},"enhancements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"progress":{"type":"integer"},"asset_id":{"type":"string"},"created_at":{"type":"string"}},"required":["id","status","progress","asset_id","created_at"]}}},"required":["success","total","hasMore","enhancements"]},"example":{"success":true,"total":2,"hasMore":false,"enhancements":[{"id":"cm7x1p4e10002abcd","status":"completed","progress":100,"asset_id":"cm7x1k2p40001abcd","created_at":"2026-09-06T21:38:40.000Z"},{"id":"cm7x1p4e10002abcd","status":"processing","progress":30,"asset_id":"cm7x1k2p40001abcd","created_at":"2026-09-06T21:38:40.000Z","stage":"Enhancing speech"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/speech-enhancer/{id}":{"get":{"operationId":"get-enhancement","summary":"Get enhancement","description":"Returns one enhancement. Once it has completed, the response carries a URL for each stem (lossless WAV plus a small AAC preview), the current levels, and every export made from it.\n\nStems are the building blocks: mix them yourself, or call the export endpoint and let us render the mix.\n\nA failed enhancement carries an error string and no stems.","tags":["Speech Enhancer"],"x-credits":"Free","x-rate-limit":{"tier":"polling","requests_per_second":2,"requests_per_minute":120},"parameters":[{"name":"id","in":"path","required":true,"description":"The enhancement id returned when the job was created.","schema":{"type":"string"},"example":"cm7x1p4e10002abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"enhancement":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"progress":{"type":"integer"},"asset_id":{"type":"string"},"created_at":{"type":"string"},"source":{"type":"object","properties":{"asset_id":{"type":"string"},"type":{"type":"string"},"duration_ms":{"type":"integer"}},"required":["asset_id","type","duration_ms"]},"credits_charged":{"type":"integer"},"levels":{"type":"object","properties":{"speech":{"type":"integer"},"music":{"type":"number"},"background":{"type":"number"}},"required":["speech","music","background"]},"stems":{"type":"object","properties":{"speech":{"type":"object","properties":{"url":{"type":"string"},"preview_url":{"type":"string"}},"required":["url","preview_url"]},"music":{"type":"object","properties":{"url":{"type":"string"},"preview_url":{"type":"string"}},"required":["url","preview_url"]},"background":{"type":"object","properties":{"url":{"type":"string"},"preview_url":{"type":"string"}},"required":["url","preview_url"]},"original":{"type":"object","properties":{"url":{"type":"string"},"preview_url":{"type":"string"}},"required":["url","preview_url"]}},"required":["speech","music","background","original"]},"exports":{"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string"},"format":{"type":"string"},"levels":{"type":"object","properties":{"speech":{"type":"integer"},"music":{"type":"number"},"background":{"type":"number"}},"required":["speech","music","background"]},"url":{"type":"string"},"created_at":{"type":"string"}},"required":["asset_id","format","levels","url","created_at"]}}},"required":["id","status","progress","asset_id","created_at","source","credits_charged","levels","stems","exports"]}},"required":["success","enhancement"]},"example":{"success":true,"enhancement":{"id":"cm7x1p4e10002abcd","status":"completed","progress":100,"asset_id":"cm7x1k2p40001abcd","created_at":"2026-09-06T21:38:40.000Z","source":{"asset_id":"cm7x1k2p40001abcd","type":"video","duration_ms":71200},"credits_charged":72,"levels":{"speech":1,"music":0.1,"background":0.1},"stems":{"speech":{"url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/speech.wav","preview_url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/speech.m4a"},"music":{"url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/music.wav","preview_url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/music.m4a"},"background":{"url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/background.wav","preview_url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/background.m4a"},"original":{"url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/original.wav","preview_url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/cm7x1p4e10002abcd/original.m4a"}},"exports":[{"asset_id":"cm7x1p9k70005abcd","format":"mp4","levels":{"speech":1,"music":0.1,"background":0.1},"url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/6b1.../enhanced.mp4","created_at":"2026-09-06T21:41:09.000Z"}]}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No enhancement with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"delete":{"operationId":"delete-enhancement","summary":"Delete enhancement","description":"Removes an enhancement and its stems. A queued job is canceled first. Exports already made from it stay in your library, and so does the source asset.","tags":["Speech Enhancer"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The enhancement id returned when the job was created.","schema":{"type":"string"},"example":"cm7x1p4e10002abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"example":{"success":true}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No enhancement with that id belongs to your account."}}}}}}},"409":{"description":"JOB_IN_PROGRESS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"JOB_IN_PROGRESS":{"summary":"JOB_IN_PROGRESS","value":{"success":false,"error":{"code":"JOB_IN_PROGRESS","message":"The enhancement is still running."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/speech-enhancer/{id}/export":{"post":{"operationId":"export-enhancement","summary":"Export a mix","description":"Renders the three stems at the levels you give and returns the finished file as an asset. Video sources come back as the original video with the new audio in place; audio sources come back as WAV by default. Identical levels reuse the earlier export instead of rendering again.\n\nThe request blocks for the few seconds the render takes, so the asset is in the response and appears in your library at once.\n\nLevels you send are saved on the enhancement and become the default for later exports.","tags":["Speech Enhancer"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The enhancement id returned when the job was created.","schema":{"type":"string"},"example":"cm7x1p4e10002abcd"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"speech":{"type":"number","description":"Level of the cleaned voice. 0 to 2. 1 keeps the stem at its processed level; 0 removes it."},"music":{"type":"number","description":"Level of any music separated from the recording. 0 to 2. 1 keeps the stem at its processed level; 0 removes it."},"background":{"type":"number","description":"Level of room tone and ambience. 0 to 2. 1 keeps the stem at its processed level; 0 removes it."},"format":{"type":"string","enum":["mp4","wav","mp3"],"default":"mp4 for video, wav for audio","description":"Container for the export. Video sources always export as mp4."}},"required":[],"additionalProperties":false},"example":{"speech":1,"music":0.1,"background":0.1}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"levels":{"type":"object","properties":{"speech":{"type":"integer"},"music":{"type":"number"},"background":{"type":"number"}},"required":["speech","music","background"]},"asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"url":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"length":{"type":"number"},"size":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"createdAt":{"type":"string"}},"required":["id","name","key","url","type","category","length","size","width","height","createdAt"]}},"required":["success","levels","asset"]},"example":{"success":true,"levels":{"speech":1,"music":0.1,"background":0.1},"asset":{"id":"cm7x1p9k70005abcd","name":"Founder interview (enhanced)","key":"user-uploads/cm7x0v8qa0000abcd/6b1.../enhanced.mp4","url":"https://cdn-crayo.com/user-uploads/cm7x0v8qa0000abcd/6b1.../enhanced.mp4","type":"video","category":"enhanced-speech","length":71.2,"size":32653494,"width":1080,"height":1920,"createdAt":"2026-09-06T21:41:09.000Z"}}}}},"400":{"description":"UNKNOWN_FIELD, VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field this endpoint does not accept."}}},"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A level is out of range, or format mp4 was asked of an audio source."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No enhancement with that id belongs to your account."}}}}}}},"409":{"description":"NOT_READY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_READY":{"summary":"NOT_READY","value":{"success":false,"error":{"code":"NOT_READY","message":"The enhancement has not completed yet."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/profile":{"get":{"operationId":"vt-raw-profile","summary":"Look up a profile","description":"Reads an account live and returns the shared profile object: followers, following, post count, bio and links. Works on all five platforms. Use it to resolve a handle before you track it, or as your own scheduled poll.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","youtube","tiktok","twitter","facebook"]},"example":"instagram"},{"name":"url","in":"query","required":false,"description":"Profile URL. Send url or handle; one of the two is required. Must belong to the platform in the path.","schema":{"type":"string"},"example":"https://www.instagram.com/mornings.with.ada/"},{"name":"handle","in":"query","required":false,"description":"Profile handle without the @, instead of url.","schema":{"type":"string"},"example":"mornings.with.ada"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"profile":{"$ref":"#/components/schemas/Profile"}},"required":["success","profile"]},"example":{"success":true,"profile":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/instagram/profile/posts":{"get":{"operationId":"vt-raw-instagram-posts","summary":"Instagram profile posts","description":"Returns the newest feed posts of an Instagram profile with the profile that owns them. One request for one page: pass limit to choose the page size and cursor to continue. Counts are the platform's numbers right now.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"url","in":"query","required":false,"description":"Profile URL. Send url or handle; one of the two is required. Must belong to the platform in the path.","schema":{"type":"string"},"example":"https://www.instagram.com/mornings.with.ada/"},{"name":"handle","in":"query","required":false,"description":"Profile handle without the @, instead of url.","schema":{"type":"string"},"example":"mornings.with.ada"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 200.","schema":{"type":"integer","default":24}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of items, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"profile":{"$ref":"#/components/schemas/Profile"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","profile","items","pagination"]},"example":{"success":true,"profile":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"},"items":[{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}],"pagination":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/profile/reels":{"get":{"operationId":"vt-raw-reels","summary":"Profile reels","description":"Returns the newest reels of an Instagram profile or Facebook page with the profile that owns them. One request for one page: pass limit to choose the page size and cursor to continue. Counts are the platform's numbers right now.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.\n\nFacebook reels come back without likes, comments or dates: like_count, comment_count and create_time are null on every item, and limit is ignored. Look a reel up with the post endpoint to fill them in.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","facebook"]},"example":"instagram"},{"name":"url","in":"query","required":false,"description":"Profile URL. Send url or handle; one of the two is required. Must belong to the platform in the path.","schema":{"type":"string"},"example":"https://www.instagram.com/mornings.with.ada/"},{"name":"handle","in":"query","required":false,"description":"Profile handle without the @, instead of url.","schema":{"type":"string"},"example":"mornings.with.ada"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 200.","schema":{"type":"integer","default":24}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of items, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"profile":{"$ref":"#/components/schemas/Profile"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","profile","items","pagination"]},"example":{"success":true,"profile":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"},"items":[{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}],"pagination":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/profile/videos":{"get":{"operationId":"vt-raw-videos","summary":"Profile videos","description":"Returns the newest videos of a TikTok profile or YouTube channel with the profile that owns them. One request for one page: pass limit to choose the page size and cursor to continue. Counts are the platform's numbers right now.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["tiktok","youtube"]},"example":"tiktok"},{"name":"url","in":"query","required":false,"description":"Profile URL. Send url or handle; one of the two is required. Must belong to the platform in the path.","schema":{"type":"string"},"example":"https://www.tiktok.com/@mornings.with.ada"},{"name":"handle","in":"query","required":false,"description":"Profile handle without the @, instead of url.","schema":{"type":"string"},"example":"mornings.with.ada"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 200.","schema":{"type":"integer","default":24}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of items, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"profile":{"$ref":"#/components/schemas/Profile"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","profile","items","pagination"]},"example":{"success":true,"profile":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"},"items":[{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}],"pagination":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/youtube/profile/shorts":{"get":{"operationId":"vt-raw-youtube-shorts","summary":"YouTube channel shorts","description":"Returns the newest Shorts of a YouTube channel with the profile that owns them. One request for one page: pass limit to choose the page size and cursor to continue. Counts are the platform's numbers right now.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"url","in":"query","required":false,"description":"Profile URL. Send url or handle; one of the two is required. Must belong to the platform in the path.","schema":{"type":"string"},"example":"https://www.youtube.com/@morningswithada"},{"name":"handle","in":"query","required":false,"description":"Profile handle without the @, instead of url.","schema":{"type":"string"},"example":"mornings.with.ada"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 200.","schema":{"type":"integer","default":24}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of items, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"profile":{"$ref":"#/components/schemas/Profile"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","profile","items","pagination"]},"example":{"success":true,"profile":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"},"items":[{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}],"pagination":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/post":{"get":{"operationId":"vt-raw-post","summary":"Look up a post","description":"Reads one post live and returns the shared post object: views, plays, likes, comments, shares, saves, caption, duration, thumbnail and owner. Works on all five platforms.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","youtube","tiktok","twitter","facebook"]},"example":"instagram"},{"name":"url","in":"query","required":true,"description":"Post URL.","schema":{"type":"string"},"example":"https://www.instagram.com/reel/C9xAbCdEfGh/"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"post":{"$ref":"#/components/schemas/Post"}},"required":["success","post"]},"example":{"success":true,"post":{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/post/comments":{"get":{"operationId":"vt-raw-post-comments","summary":"List post comments","description":"Reads a page of comments on a post. YouTube honours sort; the other platforms return their default order.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","youtube","tiktok"]},"example":"instagram"},{"name":"url","in":"query","required":true,"description":"Post URL.","schema":{"type":"string"},"example":"https://www.instagram.com/reel/C9xAbCdEfGh/"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 100.","schema":{"type":"integer","default":20}},{"name":"sort","in":"query","required":false,"description":"Order of the comments. Only YouTube honours it.","schema":{"type":"string","enum":["top","newest"]}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of comments, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"comments":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","comments","pagination"]},"example":{"success":true,"comments":[{"id":"17912345678901234","text":"Number two is exactly why I never made it to the gym","created_at":"2026-10-13T18:22:10.000Z","like_count":412,"reply_count":9,"is_pinned":false,"is_hearted":true,"author":{"id":"40128839012","username":"late.riser.lena","display_name":"Lena","avatar_url":"https://cdn.example.com/avatars/late.riser.lena.jpg","is_verified":false,"url":"https://www.instagram.com/late.riser.lena/"},"fetched_at":"2026-10-14T09:12:44.000Z"}],"pagination":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/post/status":{"get":{"operationId":"vt-raw-post-status","summary":"Check a post's status","description":"Asks the platform whether a post is still up. Answers with a status instead of failing when the post is gone or hidden, so it is the right call for checking removals.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.\n\nstatus is one of exists, deleted, private, restricted or unknown.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","youtube","tiktok","twitter"]},"example":"instagram"},{"name":"url","in":"query","required":true,"description":"Post URL.","schema":{"type":"string"},"example":"https://www.instagram.com/reel/C9xAbCdEfGh/"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"status":{"type":"string"}},"required":["success","status"]},"example":{"success":true,"status":"exists"}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/youtube/videos":{"get":{"operationId":"vt-raw-youtube-batch","summary":"Look up YouTube videos by id","description":"Reads up to 50 YouTube videos in one request. One credit covers the whole batch.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"ids","in":"query","required":true,"description":"Comma-separated YouTube video ids. 1 to 50 ids, 11 characters each.","schema":{"type":"string"},"example":"dQw4w9WgXcQ,9bZkp7q19f0"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Post"}}},"required":["success","items"]},"example":{"success":true,"items":[{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}]}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/youtube/post/transcript":{"get":{"operationId":"vt-raw-youtube-transcript","summary":"Get a YouTube transcript","description":"Returns the caption track of a YouTube video as timed segments.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"url","in":"query","required":true,"description":"YouTube video URL.","schema":{"type":"string"},"example":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"},{"name":"lang","in":"query","required":false,"description":"Language code of the caption track, for example en or pt-BR.","schema":{"type":"string","default":"en"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"language":{"type":"string"},"segments":{"type":"array","items":{"$ref":"#/components/schemas/TranscriptSegment"}}},"required":["success","language","segments"]},"example":{"success":true,"language":"en","segments":[{"text":"Three habits that quietly ruin your mornings","start_ms":120,"end_ms":2410},{"text":"The first one starts before you wake up","start_ms":2410,"end_ms":4980}]}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The url is not a YouTube video URL, or lang is not a language code."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The video does not exist, or it has no caption track in that language. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/account/about":{"get":{"operationId":"vt-raw-account-about","summary":"Get an account's public bio","description":"Reads the public bio and headline stats of an account. Use it to check that a handle exists before you build on it.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","youtube","tiktok","twitter","facebook"]},"example":"instagram"},{"name":"handle","in":"query","required":true,"description":"Account handle without the @.","schema":{"type":"string"},"example":"mornings.with.ada"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"account":{"$ref":"#/components/schemas/AccountAbout"}},"required":["success","account"]},"example":{"success":true,"account":{"id":"58291034577","display_name":"Ada | Morning routines","bio":"Three habits a week that make your mornings easier.","is_verified":false,"stats":{"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null}}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/account/verify":{"get":{"operationId":"vt-raw-account-verify","summary":"Verify account ownership","description":"Proves that someone controls an account. Ask them to put a one-time code in their bio, then call this with the handle and the code: verified is true when the code is in the bio right now.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","youtube","tiktok","twitter","facebook"]},"example":"instagram"},{"name":"handle","in":"query","required":true,"description":"Account handle without the @.","schema":{"type":"string"},"example":"mornings.with.ada"},{"name":"code","in":"query","required":true,"description":"The code you asked the account owner to add to their bio. 1 to 64 characters, no spaces.","schema":{"type":"string"},"example":"crayo-4F7K2Q"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"verified":{"type":"boolean"},"account":{"$ref":"#/components/schemas/AccountAbout"}},"required":["success","verified","account"]},"example":{"success":true,"verified":true,"account":{"id":"58291034577","display_name":"Ada | Morning routines","bio":"Three habits a week that make your mornings easier.","is_verified":false,"stats":{"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null}}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/profile/followers":{"get":{"operationId":"vt-raw-followers","summary":"List followers","description":"Lists a page of the accounts in a profile's followers list on Instagram or TikTok. One credit per page. Pass cursor to walk the list.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit per page","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","tiktok"]},"example":"instagram"},{"name":"url","in":"query","required":false,"description":"Profile URL. Send url or handle; one of the two is required. Must belong to the platform in the path.","schema":{"type":"string"},"example":"https://www.instagram.com/mornings.with.ada/"},{"name":"handle","in":"query","required":false,"description":"Profile handle without the @, instead of url.","schema":{"type":"string"},"example":"mornings.with.ada"},{"name":"user_id","in":"query","required":false,"description":"Instagram only: the numeric account id from a profile lookup. Sending it saves a call on the first page.","schema":{"type":"string"},"example":"58291034577"},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of accounts, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/AccountSummary"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","items","pagination"]},"example":{"success":true,"items":[{"id":"40128839012","username":"late.riser.lena","display_name":"Lena","avatar_url":"https://cdn.example.com/avatars/late.riser.lena.jpg","is_verified":false,"is_private":false,"url":"https://www.instagram.com/late.riser.lena/"}],"pagination":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/profile/following":{"get":{"operationId":"vt-raw-following","summary":"List following","description":"Lists a page of the accounts in a profile's following list on Instagram or TikTok. One credit per page. Pass cursor to walk the list.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit per page","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","tiktok"]},"example":"instagram"},{"name":"url","in":"query","required":false,"description":"Profile URL. Send url or handle; one of the two is required. Must belong to the platform in the path.","schema":{"type":"string"},"example":"https://www.instagram.com/mornings.with.ada/"},{"name":"handle","in":"query","required":false,"description":"Profile handle without the @, instead of url.","schema":{"type":"string"},"example":"mornings.with.ada"},{"name":"user_id","in":"query","required":false,"description":"Instagram only: the numeric account id from a profile lookup. Sending it saves a call on the first page.","schema":{"type":"string"},"example":"58291034577"},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of accounts, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/AccountSummary"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","items","pagination"]},"example":{"success":true,"items":[{"id":"40128839012","username":"late.riser.lena","display_name":"Lena","avatar_url":"https://cdn.example.com/avatars/late.riser.lena.jpg","is_verified":false,"is_private":false,"url":"https://www.instagram.com/late.riser.lena/"}],"pagination":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is missing, mistyped or out of range, or the cursor is not valid for this request (invalid cursor)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"The profile or post does not exist or was deleted. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/raw/{platform}/history":{"get":{"operationId":"vt-raw-history","summary":"60-day history","description":"Returns the readings we already hold for a profile or post, up to 60 days back, newest first. A profile URL returns profile snapshots and a post URL returns post snapshots. It covers anything any Crayo user has tracked, so a brand new target does not start with an empty chart.\n\nCharged 1 tracker credit before the platform is called. A lookup that fails on our side is refunded; a missing or private target keeps the credit.","tags":["Raw (manage it yourself)"],"x-credits":"1 credit","x-rate-limit":{"tier":"vt-raw","requests_per_second":5,"requests_per_minute":200},"parameters":[{"name":"platform","in":"path","required":true,"description":"Which platform to read.","schema":{"type":"string","enum":["instagram","youtube","tiktok","twitter","facebook"]},"example":"instagram"},{"name":"url","in":"query","required":true,"description":"Profile or post URL.","schema":{"type":"string"},"example":"https://www.instagram.com/reel/C9xAbCdEfGh/"},{"name":"from","in":"query","required":false,"description":"Oldest reading to return. ISO 8601 or Unix seconds.","schema":{"type":"string"},"example":"2026-10-01T00:00:00Z"},{"name":"to","in":"query","required":false,"description":"Newest reading to return. ISO 8601 or Unix seconds.","schema":{"type":"string"},"example":"2026-10-14T00:00:00Z"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"snapshots":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/PostSnapshot"},{"$ref":"#/components/schemas/ProfileSnapshot"}]}}},"required":["success","snapshots"]},"example":{"success":true,"snapshots":[{"observed_at":"2026-10-14T09:12:44.000Z","counts":{"views":1284500,"plays":1284500,"likes":96210,"comments":1430,"shares":8120,"saves":21480}},{"observed_at":"2026-10-13T09:12:44.000Z","counts":{"views":1284500,"plays":1284500,"likes":96210,"comments":1430,"shares":8120,"saves":21480}}]}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The url is missing, or from is after to."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"403":{"description":"TARGET_PRIVATE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TARGET_PRIVATE":{"summary":"TARGET_PRIVATE","value":{"success":false,"error":{"code":"TARGET_PRIVATE","message":"The account or post is private or restricted. The credit is kept."}}}}}}},"404":{"description":"NOT_FOUND, TARGET_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"The platform in the path does not support this lookup. Nothing was charged."}}},"TARGET_NOT_FOUND":{"summary":"TARGET_NOT_FOUND","value":{"success":false,"error":{"code":"TARGET_NOT_FOUND","message":"We hold no readings for that url. The credit is kept."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_ERROR":{"summary":"UPSTREAM_ERROR","value":{"success":false,"error":{"code":"UPSTREAM_ERROR","message":"The platform could not be read. The credit is refunded when the failure was on our side."}}}}}}},"503":{"description":"UPSTREAM_BUSY","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UPSTREAM_BUSY":{"summary":"UPSTREAM_BUSY","value":{"success":false,"error":{"code":"UPSTREAM_BUSY","message":"Lookups are saturated right now. Retry after the Retry-After header. The credit is refunded."}}}}}}}}}},"/v1/view-tracker/trackers":{"post":{"operationId":"vt-create-tracker","summary":"Create a tracker","description":"Starts tracking a profile or a single post. The first refresh runs right away, then every interval_minutes, and every reading is kept. The type is inferred from the URL, so a post URL makes a post tracker.\n\nCreating is free, but the first refresh starts immediately and costs 1 credit, like every refresh after it.\n\nThe tracker comes back with latest set to null. Post trackers usually fill within seconds and profile trackers within a minute or two: wait for the tracker.refreshed webhook, or poll GET /v1/view-tracker/trackers/{id} every few seconds until latest is not null.\n\nIf the first refresh fails, latest stays null and tracker.refresh_failed fires. After 3 failures in a row the tracker pauses with status paused_failing.\n\nA type is inferred from the URL: Instagram /p/, /tv/ and /reel/ links, YouTube watch links and TikTok /video/ links are posts. Send type only to override a URL we cannot classify.\n\nIf you run out of credits the tracker pauses with status paused_no_credits and resumes by itself when credits arrive.","tags":["Managed (our scheduler)"],"x-credits":"0 now, 1 credit per refresh","x-rate-limit":{"tier":"vt-write","requests_per_second":2,"requests_per_minute":60},"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Profile or post URL. Instagram, YouTube, TikTok and Twitter are supported. Send url, or handle with platform."},"type":{"type":"string","enum":["profile","post"],"description":"Force the target type when the URL is ambiguous."},"platform":{"type":"string","enum":["instagram","youtube","tiktok","twitter"],"description":"Required with handle. With a url it must match the url's platform, or the request is a 400."},"handle":{"type":"string","description":"Profile handle, instead of url. Needs platform; a handle without platform is a 400."},"interval_minutes":{"type":"integer","default":1440,"description":"Minutes between refreshes. Each refresh costs 1 credit, so this sets the monthly cost: 43,200 divided by the interval. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440."},"max_posts":{"type":"integer","enum":["50","100","200"],"default":100,"description":"How many of the newest posts a profile tracker keeps up to date. Ignored for post trackers. It does not change the price: a refresh is 1 credit at any depth."}},"required":[],"additionalProperties":false},"example":{"url":"https://www.instagram.com/mornings.with.ada/","interval_minutes":1440,"max_posts":100}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"tracker":{"$ref":"#/components/schemas/Tracker"}},"required":["success","tracker"]},"example":{"success":true,"tracker":{"id":"cm9t3k1r20001abcd","type":"profile","platform":"instagram","url":"https://www.instagram.com/mornings.with.ada/","handle":"mornings.with.ada","status":"active","interval_minutes":1440,"max_posts":100,"next_refresh_at":"2026-10-15T09:12:44.000Z","behind":false,"last_refreshed_at":null,"credits_per_month":30,"credits_spent":0,"refresh_count":0,"created_at":"2026-10-02T14:03:19.000Z","goal_followers":100000,"goal_by":"2026-12-31T00:00:00.000Z","group_name":"Clients","alert_kinds":["viral","milestone"],"latest":null}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The URL does not parse, handle was sent without platform, platform does not match the url, the cadence is outside 10 to 10,080 minutes, or the platform is Facebook (raw mode only)."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field this endpoint does not define."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits to run the first refresh. Buy a pack or wait for your plan to renew."}}}}}}},"409":{"description":"TRACKER_EXISTS, TRACKER_LIMIT_REACHED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"TRACKER_EXISTS":{"summary":"TRACKER_EXISTS","value":{"success":false,"error":{"code":"TRACKER_EXISTS","message":"You already track this target. error.tracker_id is the existing tracker's id."}}},"TRACKER_LIMIT_REACHED":{"summary":"TRACKER_LIMIT_REACHED","value":{"success":false,"error":{"code":"TRACKER_LIMIT_REACHED","message":"You are at your active target limit (500 by default). The error carries active_trackers and cap. Ask in Discord (crayo.ai/discord) or email support@crayo.ai and we will raise it."}}}}}}},"429":{"description":"CONCURRENT_REQUEST, RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"CONCURRENT_REQUEST":{"summary":"CONCURRENT_REQUEST","value":{"success":false,"error":{"code":"CONCURRENT_REQUEST","message":"Another create or batch request for your account is still running. Await it, then retry."}}},"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"get":{"operationId":"vt-list-trackers","summary":"List trackers","description":"Lists your trackers with their latest stored reading. Stored reads are free.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"type","in":"query","required":false,"description":"Only profile or post trackers.","schema":{"type":"string","enum":["profile","post"]}},{"name":"platform","in":"query","required":false,"description":"Only one platform.","schema":{"type":"string","enum":["instagram","youtube","tiktok","twitter"]}},{"name":"status","in":"query","required":false,"description":"Only one status.","schema":{"type":"string","enum":["active","paused","paused_no_credits","paused_failing","paused_dormant"]}},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 100.","schema":{"type":"integer","default":25}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of trackers, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"trackers":{"type":"array","items":{"$ref":"#/components/schemas/Tracker"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","trackers","pagination"]},"example":{"success":true,"trackers":[{"id":"cm9t3k1r20001abcd","type":"profile","platform":"instagram","url":"https://www.instagram.com/mornings.with.ada/","handle":"mornings.with.ada","status":"active","interval_minutes":1440,"max_posts":100,"next_refresh_at":"2026-10-15T09:12:44.000Z","behind":false,"last_refreshed_at":"2026-10-14T09:12:44.000Z","credits_per_month":30,"credits_spent":12,"refresh_count":12,"created_at":"2026-10-02T14:03:19.000Z","goal_followers":100000,"goal_by":"2026-12-31T00:00:00.000Z","group_name":"Clients","alert_kinds":["viral","milestone"],"latest":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored"}},{"id":"cm9t3k1s90002abcd","type":"post","platform":"instagram","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","handle":null,"status":"active","interval_minutes":60,"max_posts":null,"next_refresh_at":"2026-10-14T10:12:44.000Z","behind":false,"last_refreshed_at":"2026-10-14T09:12:44.000Z","credits_per_month":720,"credits_spent":52,"refresh_count":52,"created_at":"2026-10-12T09:00:12.000Z","goal_followers":null,"goal_by":null,"group_name":null,"alert_kinds":["removed"],"latest":{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored"}}],"pagination":{"has_more":false,"next_cursor":null}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A filter value is not one of the allowed options, or the cursor is invalid."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/batch":{"post":{"operationId":"vt-batch-trackers","summary":"Create trackers in a batch","description":"Creates up to 100 trackers in one request, profiles and posts mixed. Top-level interval_minutes and max_posts are the defaults; each target can override them. Every target gets its own result row, so one bad URL does not fail the rest.\n\nEach item has status created, exists, invalid or limit_reached. invalid items carry an error string, for example for a Facebook URL (raw mode only) or an unparseable URL; limit_reached items did not fit under your target limit. The HTTP status is 200 whenever the request itself was accepted.\n\nexists means you already track that target and costs nothing. The existing tracker is left as it is: interval_minutes and max_posts are not changed. Use PATCH to change them.\n\nThe batch response carries ids, not readings. To read many latest values at once, call GET /v1/view-tracker/trackers: every item carries latest, 25 per page by default.\n\nThe batch is refused as a whole when you have fewer available credits than valid targets, so every created tracker can run its first refresh.\n\nusage in the response is the same object GET /v1/view-tracker/usage returns.\n\nCreated trackers have latest set to null until their first refresh finishes (seconds for posts, a minute or two for profiles). Wait for tracker.refreshed, or poll GET /v1/view-tracker/trackers/{id}, before you read a reading.","tags":["Managed (our scheduler)"],"x-credits":"0 now, 1 credit per refresh","x-rate-limit":{"tier":"vt-batch","requests_per_second":1,"requests_per_minute":10},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"targets":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"Profile or post URL. Send url, or handle with platform."},"handle":{"type":"string","description":"Profile handle, instead of url. Needs platform."},"platform":{"type":"string","enum":["instagram","youtube","tiktok","twitter"],"description":"Required with handle. With a url it must match the url's platform."},"type":{"type":"string","enum":["profile","post"],"description":"profile or post, when the URL is ambiguous."},"interval_minutes":{"type":"integer","default":1440,"description":"Overrides the batch default for this target. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440."},"max_posts":{"type":"integer","enum":["50","100","200"],"default":100,"description":"Overrides the batch default for this target."}},"required":[],"additionalProperties":false},"description":"The targets to track, in order. Results come back in the same order. 1 to 100 targets."},"interval_minutes":{"type":"integer","default":1440,"description":"Default cadence for targets that do not set their own. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440."},"max_posts":{"type":"integer","enum":["50","100","200"],"default":100,"description":"Default depth for profile targets that do not set their own."}},"required":["targets"],"additionalProperties":false},"example":{"targets":[{"url":"https://www.instagram.com/mornings.with.ada/"},{"url":"https://www.tiktok.com/@mornings.with.ada","interval_minutes":720},{"url":"https://www.tiktok.com/@mornings.with.ada/video/7412345678901234567","type":"post","interval_minutes":60}],"interval_minutes":1440,"max_posts":100}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/BatchItem"}},"usage":{"$ref":"#/components/schemas/Usage"}},"required":["success","items","usage"]},"example":{"success":true,"items":[{"url":"https://www.instagram.com/mornings.with.ada/","status":"created","id":"cm9t3k1r20001abcd"},{"url":"https://www.tiktok.com/@mornings.with.ada","status":"exists","id":"cm9t3k1s90002abcd"},{"url":"https://www.tiktok.com/@mornings.with.ada/video/7412345678901234567","status":"created","id":"cm9t3k1t40003abcd"}],"usage":{"credits":{"available":1840,"subscription":1340,"purchased":500,"monthly_allotment":2500,"resets_at":"2026-11-03T00:00:00.000Z"},"projected_monthly":750,"active_trackers":{"profile":1,"post":1,"total":2},"cap":{"limit":500,"remaining":498,"raise_via":{"discord":"https://crayo.ai/discord","email":"support@crayo.ai"}}}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"targets is empty or has more than 100 entries, or a default is out of range."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field this endpoint does not define."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"Available credits are fewer than the number of distinct valid targets, counting ones you already track. Nothing is created. The error carries required."}}}}}}},"429":{"description":"CONCURRENT_REQUEST, RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"CONCURRENT_REQUEST":{"summary":"CONCURRENT_REQUEST","value":{"success":false,"error":{"code":"CONCURRENT_REQUEST","message":"Another create or batch request for your account is still running. Await it, then retry."}}},"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/usage":{"get":{"operationId":"vt-usage","summary":"Get tracker usage","description":"Returns your tracker credits, what your active trackers will spend this month at their cadences, how many targets you have and your target limit. Call it before a batch create and when you plan how many packs to buy.\n\nThe credits.tracker balance on GET /v1/account is the same number as credits.available here.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"usage":{"$ref":"#/components/schemas/Usage"}},"required":["success","usage"]},"example":{"success":true,"usage":{"credits":{"available":1840,"subscription":1340,"purchased":500,"monthly_allotment":2500,"resets_at":"2026-11-03T00:00:00.000Z"},"projected_monthly":750,"active_trackers":{"profile":1,"post":1,"total":2},"cap":{"limit":500,"remaining":498,"raise_via":{"discord":"https://crayo.ai/discord","email":"support@crayo.ai"}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}":{"get":{"operationId":"vt-get-tracker","summary":"Get a tracker","description":"Returns one tracker with its latest stored reading. Reading a tracker also tells us you still use it, which keeps it from going dormant.\n\nA tracker nobody has read for 30 days pauses itself with status paused_dormant. Any read of it, through the API or the app, wakes it.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"tracker":{"$ref":"#/components/schemas/Tracker"}},"required":["success","tracker"]},"example":{"success":true,"tracker":{"id":"cm9t3k1r20001abcd","type":"profile","platform":"instagram","url":"https://www.instagram.com/mornings.with.ada/","handle":"mornings.with.ada","status":"active","interval_minutes":1440,"max_posts":100,"next_refresh_at":"2026-10-15T09:12:44.000Z","behind":false,"last_refreshed_at":"2026-10-14T09:12:44.000Z","credits_per_month":30,"credits_spent":12,"refresh_count":12,"created_at":"2026-10-02T14:03:19.000Z","goal_followers":100000,"goal_by":"2026-12-31T00:00:00.000Z","group_name":"Clients","alert_kinds":["viral","milestone"],"latest":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored"}}}}}},"400":{"description":"UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"patch":{"operationId":"vt-update-tracker","summary":"Update a tracker","description":"Changes a tracker's cadence or depth, pauses and resumes it, or sets its goal, group and alerts. Send only the fields you want to change.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-write","requests_per_second":2,"requests_per_minute":60},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"interval_minutes":{"type":"integer","default":1440,"description":"New minutes between refreshes. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440."},"max_posts":{"type":"integer","enum":["50","100","200"],"default":100,"description":"How many of the newest posts a profile tracker keeps up to date. Ignored for post trackers. It does not change the price: a refresh is 1 credit at any depth."},"status":{"type":"string","enum":["active","paused"],"description":"pause with paused, resume with active. Resuming runs a refresh right away."},"goal_followers":{"type":"string","description":"A follower goal, or null to clear it. 0 or more."},"goal_by":{"type":"string","description":"When you want to reach the goal, ISO 8601, or null."},"group_name":{"type":"string","description":"A label to group trackers by, or null. Up to 40 characters."},"alert_kinds":{"type":"array","items":{"type":"string","enum":["viral","milestone","removed","new_post","follower_drop"]},"description":"Which events send a tracker.alert webhook. An empty array turns alerts off."}},"required":[],"additionalProperties":false},"example":{"interval_minutes":60}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"tracker":{"$ref":"#/components/schemas/Tracker"}},"required":["success","tracker"]},"example":{"success":true,"tracker":{"id":"cm9t3k1r20001abcd","type":"profile","platform":"instagram","url":"https://www.instagram.com/mornings.with.ada/","handle":"mornings.with.ada","status":"active","interval_minutes":60,"max_posts":100,"next_refresh_at":"2026-10-15T09:12:44.000Z","behind":false,"last_refreshed_at":"2026-10-14T09:12:44.000Z","credits_per_month":720,"credits_spent":12,"refresh_count":12,"created_at":"2026-10-02T14:03:19.000Z","goal_followers":100000,"goal_by":"2026-12-31T00:00:00.000Z","group_name":"Clients","alert_kinds":["viral","milestone"],"latest":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored"}}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The body is empty, or a value is out of range."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The body carries a field this endpoint does not define."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You tried to resume without any tracker credits."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"delete":{"operationId":"vt-delete-tracker","summary":"Delete a tracker","description":"Stops a tracker and deletes it with every reading we kept. This cannot be undone.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-write","requests_per_second":2,"requests_per_minute":60},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"id":{"type":"string"},"deleted":{"type":"boolean"}},"required":["success","id","deleted"]},"example":{"success":true,"id":"cm9t3k1r20001abcd","deleted":true}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}/refresh":{"post":{"operationId":"vt-refresh-tracker","summary":"Refresh a tracker now","description":"Queues a refresh ahead of schedule. It returns immediately; the result arrives as a tracker.refreshed webhook, or poll last_refreshed_at on the tracker.","tags":["Managed (our scheduler)"],"x-credits":"1 credit, charged when it runs","x-rate-limit":{"tier":"vt-write","requests_per_second":2,"requests_per_minute":60},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"tracker":{"$ref":"#/components/schemas/Tracker"},"refresh":{"type":"object","properties":{"status":{"type":"string"}},"required":["status"]}},"required":["success","tracker","refresh"]},"example":{"success":true,"tracker":{"id":"cm9t3k1r20001abcd","type":"profile","platform":"instagram","url":"https://www.instagram.com/mornings.with.ada/","handle":"mornings.with.ada","status":"active","interval_minutes":1440,"max_posts":100,"next_refresh_at":"2026-10-15T09:12:44.000Z","behind":false,"last_refreshed_at":"2026-10-14T09:12:44.000Z","credits_per_month":30,"credits_spent":12,"refresh_count":12,"created_at":"2026-10-02T14:03:19.000Z","goal_followers":100000,"goal_by":"2026-12-31T00:00:00.000Z","group_name":"Clients","alert_kinds":["viral","milestone"],"latest":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored"}},"refresh":{"status":"queued"}}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The tracker is paused. Resume it with PATCH and status active first."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"402":{"description":"INSUFFICIENT_CREDITS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"INSUFFICIENT_CREDITS":{"summary":"INSUFFICIENT_CREDITS","value":{"success":false,"error":{"code":"INSUFFICIENT_CREDITS","message":"You have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"REFRESH_IN_PROGRESS, RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"REFRESH_IN_PROGRESS":{"summary":"REFRESH_IN_PROGRESS","value":{"success":false,"error":{"code":"REFRESH_IN_PROGRESS","message":"A refresh is already queued or running, or the last attempt was less than 60 seconds ago. The error carries retry_after_seconds, and so does the Retry-After header."}}},"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}/snapshots":{"get":{"operationId":"vt-tracker-snapshots","summary":"List a tracker's snapshots","description":"Returns the stored series of the target itself: profile snapshots (followers, following, posts) for a profile tracker, post snapshots (views, likes, comments and more) for a post tracker. This is your chart data.\n\nReadings are kept hourly for the last 14 days and daily beyond that. Newest first.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"},{"name":"from","in":"query","required":false,"description":"Oldest reading to return, ISO 8601.","schema":{"type":"string"},"example":"2026-10-01T00:00:00Z"},{"name":"to","in":"query","required":false,"description":"Newest reading to return, ISO 8601.","schema":{"type":"string"},"example":"2026-10-14T00:00:00Z"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 500.","schema":{"type":"integer","default":100}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of snapshots, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"snapshots":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/PostSnapshot"},{"$ref":"#/components/schemas/ProfileSnapshot"}]}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","snapshots","pagination"]},"example":{"success":true,"snapshots":[{"observed_at":"2026-10-14T09:12:44.000Z","followers":182400,"following":312,"posts":418,"total_views":null,"total_likes":null}],"pagination":{"has_more":false,"next_cursor":null}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"from, to, limit or cursor is invalid."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}/events":{"get":{"operationId":"vt-tracker-events","summary":"List a tracker's events","description":"What changed on the target between refreshes: new, viral, removed and milestone posts, caption and pin changes, profile edits, follower milestones and drops. Newest first, kept for 90 days.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 200.","schema":{"type":"integer","default":50}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of events, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"events":{"type":"array","items":{"$ref":"#/components/schemas/TrackerEvent"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","events","pagination"]},"example":{"success":true,"events":[{"id":"cm9t3r8v10009abcd","kind":"post.viral","at":"2026-10-14T09:12:44.000Z","post_id":"cm9t3p4q50003abcd","before":null,"after":null,"value":412380}],"pagination":{"has_more":false,"next_cursor":null}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"limit or cursor is invalid."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}/posts":{"get":{"operationId":"vt-tracker-posts","summary":"List a profile tracker's posts","description":"Lists the posts a profile tracker is following, with their latest counts and when each was first and last seen. Removed posts are hidden unless you ask for them.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"},{"name":"sort","in":"query","required":false,"description":"How to order the posts.","schema":{"type":"string","enum":["recent","views","likes","comments","shares"],"default":"recent"}},{"name":"since","in":"query","required":false,"description":"Only posts published at or after this time. ISO 8601 or Unix seconds.","schema":{"type":"string"},"example":"2026-10-01T00:00:00Z"},{"name":"include_removed","in":"query","required":false,"description":"Include posts that were deleted, made private or restricted.","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 200.","schema":{"type":"integer","default":50}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of posts, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"posts":{"type":"array","items":{"$ref":"#/components/schemas/TrackedPost"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","posts","pagination"]},"example":{"success":true,"posts":[{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored","id":"cm9t3p4q50003abcd","first_seen_at":"2026-10-12T09:00:12.000Z","last_seen_at":"2026-10-14T09:12:44.000Z","removed_at":null,"removed_status":null}],"pagination":{"has_more":false,"next_cursor":null}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD, NOT_A_PROFILE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"A parameter is out of range, or the cursor is invalid."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}},"NOT_A_PROFILE":{"summary":"NOT_A_PROFILE","value":{"success":false,"error":{"code":"NOT_A_PROFILE","message":"The tracker follows a single post. Use its snapshots instead."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}/posts/{post_id}":{"get":{"operationId":"vt-tracker-post","summary":"Get a tracked post","description":"Returns one tracked post with the comments we stored for it. The comments array sits inside the post object: up to 20, pinned first, each with the time we fetched it.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"},{"name":"post_id","in":"path","required":true,"description":"The tracked post's id from the posts list (the id field, not the platform's content_id).","schema":{"type":"string"},"example":"cm9t3p4q50003abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"post":{"$ref":"#/components/schemas/TrackedPost"}},"required":["success","post"]},"example":{"success":true,"post":{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored","id":"cm9t3p4q50003abcd","first_seen_at":"2026-10-12T09:00:12.000Z","last_seen_at":"2026-10-14T09:12:44.000Z","removed_at":null,"removed_status":null,"comments":[{"id":"17912345678901234","text":"Number two is exactly why I never made it to the gym","created_at":"2026-10-13T18:22:10.000Z","like_count":412,"reply_count":9,"is_pinned":false,"is_hearted":true,"author":{"id":"40128839012","username":"late.riser.lena","display_name":"Lena","avatar_url":"https://cdn.example.com/avatars/late.riser.lena.jpg","is_verified":false,"url":"https://www.instagram.com/late.riser.lena/"},"fetched_at":"2026-10-14T09:12:44.000Z"}]}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}/posts/{post_id}/snapshots":{"get":{"operationId":"vt-tracker-post-snapshots","summary":"List a tracked post's snapshots","description":"Returns the stored series for one post inside a profile tracker: views, likes, comments, shares and saves over time.\n\nReadings are kept hourly for the last 14 days and daily beyond that. Newest first.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"},{"name":"post_id","in":"path","required":true,"description":"The tracked post's id from the posts list (the id field, not the platform's content_id).","schema":{"type":"string"},"example":"cm9t3p4q50003abcd"},{"name":"from","in":"query","required":false,"description":"Oldest reading to return, ISO 8601.","schema":{"type":"string"},"example":"2026-10-01T00:00:00Z"},{"name":"to","in":"query","required":false,"description":"Newest reading to return, ISO 8601.","schema":{"type":"string"},"example":"2026-10-14T00:00:00Z"},{"name":"limit","in":"query","required":false,"description":"How many items to return. 1 to 500.","schema":{"type":"integer","default":100}},{"name":"cursor","in":"query","required":false,"description":"The pagination.next_cursor of the previous page of snapshots, passed back unchanged. It only works for the same target and route, from the same account.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"snapshots":{"type":"array","items":{"$ref":"#/components/schemas/PostSnapshot"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["success","snapshots","pagination"]},"example":{"success":true,"snapshots":[{"observed_at":"2026-10-14T09:12:44.000Z","counts":{"views":1284500,"plays":1284500,"likes":96210,"comments":1430,"shares":8120,"saves":21480}}],"pagination":{"has_more":false,"next_cursor":null}}}}},"400":{"description":"VALIDATION_ERROR, UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"from, to, limit or cursor is invalid."}}},"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/view-tracker/trackers/{id}/insights":{"get":{"operationId":"vt-tracker-insights","summary":"Get a tracker's insights","description":"Our optional math on top of the stored readings: follower growth over 7 days, posting pace, median views, engagement rate, which posts went viral and how consistent the account is. An empty object for post trackers. Readings elsewhere are never adjusted; this is the only place we interpret them.\n\nA post tracker returns an empty insights object.","tags":["Managed (our scheduler)"],"x-credits":"0, stored","x-rate-limit":{"tier":"vt-read","requests_per_second":5,"requests_per_minute":300},"parameters":[{"name":"id","in":"path","required":true,"description":"The tracker id.","schema":{"type":"string"},"example":"cm9t3k1r20001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"insights":{"$ref":"#/components/schemas/Insights"}},"required":["success","insights"]},"example":{"success":true,"insights":{"followers_delta_7d":2310,"posts_per_week":3.5,"median_views":412000,"engagement_rate":0.083,"viral_post_ids":["cm9t3p4q50003abcd"],"consistency":0.82}}}}},"400":{"description":"UNKNOWN_FIELD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"UNKNOWN_FIELD":{"summary":"UNKNOWN_FIELD","value":{"success":false,"error":{"code":"UNKNOWN_FIELD","message":"The query carries a parameter this endpoint does not define. There is no provider parameter anywhere."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No tracker with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/webhooks":{"post":{"operationId":"create-webhook","summary":"Create webhook","description":"Registers an https endpoint of yours to receive events. The signing secret comes back once, in this response, and is never shown again, so store it before you do anything else.\n\nStore the secret now. Listing webhooks later returns only a masked prefix.","tags":["Webhooks"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public https URL that will receive POST deliveries."},"events":{"type":"array","items":{"type":"string"},"description":"Events to subscribe to. Non-empty. One or more of: export.completed, export.failed, autoclip.completed, autoclip.failed, speech_enhancer.completed, speech_enhancer.failed, tracker.refreshed, tracker.refresh_failed, tracker.paused, tracker.alert, credits.low."}},"required":["url","events"],"additionalProperties":false},"example":{"url":"https://example.com/hooks/crayo","events":["export.completed","export.failed"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"disabled":{"type":"boolean"},"created_at":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","events","disabled","created_at","secret"]}},"required":["success","webhook"]},"example":{"success":true,"webhook":{"id":"cm7x1p4990001abcd","url":"https://example.com/hooks/crayo","events":["export.completed","export.failed"],"disabled":false,"created_at":"2026-08-21T13:58:20.000Z","secret":"crayo_whsec_8Kd2mQ1rXv7pLb0aY3sTuW9e"}}}}},"400":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"VALIDATION_ERROR":{"summary":"VALIDATION_ERROR","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"The URL is not a valid public https address, or an event name is unknown."}}}}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"409":{"description":"WEBHOOK_LIMIT_REACHED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"WEBHOOK_LIMIT_REACHED":{"summary":"WEBHOOK_LIMIT_REACHED","value":{"success":false,"error":{"code":"WEBHOOK_LIMIT_REACHED","message":"You already have 5 endpoints registered."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}},"get":{"operationId":"list-webhooks","summary":"List webhooks","description":"Lists your registered endpoints, the events each one is subscribed to, and whether it has been disabled after repeated delivery failures. Secrets are masked.","tags":["Webhooks"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"webhooks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"disabled":{"type":"boolean"},"created_at":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","events","disabled","created_at","secret"]}}},"required":["success","webhooks"]},"example":{"success":true,"webhooks":[{"id":"cm7x1p4990001abcd","url":"https://example.com/hooks/crayo","events":["export.completed","export.failed"],"disabled":false,"created_at":"2026-08-21T13:58:20.000Z","secret":"crayo_whsec_8Kd2••••••••"}]}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/webhooks/{id}":{"delete":{"operationId":"delete-webhook","summary":"Delete webhook","description":"Removes an endpoint and stops all deliveries to it. This is also how you replace a leaked secret: delete the endpoint and register it again to get a new one.","tags":["Webhooks"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook endpoint id.","schema":{"type":"string"},"example":"cm7x1p4990001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"example":{"success":true}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No webhook with that id belongs to your account."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}},"/v1/webhooks/{id}/test":{"post":{"operationId":"test-webhook","summary":"Send test delivery","description":"Sends a signed test.ping delivery to the endpoint so you can confirm your receiver is reachable and your signature check passes. The test is attempted once rather than retried.","tags":["Webhooks"],"x-credits":"Free","x-rate-limit":{"tier":"default","requests_per_second":2,"requests_per_minute":50},"parameters":[{"name":"id","in":"path","required":true,"description":"The webhook endpoint id.","schema":{"type":"string"},"example":"cm7x1p4990001abcd"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"delivery_id":{"type":"string"}},"required":["success","delivery_id"]},"example":{"success":true,"delivery_id":"evt_7Yc2mQ1rXv7pLb0a"}}}},"401":{"description":"MISSING_API_KEY, UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"MISSING_API_KEY":{"summary":"MISSING_API_KEY","value":{"success":false,"error":{"code":"MISSING_API_KEY","message":"No Authorization header was sent, or it does not carry a crayo_sk_ key."}}},"UNAUTHORIZED":{"summary":"UNAUTHORIZED","value":{"success":false,"error":{"code":"UNAUTHORIZED","message":"The key sent is malformed, expired, or revoked."}}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"NOT_FOUND":{"summary":"NOT_FOUND","value":{"success":false,"error":{"code":"NOT_FOUND","message":"No webhook with that id belongs to your account."}}}}}}},"409":{"description":"WEBHOOK_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"WEBHOOK_DISABLED":{"summary":"WEBHOOK_DISABLED","value":{"success":false,"error":{"code":"WEBHOOK_DISABLED","message":"The endpoint was disabled after repeated failures. Delete it and register it again."}}}}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"RATE_LIMITED":{"summary":"RATE_LIMITED","value":{"success":false,"error":{"code":"RATE_LIMITED","message":"Over the rate limit. Wait Retry-After seconds."}}}}}}},"500":{"description":"SERVER_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"SERVER_ERROR":{"summary":"SERVER_ERROR","value":{"success":false,"error":{"code":"SERVER_ERROR","message":"Something failed on our side. Retry with backoff."}}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"crayo_sk_"}},"schemas":{"Error":{"type":"object","properties":{"success":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["success","error"]},"Profile":{"type":"object","properties":{"id":{"type":["string","null"],"description":"The platform's own account id."},"username":{"type":["string","null"],"description":"Handle without the @."},"display_name":{"type":["string","null"],"description":"Name shown on the profile."},"url":{"type":["string","null"],"description":"Canonical profile URL."},"bio":{"type":["string","null"],"description":"Profile bio."},"avatar_url":{"type":["string","null"],"description":"Profile picture URL."},"is_verified":{"type":["boolean","null"],"description":"Verified badge."},"is_private":{"type":["boolean","null"],"description":"Private account."},"external_url":{"type":["string","null"],"description":"Link in bio."},"links":{"type":["array","null"],"items":{"type":"object","properties":{"title":{"type":["string","null"],"description":"Link label."},"url":{"type":["string","null"],"description":"Link URL."}},"required":["title","url"]},"description":"All bio links."},"followers_count":{"type":["integer","null"],"description":"Followers."},"following_count":{"type":["integer","null"],"description":"Accounts followed."},"content_count":{"type":["integer","null"],"description":"Posts, videos or tweets published."},"total_likes":{"type":["integer","null"],"description":"Lifetime likes. TikTok reports it, other platforms return null."},"observed_at":{"type":"string","description":"When this reading was taken, ISO 8601."},"source":{"type":"string","description":"\"live\" for a fresh lookup, \"stored\" for anything we kept from a refresh."}},"required":["id","username","display_name","url","bio","avatar_url","is_verified","is_private","external_url","links","followers_count","following_count","content_count","total_likes","observed_at","source"],"description":"An account on any platform. The same shape comes back from a live lookup, a tracker's latest reading, a feed's profile and a webhook. Fields a platform does not expose are null, never omitted.","example":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}},"Post":{"type":"object","properties":{"content_id":{"type":["string","null"],"description":"The platform's own post id."},"shortcode":{"type":["string","null"],"description":"Short id used in the post URL."},"url":{"type":["string","null"],"description":"Canonical post URL."},"play_count":{"type":["integer","null"],"description":"Plays."},"view_count":{"type":["integer","null"],"description":"Views."},"like_count":{"type":["integer","null"],"description":"Likes."},"comment_count":{"type":["integer","null"],"description":"Comments."},"share_count":{"type":["integer","null"],"description":"Shares."},"save_count":{"type":["integer","null"],"description":"Saves."},"create_time":{"type":["integer","null"],"description":"When it was posted, Unix seconds."},"caption":{"type":["string","null"],"description":"Caption or description."},"title":{"type":["string","null"],"description":"Title (YouTube)."},"duration":{"type":["number","null"],"description":"Length in seconds."},"product_type":{"type":["string","null"],"description":"Platform format, for example clips, feed, shorts."},"video_url":{"type":["string","null"],"description":"Always null. This API does not return media download links."},"thumbnail_url":{"type":["string","null"],"description":"Cover image URL."},"owner":{"type":["object","null"],"properties":{"id":{"type":["string","null"],"description":"Account id."},"username":{"type":["string","null"],"description":"Handle."},"full_name":{"type":["string","null"],"description":"Display name."},"is_verified":{"type":["boolean","null"],"description":"Verified badge."},"profile_pic_url":{"type":["string","null"],"description":"Avatar URL."}},"required":["id","username","full_name","is_verified","profile_pic_url"],"description":"Who posted it."},"audio":{"type":["object","null"],"properties":{"id":{"type":["string","null"],"description":"Sound id."},"artist":{"type":["string","null"],"description":"Artist."},"song":{"type":["string","null"],"description":"Title."},"is_original":{"type":["boolean","null"],"description":"Original audio."}},"required":["id","artist","song","is_original"],"description":"Sound used."},"is_video":{"type":["boolean","null"],"description":"Video rather than image."},"is_sponsored":{"type":["boolean","null"],"description":"Paid partnership."},"is_pinned":{"type":["boolean","null"],"description":"Pinned on the profile."},"tags":{"type":["array","null"],"items":{"type":"string"},"description":"Hashtags without the #."},"images":{"type":["array","null"],"items":{"type":"string"},"description":"Carousel image URLs. Live lookups only."},"observed_at":{"type":"string","description":"When this reading was taken, ISO 8601."},"source":{"type":"string","description":"\"live\" for a fresh lookup, \"stored\" for anything we kept from a refresh."}},"required":["content_id","shortcode","url","play_count","view_count","like_count","comment_count","share_count","save_count","create_time","caption","title","duration","product_type","video_url","thumbnail_url","owner","audio","is_video","is_sponsored","is_pinned","tags","images","observed_at","source"],"description":"A single video, reel, photo post or tweet. Counts are the platform's numbers at observed_at. video_url is always null: this API never returns media download links. Use thumbnail_url and images for visuals. A stored post also carries null for fields we never keep (images, and owner on profile feeds).","example":{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"live"}},"Comment":{"type":"object","properties":{"id":{"type":["string","null"],"description":"Comment id."},"text":{"type":["string","null"],"description":"Comment text."},"created_at":{"type":["string","null"],"description":"When it was written, ISO 8601."},"like_count":{"type":["integer","null"],"description":"Likes on the comment."},"reply_count":{"type":["integer","null"],"description":"Replies."},"is_pinned":{"type":["boolean","null"],"description":"Pinned by the author."},"is_hearted":{"type":["boolean","null"],"description":"Liked by the author."},"author":{"type":["object","null"],"properties":{"id":{"type":["string","null"],"description":"Account id."},"username":{"type":["string","null"],"description":"Handle."},"display_name":{"type":["string","null"],"description":"Display name."},"avatar_url":{"type":["string","null"],"description":"Avatar URL."},"is_verified":{"type":["boolean","null"],"description":"Verified badge."},"url":{"type":["string","null"],"description":"Profile URL."}},"required":["id","username","display_name","avatar_url","is_verified","url"],"description":"Who wrote it."},"fetched_at":{"type":["string","null"],"description":"When we read it. Set on stored comments, null on live lookups."}},"required":["id","text","created_at","like_count","reply_count","is_pinned","is_hearted","author","fetched_at"],"description":"A comment on a post.","example":{"id":"17912345678901234","text":"Number two is exactly why I never made it to the gym","created_at":"2026-10-13T18:22:10.000Z","like_count":412,"reply_count":9,"is_pinned":false,"is_hearted":true,"author":{"id":"40128839012","username":"late.riser.lena","display_name":"Lena","avatar_url":"https://cdn.example.com/avatars/late.riser.lena.jpg","is_verified":false,"url":"https://www.instagram.com/late.riser.lena/"},"fetched_at":"2026-10-14T09:12:44.000Z"}},"ProfileSnapshot":{"type":"object","properties":{"observed_at":{"type":"string","description":"When the reading was taken, ISO 8601."},"followers":{"type":["integer","null"],"description":"Followers."},"following":{"type":["integer","null"],"description":"Accounts followed."},"posts":{"type":["integer","null"],"description":"Published posts."},"total_views":{"type":["integer","null"],"description":"Lifetime views, where the platform reports it."},"total_likes":{"type":["integer","null"],"description":"Lifetime likes, where the platform reports it."}},"required":["observed_at","followers","following","posts","total_views","total_likes"],"description":"One stored reading of a profile.","example":{"observed_at":"2026-10-14T09:12:44.000Z","followers":182400,"following":312,"posts":418,"total_views":null,"total_likes":null}},"PostSnapshot":{"type":"object","properties":{"observed_at":{"type":"string","description":"When the reading was taken, ISO 8601."},"counts":{"type":"object","properties":{"views":{"type":["integer","null"],"description":"Views."},"plays":{"type":["integer","null"],"description":"Plays."},"likes":{"type":["integer","null"],"description":"Likes."},"comments":{"type":["integer","null"],"description":"Comments."},"shares":{"type":["integer","null"],"description":"Shares."},"saves":{"type":["integer","null"],"description":"Saves."}},"required":["views","plays","likes","comments","shares","saves"],"description":"Counts at that moment. Each is null when the platform did not report it."}},"required":["observed_at","counts"],"description":"One stored reading of a post.","example":{"observed_at":"2026-10-14T09:12:44.000Z","counts":{"views":1284500,"plays":1284500,"likes":96210,"comments":1430,"shares":8120,"saves":21480}}},"TrackedPost":{"allOf":[{"$ref":"#/components/schemas/Post"},{"type":"object","properties":{"id":{"type":"string","description":"Our id for this post inside the tracker. Use it as post_id."},"first_seen_at":{"type":"string","description":"When a refresh first saw it, ISO 8601."},"last_seen_at":{"type":["string","null"],"description":"When a refresh last saw it."},"removed_at":{"type":["string","null"],"description":"When it stopped appearing."},"removed_status":{"type":["string","null"],"description":"deleted, private or restricted once a check confirmed it."}},"required":["id","first_seen_at","last_seen_at","removed_at","removed_status"]}],"description":"A post inside a profile tracker: the post object plus when we first and last saw it and whether it has been removed.","example":{"content_id":"3412345678901234567","shortcode":"C9xAbCdEfGh","url":"https://www.instagram.com/reel/C9xAbCdEfGh/","play_count":1284500,"view_count":1284500,"like_count":96210,"comment_count":1430,"share_count":8120,"save_count":21480,"create_time":1760250000,"caption":"Three habits that quietly ruin your mornings","title":null,"duration":31.4,"product_type":"clips","video_url":null,"thumbnail_url":"https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg","owner":{"id":"58291034577","username":"mornings.with.ada","full_name":"Ada | Morning routines","is_verified":false,"profile_pic_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg"},"audio":{"id":"1203948572","artist":"mornings.with.ada","song":"Original audio","is_original":true},"is_video":true,"is_sponsored":false,"is_pinned":false,"tags":["morningroutine","habits"],"images":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored","id":"cm9t3p4q50003abcd","first_seen_at":"2026-10-12T09:00:12.000Z","last_seen_at":"2026-10-14T09:12:44.000Z","removed_at":null,"removed_status":null}},"Tracker":{"type":"object","properties":{"id":{"type":"string","description":"Tracker id."},"type":{"type":"string","description":"profile or post."},"platform":{"type":"string","description":"instagram, youtube, tiktok or twitter."},"url":{"type":"string","description":"Canonical URL of the target."},"handle":{"type":["string","null"],"description":"Handle for profile trackers, null for posts."},"status":{"type":"string","description":"active, paused, paused_no_credits, paused_failing or paused_dormant."},"interval_minutes":{"type":"integer","description":"Minutes between refreshes, 10 to 10,080."},"max_posts":{"type":["integer","null"],"description":"Posts kept per refresh (50, 100 or 200). Null for post trackers."},"next_refresh_at":{"type":["string","null"],"description":"When the next refresh is due."},"behind":{"type":"boolean","description":"True when the scheduler is running late for this target. The next refresh is queued and will not be charged twice."},"last_refreshed_at":{"type":["string","null"],"description":"When the last refresh succeeded."},"credits_per_month":{"type":"integer","description":"What this cadence costs per month: 43,200 divided by interval_minutes."},"credits_spent":{"type":"integer","description":"Credits this tracker has used so far."},"refresh_count":{"type":"integer","description":"Refreshes completed."},"created_at":{"type":"string","description":"ISO 8601."},"goal_followers":{"type":["integer","null"],"description":"A follower goal you set, if any."},"goal_by":{"type":["string","null"],"description":"When you want to reach it, ISO 8601."},"group_name":{"type":["string","null"],"description":"A label to group trackers by, up to 40 characters."},"alert_kinds":{"type":"array","items":{"type":"string"},"description":"Which events send a tracker.alert webhook: viral, milestone, removed, new_post, follower_drop."},"latest":{"oneOf":[{"$ref":"#/components/schemas/Profile"},{"$ref":"#/components/schemas/Post"},{"type":"null"}],"description":"The newest stored reading with source stored. Null until the first refresh runs."}},"required":["id","type","platform","url","handle","status","interval_minutes","max_posts","next_refresh_at","behind","last_refreshed_at","credits_per_month","credits_spent","refresh_count","created_at","goal_followers","goal_by","group_name","alert_kinds","latest"],"description":"A managed target: a profile or a single post that we refresh on your cadence and keep every reading of.","example":{"id":"cm9t3k1r20001abcd","type":"profile","platform":"instagram","url":"https://www.instagram.com/mornings.with.ada/","handle":"mornings.with.ada","status":"active","interval_minutes":1440,"max_posts":100,"next_refresh_at":"2026-10-15T09:12:44.000Z","behind":false,"last_refreshed_at":"2026-10-14T09:12:44.000Z","credits_per_month":30,"credits_spent":12,"refresh_count":12,"created_at":"2026-10-02T14:03:19.000Z","goal_followers":100000,"goal_by":"2026-12-31T00:00:00.000Z","group_name":"Clients","alert_kinds":["viral","milestone"],"latest":{"id":"58291034577","username":"mornings.with.ada","display_name":"Ada | Morning routines","url":"https://www.instagram.com/mornings.with.ada/","bio":"Three habits a week that make your mornings easier.","avatar_url":"https://cdn.example.com/avatars/mornings.with.ada.jpg","is_verified":false,"is_private":false,"external_url":"https://example.com/mornings","links":[{"title":"Newsletter","url":"https://example.com/mornings"}],"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null,"observed_at":"2026-10-14T09:12:44.000Z","source":"stored"}}},"TrackerEvent":{"type":"object","properties":{"id":{"type":"string","description":"Event id."},"kind":{"type":"string","description":"profile.name, profile.bio, profile.avatar, profile.link, profile.milestone, followers.drop, post.new, post.viral, post.milestone, post.removed, post.caption, post.pinned, post.unpinned, post.sponsored or post.views_dropped."},"at":{"type":"string","description":"When the refresh noticed it, ISO 8601."},"post_id":{"type":["string","null"],"description":"The tracked post's id for post.* events, null for profile events."},"before":{"type":["string","null"],"description":"The old text for name, bio, avatar, link and caption changes."},"after":{"type":["string","null"],"description":"The new text, or the removal status for post.removed."},"value":{"type":["integer","null"],"description":"The number behind the event: the milestone crossed, the views when a post went viral, or the negative delta of a drop."}},"required":["id","kind","at","post_id","before","after","value"],"description":"Something that changed on a tracked target between two refreshes. Kept for 90 days.","example":{"id":"cm9t3r8v10009abcd","kind":"post.viral","at":"2026-10-14T09:12:44.000Z","post_id":"cm9t3p4q50003abcd","before":null,"after":null,"value":412380}},"Usage":{"type":"object","properties":{"credits":{"type":"object","properties":{"available":{"type":"integer","description":"Subscription plus purchased credits."},"subscription":{"type":"integer","description":"Credits from your plan that reset each cycle."},"purchased":{"type":"integer","description":"Pack credits that never expire."},"monthly_allotment":{"type":"integer","description":"What your plan grants each cycle."},"resets_at":{"type":["string","null"],"description":"When the plan allotment renews."}},"required":["available","subscription","purchased","monthly_allotment","resets_at"],"description":"Tracker credit balance."},"projected_monthly":{"type":"integer","description":"What your active trackers will spend per month at their cadences."},"active_trackers":{"type":"object","properties":{"profile":{"type":"integer","description":"Profile trackers."},"post":{"type":"integer","description":"Post trackers."},"total":{"type":"integer","description":"Both."}},"required":["profile","post","total"],"description":"Targets by type."},"cap":{"type":"object","properties":{"limit":{"type":"integer","description":"Maximum targets."},"remaining":{"type":"integer","description":"Targets you can still add."},"raise_via":{"type":"object","description":"Where to ask for a higher limit: discord, then email."}},"required":["limit","remaining","raise_via"],"description":"Your target limit."}},"required":["credits","projected_monthly","active_trackers","cap"],"description":"Your tracker credits, projected spend and target count.","example":{"credits":{"available":1840,"subscription":1340,"purchased":500,"monthly_allotment":2500,"resets_at":"2026-11-03T00:00:00.000Z"},"projected_monthly":750,"active_trackers":{"profile":1,"post":1,"total":2},"cap":{"limit":500,"remaining":498,"raise_via":{"discord":"https://crayo.ai/discord","email":"support@crayo.ai"}}}},"Insights":{"type":"object","properties":{"followers_delta_7d":{"type":["integer","null"],"description":"Follower change over the last 7 days."},"posts_per_week":{"type":["number","null"],"description":"Average posts per week."},"median_views":{"type":["integer","null"],"description":"Median views of recent posts."},"engagement_rate":{"type":["number","null"],"description":"Engagement rate over recent posts."},"viral_post_ids":{"type":"array","items":{"type":"string"},"description":"Tracked post ids (the id of a tracked post) that our viral rule flags for this account."},"consistency":{"type":["number","null"],"description":"Share of the last 8 weeks with at least one post, 0 to 1."}},"required":["followers_delta_7d","posts_per_week","median_views","engagement_rate","viral_post_ids","consistency"],"description":"Optional math over a profile tracker's stored readings. Every field is null until there is enough history.","example":{"followers_delta_7d":2310,"posts_per_week":3.5,"median_views":412000,"engagement_rate":0.083,"viral_post_ids":["cm9t3p4q50003abcd"],"consistency":0.82}},"AccountAbout":{"type":"object","properties":{"id":{"type":["string","null"],"description":"The platform's own account id."},"display_name":{"type":["string","null"],"description":"Name shown on the profile."},"bio":{"type":["string","null"],"description":"Bio text."},"is_verified":{"type":["boolean","null"],"description":"Verified badge."},"stats":{"type":"object","description":"Headline counts: followers_count, following_count, content_count and total_likes. Each is null when the platform does not report it."}},"required":["id","display_name","bio","is_verified","stats"],"description":"The public bio and headline stats of an account.","example":{"id":"58291034577","display_name":"Ada | Morning routines","bio":"Three habits a week that make your mornings easier.","is_verified":false,"stats":{"followers_count":182400,"following_count":312,"content_count":418,"total_likes":null}}},"AccountSummary":{"type":"object","properties":{"id":{"type":["string","null"],"description":"The platform's own account id."},"username":{"type":["string","null"],"description":"Handle."},"display_name":{"type":["string","null"],"description":"Display name."},"avatar_url":{"type":["string","null"],"description":"Avatar URL."},"is_verified":{"type":["boolean","null"],"description":"Verified badge."},"is_private":{"type":["boolean","null"],"description":"Private account."},"url":{"type":["string","null"],"description":"Profile URL."}},"required":["id","username","display_name","avatar_url","is_verified","is_private","url"],"description":"One entry in a followers or following list.","example":{"id":"40128839012","username":"late.riser.lena","display_name":"Lena","avatar_url":"https://cdn.example.com/avatars/late.riser.lena.jpg","is_verified":false,"is_private":false,"url":"https://www.instagram.com/late.riser.lena/"}},"BatchItem":{"type":"object","properties":{"url":{"type":"string","description":"The url you sent."},"status":{"type":"string","description":"created, exists, invalid or limit_reached."},"id":{"type":"string","description":"The tracker id. Present when status is created or exists."},"error":{"type":"string","description":"Why the target was refused. Present when status is invalid."}},"required":["url","status","id","error"],"description":"The result for one target in a batch create, in the order you sent them.","example":{"url":"https://www.instagram.com/mornings.with.ada/","status":"created","id":"cm9t3k1r20001abcd"}},"Pagination":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Another page exists."},"next_cursor":{"type":["string","null"],"description":"Opaque signed cursor for the next page. Do not build or edit it."}},"required":["has_more","next_cursor"],"description":"Every list answers with the same pagination object. Pass next_cursor back unchanged as cursor to get the next page; stop when has_more is false. A cursor is an opaque signed token bound to your account and to the request that produced it. Sending it with a different target, route or account is 400 VALIDATION_ERROR (invalid cursor).","example":{"has_more":true,"next_cursor":"vtc1.k3Jx9Qm2Lw8aTn0ZpR5dYvUe.4f1c9e07a2b6"}},"TranscriptSegment":{"type":"object","properties":{"text":{"type":"string","description":"The words."},"start_ms":{"type":"integer","description":"Start, in milliseconds."},"end_ms":{"type":"integer","description":"End, in milliseconds."}},"required":["text","start_ms","end_ms"],"description":"One timed line of a transcript.","example":{"text":"Three habits that quietly ruin your mornings","start_ms":120,"end_ms":2410}}}}}