Browse the API docs
Guide

Getting started

The Crayo API is a JSON REST API at https://api.crayo.ai authenticated with a bearer key created on the Developers page of the Crayo app. Every request sends an Authorization: Bearer header with a key that starts with crayo_sk_, and errors come back as a success false envelope with a stable code.

1. Create an API key

Keys are created on the Developers page of the Crayo app. Every key starts with crayo_sk_ and acts as the whole account, so keep it on a server and read it from an environment variable rather than shipping it in a client app.

  • An account can hold up to 5 active keys at once, each with its own name, so every app, environment or teammate can have one that is revoked on its own.
  • Expiry is picked at creation: 1 day, 1 week, 1 month, 1 year, never. The dashboard defaults to 1 month. An expired key answers 401 exactly like a revoked one.
  • Only a hash of the key is stored, so a lost key cannot be recovered. Create a new one, deploy it, then revoke the old one.

2. Send it as a bearer token

The base URL is https://api.crayo.ai. Every request carries the key in the Authorization header. There is nothing else to sign and no session to keep alive. POST and PATCH bodies are JSON with a Content-Type: application/json header, GET and DELETE take no body, and request bodies are capped at 512KB.

curl
curl "https://api.crayo.ai/v1/account" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

A good first call is GET /v1/account. It is free and returns your plan, credit balances, storage usage and the rate limits that apply to the key.

3. Understand credits

The API spends the same credits as the Crayo app, from the same balance. Reads are free. Anything that generates or renders media costs credits, and they are spent when a request is accepted rather than when it finishes well, so a failed render or an AutoClip job that finds fewer clips than requested leaves them spent. View Tracker is the exception: a lookup that fails on our side is refunded.

Credit typeSpent on
ImageImage, icon, and face swap generation.
VoiceoverNarration, voice changes, speech cleanup, and transcripts. Charged per second.
ExportProject renders. Charged per second of finished video.
VideoAutoClip jobs. Charged per requested clip.
TrackerView Tracker. 1 credit per request for fresh data: each live lookup and each scheduled refresh. Stored reads are free.

Storage is a separate budget. Uploads and imports cost no credits but count against your plan storage, and so does everything you generate or render. Going over returns 402 STORAGE_LIMIT_EXCEEDED.

4. Rate limits

Limits are per API key. Most endpoints share the default budget, while the expensive and the pollable endpoints get their own tiers.

Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. Going over returns 429 with code RATE_LIMITED and a Retry-After header in seconds.

View Tracker has its own, higher limits that count per account rather than per key, so a busy tracker integration never eats the budget of your other calls.

TierPer secondPer minuteApplies to
Raw lookups5200Every raw lookup under /v1/view-tracker/raw
Tracker reads5300GET /v1/view-tracker/trackers and everything under it, GET /v1/view-tracker/usage
Tracker writes260POST /v1/view-tracker/trackers, PATCH and DELETE /v1/view-tracker/trackers/{id}, POST /v1/view-tracker/trackers/{id}/refresh
Batch create110POST /v1/view-tracker/trackers/batch

5. Errors

Failures come back in one shape, with a stable code you can branch on and a message written for a human reading a log. Branch on the code: messages get clearer over time, codes do not change.

error response
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "title is required"
  }
}

These four can come back from any endpoint.

StatusCodeWhen
401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
500SERVER_ERRORSomething failed on our side. Retry with backoff.

Endpoint-specific codes are listed on each endpoint. The most common across the API are below, with the number of endpoints that can return each one.

StatusCodeEndpoints
400VALIDATION_ERROR39
400UNKNOWN_FIELD31
400INVALID_ASSET_TYPE3
402STORAGE_LIMIT_EXCEEDED3
402INSUFFICIENT_CREDITS30
403TARGET_PRIVATE15
404NOT_FOUND46
404TARGET_NOT_FOUND15
413FILE_TOO_LARGE3
415UNSUPPORTED_MEDIA_TYPE3
429CONCURRENT_REQUEST4
429RATE_LIMITED29
502UPSTREAM_ERROR15
503UPSTREAM_BUSY15

6. Webhooks

Renders, AutoClip jobs, speech enhancements and tracker refreshes run in the background. Register an https endpoint with POST /v1/webhooks and we send one signed POST the moment the work is done. The signing secret starts with crayo_whsec_ and is returned exactly once.

EventFires when
export.completedA project render finished. The payload carries the finished video asset.
export.failedA project render failed. Credits stay spent.
autoclip.completedAn AutoClip job finished and its clips are ready.
autoclip.failedAn AutoClip job failed.
speech_enhancer.completedA speech enhancement finished. Fetch it for stems and export the mix you want.
speech_enhancer.failedA speech enhancement failed. Credits stay spent.
tracker.refreshedA managed tracker was refreshed. The payload carries the latest reading, the new snapshot, new posts and removed post ids.
tracker.refresh_failedA managed tracker refresh failed because the target is private, missing or unavailable.
tracker.pausedA managed tracker paused itself: out of credits, failing, or dormant.
tracker.alertSomething you asked to be alerted about happened on a tracker: a post went viral, a follower or view milestone was crossed, a post was removed, a new post appeared, or followers dropped. Pick what counts with alert_kinds on the tracker.
credits.lowYour tracker credits dropped below 10% of your monthly allotment. Sent once per cycle.

Each delivery carries a crayo-signature header shaped like t=1755785271,v1=<hex>: an HMAC-SHA256 over <t>.<raw body> using your webhook secret. Deliveries are attempted up to 5 times, backing off exponentially from 30 seconds, and an endpoint that fails 20 times in a row is disabled. Read the Webhooks reference for the endpoints and payloads.

Next steps

New to the Crayo API? See what it is forUse cases, pricing and the console walkthrough live on the API feature page.

FAQs

Frequent questions

Open the Developers page in the Crayo app at crayo.ai/developers and create a key. An account can hold up to 5 active keys, each with its own name and an expiry of 1 day, 1 week, 1 month, 1 year, never. Only a hash is stored, so copy the key when it is shown.

https://api.crayo.ai. Every path in these docs is relative to it, for example GET https://api.crayo.ai/v1/account.

Credits are spent when a request is accepted, not when it finishes well, so a failed render or an AutoClip job that finds fewer clips leaves them spent. View Tracker is the exception: a lookup that fails on our side is refunded.

The response is 429 with code RATE_LIMITED and a Retry-After header in seconds. Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers so you can pace requests before that happens.

Still have questions?

Contact our 24/7 support team for any concerns or inquiries.

Get in touch