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.
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'
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.
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"}'
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.
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 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.
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.
| Field | Type / default | Description |
|---|---|---|
| url | string | Public audio-file URL, or a YouTube, SoundCloud, Google Drive or Dropbox link. Choose exactly one source field. |
| clipId | string | An existing source clip ID. Choose exactly one source field. |
| uploadId | string | One-use ID from POST /uploads. Choose exactly one source field. |
| title | string | Name for the resulting cover. Default: linked filename/title, or Cover. |
| lyrics | string | Lyrics to sing. Omit to let the audio guide the cover; supply lyrics when exact wording matters. |
| persona | string | Preset key from GET /personas. |
| style | string | Style prompt. Replaces the selected persona style while keeping its voice selection. |
| extraTags | string | Additional style instructions appended to the style prompt. |
| voiceClone | boolean / true | Use the selected preset voice when available. |
| quality | string / normal normal, 8khz, 8khz_mono, opus_low, 4khz, 2khz, 1khz | Source audio preparation quality; applies to URLs and uploaded files. |
| model | string / v6 v6, v6-wild, v6-mini | Generation model. |
| negativePrompts | boolean / false | Enable exclusion instructions from negativeTags and leading minus style tags. |
| negativeTags | string | Styles to exclude. Used only when negativePrompts is true. |
| styleWeight | number | How strongly to follow the style, 0–100. Omitted uses account defaults. |
| audioWeight | number | How strongly to follow the source, 0–100. Omitted uses account defaults. |
| weirdness | number | Experimentalness, 0–100. Omitted uses account defaults. |
| variety | number | Variation level, 0–1. |
| transpose | integer | Source pitch shift in semitones; URLs/uploads only. Defaults to the preset voice register, otherwise 0. |
| vocalGender | string f, m, | f or m overrides the preset; null omits the gender hint. |
| vocalsOnly | boolean / false | Isolate source vocals before preparation; URLs/uploads only. |
| instrumental | boolean / false | Generate without vocals. |
| maxMode | boolean / false | Enable the model’s max mode. |
Download the OpenAPI 3.0 contract to import into Postman or generate a client.