Agent Integration Guide¶
Access and authentication¶
Register through the portal. Accounts require manual approval before keys are issued; timing varies. If you have no key, tell your user to register and check their approval status. Repeating unauthenticated API calls will not grant access.
Send X-API-Key: YOUR_KEY. The legacy ?key= query parameter remains supported;
this API does not use Authorization: Bearer authentication. Use the environment
that issued your key. Examples below default to staging:
export TONN_API_BASE_URL=https://tonn-staging.roexaudio.com
# Set TONN_API_KEY through your secret store or local environment.
curl --fail-with-body "$TONN_API_BASE_URL/account" \
-H "X-API-Key: $TONN_API_KEY"
GET /account is read-only and does not charge credits or trigger auto top-up. It
returns approval status, key type, balance, reserved and available credits, the
pricing version, effective prices and operation billing metadata. Null pricing
means unavailable, not free. No universal per-key rate allowance or daily preview
cap is advertised. The input limits for each workflow are in its request schema.
Development keys simulate processing and may return dummy output URLs. They can check integration shape but cannot establish audio quality or successful rendering.
Discover the exact contract¶
- OpenAPI JSON is the complete machine-readable reference.
- llms.txt includes full field paths, enum values and JSON types.
- JSON summary lists actual operations and discovery links.
The curated spec is generated with checks against backend request validation.
Preserve each operation's wrapper and task-ID spelling. For example, mastering
uses masteringData and mastering_task_id, mixing uses multitrackData and
multitrack_task_id, and Mix Enhance retains the legacy mixReviveData wrapper
and mixrevive_task_id field.
Genre enums are endpoint-specific. Analysis uses HIP_HOP_GRIME and ROCK;
mastering/mixing use HIPHOP_GRIME and ROCK_INDIE. Analysis response values may
also be lowercase. Do not copy a genre between workflows without checking the
destination enum. There is no universal, lossless mapping for all genres.
Mixing uses BACKING_VOX_GROUP; cleanup uses BACKING_VOCALS_GROUP.
Mixing and mastering accept a string sample rate, such as "44100";
post-production accepts an integer, such as 48000. Defaults and allowed
values are documented on each operation.
Upload a local WAV¶
POST /uploadwith{"filename":"input.wav","contentType":"audio/wav"}.- PUT the file bytes to
signed_url, using the same Content-Type. Do not send your API key to Cloud Storage or other file hosts. - Pass
readable_urlto processing endpoints. Upload URLs expire; request a new URL if needed. A signed audio URL is not a processing task ID.
import os
import requests
base = os.environ.get("TONN_API_BASE_URL", "https://tonn-staging.roexaudio.com")
headers = {"X-API-Key": os.environ["TONN_API_KEY"]}
upload = requests.post(base + "/upload", headers=headers,
json={"filename": "input.wav", "contentType": "audio/wav"},
timeout=30)
upload.raise_for_status()
urls = upload.json()
with open("input.wav", "rb") as audio:
response = requests.put(urls["signed_url"], data=audio,
headers={"Content-Type": "audio/wav"}, timeout=120)
response.raise_for_status()
track_url = urls["readable_url"]
Master a WAV¶
POST /masteringpreview accepts:
{
"masteringData": {
"trackData": [{"trackURL": "YOUR_READABLE_URL"}],
"musicalStyle": "POP",
"desiredLoudness": "MEDIUM",
"sampleRate": "44100"
}
}
Keep the returned mastering_task_id. Retrieve its preview with
POST /retrievepreviewmaster and the body below. When requesting the full master,
use POST /retrievefinalmaster with the same body. Full retrieval can charge credits.
{"masteringData": {"masteringTaskId": "RETURNED_TASK_ID"}}
The final URL is an object field:
finalMasterTaskResults.download_url_mastered, not a bare response string.
Mix stems¶
Submit 2–32 aligned stems to POST /mixpreview. Each item must include
trackURL, instrumentGroup, presenceSetting, panPreference and
reverbPreference. Supply a readable URL for each file. A minimal two-stem example:
{
"multitrackData": {
"musicalStyle": "POP",
"sampleRate": "44100",
"trackData": [
{"trackURL": "VOCAL_URL", "instrumentGroup": "VOCAL_GROUP", "presenceSetting": "LEAD", "panPreference": "CENTRE", "reverbPreference": "NONE"},
{"trackURL": "BACKING_URL", "instrumentGroup": "BACKING_TRACK_GROUP", "presenceSetting": "NORMAL", "panPreference": "CENTRE", "reverbPreference": "NONE"}
]
}
}
The response supplies multitrack_task_id. Consult /retrievepreviewmix and
/retrievefinalmix for their different wrappers and retrieval options. FX settings
and processed stems can incur additional charges; a preview URL alone is not
proof that a full mix has been rendered.
Analyse, fix, then verify¶
POST /mixanalysiswith:{"mixDiagnosisData":{"audioFileLocation":"YOUR_READABLE_URL","musicalStyle":"POP","isMaster":false}}.- Inspect
mixDiagnosisResultsand select the applicable correction flags. POST /mixenhancewith the full required wrapper, for example:
{
"mixReviveData": {
"audioFileLocation": "YOUR_READABLE_URL",
"musicalStyle": "POP",
"isMaster": false,
"fixClippingIssues": true,
"fixStereoWidthIssues": false,
"fixLoudnessIssues": true,
"fixTonalProfileIssues": false,
"applyMastering": false,
"stemProcessing": false
}
}
- Use the returned
mixrevive_task_idwith/retrieveenhancedtrack, following that operation's request schema. Retrieve/download the completed output. - Analyse the processed URL again and report before/after measurements plus any remaining issues. HTTP 200 or a task ID alone does not establish that the requested correction succeeded.
Costs, polling and retries¶
Each operation's x-credit-cost describes its pricing field, billing stage and
conditional variants. GET /account supplies effective amounts from the pricing
document used by billing. Fallback amounts in the spec preserve legacy runtime
fallbacks; they are not a quote for a particular account.
Supported previews can have a positive-balance requirement on retrieval. FX
settings and stems are not necessarily free. Analysis and cleanup charge during
processing; separation reserves credits at submission and charges on success.
Most final renders charge on retrieval. Follow the operation-specific metadata.
Auto top-up may charge the configured payment method during paid workflows if
the account has enabled it; reading /account does not perform a top-up.
- On 202, retry the same retrieval request and task ID after
Retry-Afterseconds. Do not create another processing job just to poll. - Inspect
error: trueeven on HTTP 200: legacy terminal job failures can retain that status. Stop polling a failed task and report its failure. - On 400, fix the named field/type/constraint before retrying.
- On 401, fix authentication; on 403 with
approval_required, check the portal. - On 402, inspect balance and pricing; repeating the same request does not add credits.
- On 429, respect Retry-After when present. Back off on transient service failures.
- Do not blindly retry job submissions after a network timeout: the task may already exist. Final retrieval uses task-specific billing flags/transactions; retry with the same task ID rather than recreating the job.
A validation error has stable, additive machine-readable fields:
{
"error": true,
"code": "validation_error",
"message": "Request field does not meet the documented constraint.",
"field": "masteringData.sampleRate",
"constraint": "type",
"expected_type": "string",
"retryable": false,
"docs_url": "https://tonn-portal.roexaudio.com/docs/"
}
Enum errors include allowed. Existing workflow result wrappers remain intact.
Download and decode the final audio before treating a job as complete.