Browse the API docs
Endpoint reference

Speech Enhancer

The Crayo Speech Enhancer API cleans the speech in an audio or video asset and separates it into speech, music and background stems. Create a job, wait for speech_enhancer.completed, then export a mix at the levels you choose.

Create enhancement

POST/v1/speech-enhancer

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.

  • A typical recording finishes in one to three minutes.
  • Credits are charged when the job starts and stay spent if it fails.
Credits:
1 voiceover credit per second of the source asset, charged when the job starts
Rate limit:
Heavy tier, 2/s and 10/min

Parameters

NameInTypeRequiredDescription
asset_idbodystringYesAn 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.

Request

curl
curl -X POST "https://api.crayo.ai/v1/speech-enhancer" \
  -H "Authorization: Bearer $CRAYO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "asset_id": "cm7x1k2p40001abcd"
}'

Response

200 application/json
{
  "success": true,
  "enhancement": {
    "id": "cm7x1p4e10002abcd",
    "status": "queued",
    "credits_charged": 72
  }
}

Errors

  • 400UNKNOWN_FIELDThe body carries a field this endpoint does not accept.
  • 400INVALID_ASSET_TYPEThe asset is an image rather than audio or video.
  • 400INVALID_ASSETThe asset has no known duration. Upload it again.
  • 400VALIDATION_ERRORThe source is longer than 10 minutes.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 402INSUFFICIENT_CREDITSYour voiceover balance is below the media duration.
  • 404NOT_FOUNDNo asset with that id belongs to your account.
  • 429JOB_LIMIT_REACHEDYou already have 8 enhancements running.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

List enhancements

GET/v1/speech-enhancer

Lists enhancements on the account, newest first, with the stage and progress of each.

Credits:
Free
Rate limit:
Polling tier, 2/s and 120/min

Parameters

NameInTypeRequiredDescription
limitqueryintegerNoPage size. 1 to 100.default 25
offsetqueryintegerNoSkip this many, newest first.default 0

Request

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

Response

200 application/json
{
  "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"
    }
  ]
}

Errors

  • 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.

Get enhancement

GET/v1/speech-enhancer/{id}

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.

  • Stems are the building blocks: mix them yourself, or call the export endpoint and let us render the mix.
  • A failed enhancement carries an error string and no stems.
Credits:
Free
Rate limit:
Polling tier, 2/s and 120/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe enhancement id returned when the job was created.

Request

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

Response

200 application/json
{
  "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"
      }
    ]
  }
}

Errors

  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo enhancement with that id belongs to your account.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Export a mix

POST/v1/speech-enhancer/{id}/export

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.

  • The request blocks for the few seconds the render takes, so the asset is in the response and appears in your library at once.
  • Levels you send are saved on the enhancement and become the default for later exports.
Credits:
Free
Rate limit:
Default tier, 2/s and 50/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe enhancement id returned when the job was created.
speechbodynumberNoLevel of the cleaned voice. 0 to 2. 1 keeps the stem at its processed level; 0 removes it.
musicbodynumberNoLevel of any music separated from the recording. 0 to 2. 1 keeps the stem at its processed level; 0 removes it.
backgroundbodynumberNoLevel of room tone and ambience. 0 to 2. 1 keeps the stem at its processed level; 0 removes it.
formatbodystringNoContainer for the export. Video sources always export as mp4.default mp4 for video, wav for audiomp4wavmp3

Request

curl
curl -X POST "https://api.crayo.ai/v1/speech-enhancer/cm7x1p4e10002abcd/export" \
  -H "Authorization: Bearer $CRAYO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "speech": 1,
  "music": 0.1,
  "background": 0.1
}'

Response

200 application/json
{
  "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"
  }
}

Errors

  • 400UNKNOWN_FIELDThe body carries a field this endpoint does not accept.
  • 400VALIDATION_ERRORA level is out of range, or format mp4 was asked of an audio source.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo enhancement with that id belongs to your account.
  • 409NOT_READYThe enhancement has not completed yet.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Delete enhancement

DELETE/v1/speech-enhancer/{id}

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.

Credits:
Free
Rate limit:
Default tier, 2/s and 50/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe enhancement id returned when the job was created.

Request

curl
curl -X DELETE "https://api.crayo.ai/v1/speech-enhancer/cm7x1p4e10002abcd" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true
}

Errors

  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo enhancement with that id belongs to your account.
  • 409JOB_IN_PROGRESSThe enhancement is still running.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.
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

1 voiceover credit per second of the source asset, charged when the job starts. Sources can be up to 10 minutes long and need a known duration.

A typical recording finishes in one to three minutes. GET /v1/speech-enhancer/{id} then returns a URL for each stem as lossless WAV plus a small AAC preview, the current levels, and every export made from it.

POST /v1/speech-enhancer/{id}/export accepts speech, music and background levels and a format of mp4, wav or mp3. Video sources come back as the original video with the new audio, and identical levels reuse the earlier export.

DELETE /v1/speech-enhancer/{id} removes the enhancement and its stems and cancels a queued job. Exports already made from it and the source asset stay in your library.

Still have questions?

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

Get in touch