v1 · REST · JSON

Cover API

Create music covers from a URL, an audio file, or an existing clip. Choose a voice preset and a style, then poll for finished audio. Source preparation happens automatically.

Authentication

Ask the administrator for a private API key. Send Authorization: Bearer YOUR_API_KEY on every request for covers, uploads, presets and jobs. Store the key on your server, outside source control. The docs, schema and health check are public. If a client receives an edge 403, send a descriptive User-Agent, such as CoverClient/1.0.

export COVER_API_KEY='your-private-key'
export COVER_API_BASE='https://covers.waily.io/api/v1'

Create a cover from a URL

A public audio-file URL works directly. YouTube, SoundCloud, Google Drive and Dropbox links are also supported when the linked audio is accessible. Direct file redirects are followed; local/private addresses and embedded credentials are rejected. Maximum audio size: 50 MiB. Requests use the connected account’s credits.

curl --fail-with-body "$COVER_API_BASE/cover" \
  -H "Authorization: Bearer $COVER_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: my-cover-request-001' \
  -d '{
    "url": "https://example.com/my-song.mp3",
    "title": "My cover",
    "persona": "flavia",
    "lyrics": "[Verse]\nYour lyrics here"
  }'

The server immediately returns 202 Accepted:

{"jobId":"11111111-1111-4111-8111-111111111111","statusUrl":"/api/v1/jobs/11111111-1111-4111-8111-111111111111"}

List the available presets:

curl --fail-with-body "$COVER_API_BASE/personas" \
  -H "Authorization: Bearer $COVER_API_KEY"

To cover an existing clip, replace url with clipId. Supply exactly one of url, clipId or uploadId.

Create a cover from a local file

Upload raw file bytes using --data-binary. Do not send multipart form data. MP3, WAV, M4A, FLAC, OGG and other formats supported by the audio decoder can be uploaded.

curl --fail-with-body "$COVER_API_BASE/uploads" \
  -H "Authorization: Bearer $COVER_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @my-song.wav

Use the returned uploadId in POST /cover. Uploads expire after one hour and are consumed by one job. At most ten pending uploads are kept. Uploading alone does not generate a cover.

curl --fail-with-body "$COVER_API_BASE/cover" \
  -H "Authorization: Bearer $COVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"uploadId":"YOUR_UPLOAD_ID","persona":"flavia","title":"My cover"}'

Poll for results

curl --fail-with-body "$COVER_API_BASE/jobs/YOUR_JOB_ID" \
  -H "Authorization: Bearer $COVER_API_KEY"

Poll about every five seconds. The state moves from queued to running, then done or failed. A successful result contains result.clips, each with id, title, status, audioUrl, imageUrl and duration in seconds. Download finished audio promptly because media URLs may expire. Individual takes can fail while other takes succeed.

Retries and service restarts

Send an Idempotency-Key when submitting a cover. Retrying the same key and body returns the same job. Reusing the key for a different body returns 409. Jobs and keys are retained for 24 hours after completion. At most three jobs may be running or queued; jobs run one at a time. Interrupted jobs become failed after a restart and are never automatically submitted again. Check existing results before starting a replacement.

Errors

Errors use {"error":{"code":"…","message":"…"}}. 400: invalid request; 401: missing/wrong key; 404: unknown job or endpoint; 409: conflicting retry key; 413: file too large; 415: unsupported upload content type; 429: queue/upload limit; 503: service not ready. Job failures are returned in the job’s error field. Contact the administrator with the job ID if account verification or generation fails.

Cover request options

Send JSON to POST https://covers.waily.io/api/v1/cover. Unknown fields are rejected. Negative prompts are off by default. Style and audio weights use 0–100; variety uses 0–1.

FieldType / defaultDescription
urlstringPublic audio-file URL, or a YouTube, SoundCloud, Google Drive or Dropbox link. Choose exactly one source field.
clipIdstringAn existing source clip ID. Choose exactly one source field.
uploadIdstringOne-use ID from POST /uploads. Choose exactly one source field.
titlestringName for the resulting cover. Default: linked filename/title, or Cover.
lyricsstringLyrics to sing. Omit to let the audio guide the cover; supply lyrics when exact wording matters.
personastringPreset key from GET /personas.
stylestringStyle prompt. Replaces the selected persona style while keeping its voice selection.
extraTagsstringAdditional style instructions appended to the style prompt.
voiceCloneboolean / trueUse the selected preset voice when available.
qualitystring / normal
normal, 8khz, 8khz_mono, opus_low, 4khz, 2khz, 1khz
Source audio preparation quality; applies to URLs and uploaded files.
modelstring / v6
v6, v6-wild, v6-mini
Generation model.
negativePromptsboolean / falseEnable exclusion instructions from negativeTags and leading minus style tags.
negativeTagsstringStyles to exclude. Used only when negativePrompts is true.
styleWeightnumberHow strongly to follow the style, 0–100. Omitted uses account defaults.
audioWeightnumberHow strongly to follow the source, 0–100. Omitted uses account defaults.
weirdnessnumberExperimentalness, 0–100. Omitted uses account defaults.
varietynumberVariation level, 0–1.
transposeintegerSource pitch shift in semitones; URLs/uploads only. Defaults to the preset voice register, otherwise 0.
vocalGenderstring
f, m,
f or m overrides the preset; null omits the gender hint.
vocalsOnlyboolean / falseIsolate source vocals before preparation; URLs/uploads only.
instrumentalboolean / falseGenerate without vocals.
maxModeboolean / falseEnable the model’s max mode.

Download the OpenAPI 3.0 contract to import into Postman or generate a client.