API reference
This page lists every endpoint and parameter. If you are new to the API, start with the guides.
Requests
- The base URL is
https://api.treblo.com/v1. The model version is part of the path, as in/generations/v3. - Every request needs your API key:Authorization: Bearer your_api_key_here
- Request bodies are JSON, except for
POST /uploads. An endpoint ignores fields it does not know. - Each v3 generation costs 100 credits. v2 costs 100, or 150 for two songs. We do not charge for a generation that fails.
Errors
An error response is JSON with the reason in detail. For a request body that fails validation, a 422, detail is a list with one entry for each problem. Otherwise it is a string.
400The API key is missing or not valid, or the API could not use something in the request.402You are out of credits.404No task with that id belongs to your account.413The upload is larger than 40MB.422The request is not valid. A field is missing or out of range, or two fields cannot be combined.A request that the API accepts can still fail later. The task then ends with the status FAILURE and, when we know the reason, an error_message.
POST/generations/v3
Generate a song of up to 4 minutes 45 seconds. Guides: generate, lyrics, styles.
Send prompt, tags, and lyrics in one of the accepted combinations.
Body
promptstringlyricsstringprompt or tags. Up to 40,000 characters.tagsarray of stringsinstrumentalbooleanDefault: falselyrics with it.negative_tagsarray of stringsnegative_tags_strengthfloatDefault: 1.0negative_tags. 1.0 to 10.0. We strongly discourage values above 5.0, which will likely give lower quality results. You can change it only if you send negative_tags.style_scalefloatDefault: 2.3prompt_strengthfloatDefault: 1.0prompt_strength and style_scale must be above 1.0, so set style_scale to 1.0 before you raise this.length_range[integer, integer][shortest, longest] length you want for the song, in seconds. This is a suggestion to the model and it generally follows it. Both values are multiples of 30. The first is 0 to 270, the second is 30 to 300, and the first must be lower than the second. The model never generates more than 4 minutes 45 seconds in one request.enable_streamingbooleanDefault: falsestream_formatstringDefault: oggwebhook_urlstring (URL)output_formatstringDefault: oggoutput_bit_rateintegeralign_lyricsbooleanDefault: falseimport requestsresponse = requests.post("https://api.treblo.com/v1/generations/v3",headers={"Authorization": "Bearer your_api_key_here"},json={"prompt": "An upbeat indie rock song about a road trip with old friends",},)print(response.json()) # {"task_id": "..."}
Response
{"task_id": "string (UUID)"}
POST/generations/v3/extend
Continue a song from its end. v3 cannot extend a song from its start. Guide: Extend a song.
Send exactly one of audio_url, audio_upload_id, and audio_base64. See Send us audio.
Send prompt, tags, and lyrics in one of the accepted combinations.
Body
audio_urlstring (URL)song_paths.audio_upload_idstring (UUID)POST /uploads returns. It expires after about 24 hours.audio_base64stringcontext_secondsfloatDefault: 150crop_durationfloatDefault: 0promptstringlyricsstringprompt or tags. Up to 40,000 characters.tagsarray of stringsinstrumentalbooleanDefault: falselyrics with it.negative_tagsarray of stringsnegative_tags_strengthfloatDefault: 1.0negative_tags. 1.0 to 10.0. We strongly discourage values above 5.0, which will likely give lower quality results. You can change it only if you send negative_tags.style_scalefloatDefault: 2.3prompt_strengthfloatDefault: 1.0prompt_strength and style_scale must be above 1.0, so set style_scale to 1.0 before you raise this.length_range[integer, integer][shortest, longest] length you want for the song, in seconds. This is a suggestion to the model and it generally follows it. Both values are multiples of 30. The first is 0 to 270, the second is 30 to 300, and the first must be lower than the second. The model never generates more than 4 minutes 45 seconds in one request.enable_streamingbooleanDefault: falsewebhook_urlstring (URL)output_formatstringDefault: oggoutput_bit_rateintegeralign_lyricsbooleanDefault: falseimport requestsresponse = requests.post("https://api.treblo.com/v1/generations/v3/extend",headers={"Authorization": "Bearer your_api_key_here"},json={"audio_url": "https://cdn.treblo.com/pubapi/generations3/audio_a598194b-d464-474c-b1e6-1c99f8f8e457_0.ogg","prompt": "Add a guitar solo, then one last chorus",},)print(response.json()) # {"task_id": "..."}
Response
{"task_id": "string (UUID)"}
POST/generations/v3/reference
Generate a new song from reference audio. Guides: cover, voice, style.
Send exactly one of audio_url, audio_upload_id, and audio_base64. See Send us audio.
Send prompt, tags, and lyrics in one of the accepted combinations.
Body
audio_urlstring (URL)song_paths.audio_upload_idstring (UUID)POST /uploads returns. It expires after about 24 hours.audio_base64stringreference_modestringDefault: covercover keeps the melody, style keeps the vocals and instruments, and voice keeps the singer's voice.reference_crop_startfloatreference_crop_end.reference_crop_endfloatreference_scalefloatDefault: 1.0, or 4.0 for a voicevoice_from_songbooleanDefault: falsereference_mode: "voice". Set to true when the audio is a full song and not a recording of only the singer.promptstringlyricsstringprompt or tags. Up to 40,000 characters.tagsarray of stringsinstrumentalbooleanDefault: falselyrics with it.negative_tagsarray of stringsnegative_tags_strengthfloatDefault: 1.0negative_tags. 1.0 to 10.0. We strongly discourage values above 5.0, which will likely give lower quality results. You can change it only if you send negative_tags.style_scalefloatDefault: 2.3prompt_strengthfloatDefault: 1.0prompt_strength and style_scale must be above 1.0, so set style_scale to 1.0 before you raise this.length_range[integer, integer][shortest, longest] length you want for the song, in seconds. This is a suggestion to the model and it generally follows it. Both values are multiples of 30. The first is 0 to 270, the second is 30 to 300, and the first must be lower than the second. The model never generates more than 4 minutes 45 seconds in one request.enable_streamingbooleanDefault: falsestream_formatstringDefault: oggwebhook_urlstring (URL)output_formatstringDefault: oggoutput_bit_rateintegeralign_lyricsbooleanDefault: falseimport requestsresponse = requests.post("https://api.treblo.com/v1/generations/v3/reference",headers={"Authorization": "Bearer your_api_key_here"},json={"audio_url": "https://cdn.treblo.com/pubapi/generations3/audio_a598194b-d464-474c-b1e6-1c99f8f8e457_0.ogg","reference_mode": "cover","prompt": "A slow acoustic version with fingerpicked guitar","reference_crop_start": 30,"reference_crop_end": 120,"reference_scale": 2,},)print(response.json()) # {"task_id": "..."}
Response
{"task_id": "string (UUID)"}
POST/uploads
Upload audio to use as audio_upload_id. Send it as multipart/form-data in a field named file.
- Formats: mp3, m4a, ogg, flac, wav, amr, aac, and aiff. Up to 40MB.
- An upload expires about 24 hours after you make it. Until then you can use it in any number of requests.
import requestswith open("my-song.mp3", "rb") as f:response = requests.post("https://api.treblo.com/v1/uploads",headers={"Authorization": "Bearer your_api_key_here"},files={"file": f},)print(response.json()) # {"audio_upload_id": "..."}
Response
{"audio_upload_id": "string (UUID)"}
GET/generations/{task_id}
Returns a task with its result and the parameters used to generate it.
song_pathsis null until the task succeeds. We may delete a song 168 hours after we generate it.lyricsandtagsare the ones the song was generated with, whether you sent them or we wrote them.lyricsis null for an instrumental, andtagsis null until we have written them.style_scaleis null for v2.word_aligned_lyricsis null until lyrics alignment succeeds, and stays null if the lyrics could not be aligned.v2_params,v3_params,extend_params,reference_params, andinpaint_paramsare null when they do not apply to the task.
import requeststask_id = "your_task_id"response = requests.get(f"https://api.treblo.com/v1/generations/{task_id}",headers={"Authorization": "Bearer your_api_key_here"},)print(response.json())
Response
{"id": "string (UUID)","created_at": "string (ISO 8601 timestamp)","status": "string","alignment_status": "string | null","model_version": "string (e.g. 'v3-preview', 'v2.2')","song_paths": "array[string] (URLs) | null","error_message": "string | null","lyrics": "string | null","word_aligned_lyrics": "array[{ word: string, start: float, end: float }] | null","prompt": "string | null","tags": "array[string] | null","prompt_strength": "float","style_scale": "float | null","v3_params": {"negative_tags": "array[string]","negative_tags_strength": "float | null","length_range": "[integer, integer] | null"},"v2_params": {"balance_strength": "float","seed": "integer","bpm": "'auto' | integer | null"},"extend_params": {"audio_url": "string (URL, or 'upload')","side": "string","crop_duration": "float","lyrics": "string | null","context_seconds": "float (v3)","extend_duration": "float (v2)","start_end_song": "'start' | 'end' | 'both' | null (v2)"},"reference_params": {"audio_url": "string (URL, or 'upload')","mode": "'cover' | 'style' | 'voice'","crop_start": "float | null","crop_end": "float | null","reference_scale": "float","voice_from_song": "boolean | null"},"inpaint_params": {"audio_url": "string (URL, or 'upload')","sections": "array[[float, float]]","lyrics": "string | null","selection_crop": "boolean"}}
GET/generations/status/{task_id}
The task's current status, as a JSON string. Use this endpoint to poll. It looks up only the status, so it is a lighter request than GET /generations/{task_id}, which you need only once the task has finished.
With the alignment status
Add ?include_alignment=true to get an object instead. alignment_status is null if the request did not set align_lyrics.
import requeststask_id = "your_task_id"response = requests.get(f"https://api.treblo.com/v1/generations/status/{task_id}?include_alignment=true",headers={"Authorization": "Bearer your_api_key_here"},)print(response.json())
{"status": "SUCCESS","alignment_status": "ALIGNING"}
import requeststask_id = "your_task_id"response = requests.get(f"https://api.treblo.com/v1/generations/status/{task_id}",headers={"Authorization": "Bearer your_api_key_here"},)print(response.json())
Response
"GENERATING"
GET/stream/{task_id}
The audio of a v3 task as it is generated. Guide: Stream while generating.
- This endpoint is on its own host,
https://api-stream.treblo.com, and takes no API key. - The request must have set
enable_streaming, and the task must have reachedGENERATING_STREAMING_READY. Before that it returns a 400. After the stream has ended, the response can be empty. - The
Content-Typeisaudio/ogg; codecs="opus", oraudio/mpegwithstream_format: "mp3".
<!-- Works once the task reaches GENERATING_STREAMING_READY --><audio controls autoplay><source src="https://api-stream.treblo.com/stream/your_task_id" type="audio/ogg" /></audio>
GET/credits/balance
Your remaining credits: num_credits from your subscription and num_credits_payg bought pay-as-you-go.
import requestsresponse = requests.get("https://api.treblo.com/v1/credits/balance",headers={"Authorization": "Bearer your_api_key_here"},)print(response.json())
Response
{"num_credits": "integer","num_credits_payg": "integer"}
Legacy (v2)
Use v3 for new work
v2 songs are 1 minute 35 seconds long, and v2 has its own set of tags.
POST/generations/v2
Generate a 1 minute 35 seconds song.
Send prompt, tags, and lyrics in one of the accepted combinations.
Body
promptstringlyricsstringprompt or tags. Up to 40,000 characters.tagsarray of stringsinstrumentalbooleanDefault: falselyrics with it.prompt_strengthfloatDefault: 2.0, or 1.8 for extendbalance_strengthfloatDefault: 0.7seedintegernum_songsintegerDefault: 1song_paths has one URL for each. Must be 1 with align_lyrics.bpminteger or "auto"Default: auto"auto" picks a tempo from the tags. null lets the model choose.webhook_urlstring (URL)output_formatstringDefault: oggoutput_bit_rateintegeralign_lyricsbooleanDefault: falseimport requestsresponse = requests.post("https://api.treblo.com/v1/generations/v2",headers={"Authorization": "Bearer your_api_key_here"},json={"prompt": "An upbeat rock song with heavy guitar riffs",},)print(response.json()) # {"task_id": "..."}
Response
{"task_id": "string (UUID)"}
POST/generations/v2/extend
Add to the start or the end of a song.
Send exactly one of audio_url, audio_upload_id, and audio_base64. See Send us audio.
Send prompt, tags, and lyrics in one of the accepted combinations.
Body
audio_urlstring (URL)song_paths.audio_upload_idstring (UUID)POST /uploads returns. It expires after about 24 hours.audio_base64stringsidestringrequiredright adds to the end of the song. left adds before its start.extend_durationfloatcrop_durationfloatDefault: 0promptstringlyricsstringprompt or tags. Up to 40,000 characters.tagsarray of stringsinstrumentalbooleanDefault: falselyrics with it.prompt_strengthfloatDefault: 2.0, or 1.8 for extendbalance_strengthfloatDefault: 0.7seedintegernum_songsintegerDefault: 1song_paths has one URL for each. Must be 1 with align_lyrics.webhook_urlstring (URL)output_formatstringDefault: oggoutput_bit_rateintegeralign_lyricsbooleanDefault: falseimport requestsresponse = requests.post("https://api.treblo.com/v1/generations/v2/extend",headers={"Authorization": "Bearer your_api_key_here"},json={"audio_url": "https://cdn.treblo.com/pubapi/generations2/audio_a598194b-d464-474c-b1e6-1c99f8f8e457_0.ogg","prompt": "Write another verse for my song","side": "right","extend_duration": 45,},)print(response.json()) # {"task_id": "..."}
Response
{"task_id": "string (UUID)"}
POST/generations/v2/inpaint
Regenerate one part of a song. Guide: Replace a section.
Send exactly one of audio_url, audio_upload_id, and audio_base64. See Send us audio.
Send tags with either lyrics or instrumental: true. A prompt is not accepted.
Body
audio_urlstring (URL)song_paths.audio_upload_idstring (UUID)POST /uploads returns. It expires after about 24 hours.audio_base64stringsections[[float, float]]required[start, end] of the part to replace, in seconds. The part must be at least 0.1 seconds long. Send exactly 1 section.selection_cropbooleanDefault: falselyricsstringinstrumental to true. Up to 40,000 characters.tagsarray of stringsrequiredinstrumentalbooleanDefault: falselyrics with it.prompt_strengthfloatDefault: 2.0, or 1.8 for extendbalance_strengthfloatDefault: 0.7seedintegernum_songsintegerDefault: 1song_paths has one URL for each. Must be 1 with align_lyrics.webhook_urlstring (URL)output_formatstringDefault: oggoutput_bit_rateintegeralign_lyricsbooleanDefault: falseimport requestsresponse = requests.post("https://api.treblo.com/v1/generations/v2/inpaint",headers={"Authorization": "Bearer your_api_key_here"},json={"audio_url": "https://cdn.treblo.com/pubapi/generations3/audio_a598194b-d464-474c-b1e6-1c99f8f8e457_0.ogg","tags": ["rock", "energetic"],"sections": [[20, 35]],"lyrics": "The new words for these fifteen seconds",},)print(response.json()) # {"task_id": "..."}
Response
{"task_id": "string (UUID)"}