Developers
Audio intelligence as an API
One REST contract over api.euphonaai.com/v1. Async jobs with live SSE progress, signed file transfer, prefixed keys and a free test mode — a first-party product with its own twelve-month support window.
Keys are created in Studio settings — eu_test_… immediately and free, eu_live_… when you add a card. Test mode runs the full contract.
Design
How it's designed
Four decisions that aren't negotiable, because every one of them is the difference between an integration that survives its first outage and one that doesn't.
Everything is a job
Audio goes around the API, not through it
This API is the product, not a byproduct
The document is the contract
Walkthrough
The shape of an integration
Create a file, send the bytes to the signed target, submit a job, and watch it finish over SSE. Four steps, and the third one is the only part that differs per capability.
1 — Create the file and get an upload target
curl -X POST https://api.euphonaai.com/v1/files \
-H "Authorization: Bearer $EUPHONA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"filename":"take-07.wav","bytes":58210044,"content_type":"audio/wav"}'
{
"id": "file_8Kd2mQ...",
"object": "file",
"status": "awaiting_upload",
"upload": { "protocol": "...", "url": "https://files.euphonaai.com/...", "expires_at": "..." }
}2 — Send the bytes to files., not to us
# Read upload.protocol — do not assume one. The resumable mechanism is an
# implementation choice inside the contract and can change without a major
# version bump, which is exactly why it is a field and not documentation.3 — Watch the job
curl -N https://api.euphonaai.com/v1/jobs/job_4Rb.../events \
-H "Authorization: Bearer $EUPHONA_API_KEY"
event: job.progress
data: {"status":"analyzing","stage":"analyze","progress":{"fraction":0.4}}
event: job.completed
data: {"status":"succeeded","result":{...},"metering":{"pool":"payg","charged_minutes":3.4}}4 — Reconcile against the job itself
curl https://api.euphonaai.com/v1/jobs/job_4Rb... \
-H "Authorization: Bearer $EUPHONA_API_KEY"
{"id":"job_4Rb...","status":"succeeded","result":{...},
"metering":{"pool":"payg","charged_minutes":3.4}}
# The job resource is the state machine's current truth: whatever a stream
# showed or missed, read it back before you act on it. A dropped SSE
# connection reconnects with Last-Event-ID and loses nothing.Reference
The surface
The platform surface every capability shares. Each capability adds one creation endpoint; the job it returns flows through everything below — the same lifecycle, the same events, the same report.
| Method | Path | What it does |
|---|---|---|
| POST | /v1/files | Create a file and get a signed, resumable upload target. |
| GET | /v1/files/{id} | Ingest status, measured duration, sample rate, channels, format. |
| GET | /v1/files/{id}/download | A signed, expiring download URL. |
| GET | /v1/jobs | The unified read surface, cursor-paginated. |
| GET | /v1/jobs/{id} | Status, stage, progress, metering and the measured report. |
| POST | /v1/jobs/{id}/cancel | Cancel; no charge before the process stage starts. |
| GET | /v1/jobs/{id}/events | Server-sent events for the life of the job. |
| POST | /v1/projects | Group files and jobs; the Track Graph is per project. |
| GET | /v1/usage | Quota state and the two metering pools. |
Operations
The things that bite at three in the morning
The six behaviours worth reading before you write the integration rather than after it wakes you up.
- Keys
eu_live_…andeu_test_…, owned by a workspace, shown once at creation and hashed at rest. Rotate with an overlap window of up to thirty days, so a rotation is not an outage. Test keys are free, watermark their output, and run in their own scheduling class.- Errors
- RFC 9457
application/problem+json, always, with a stable machine-readablecode, a humandetailand the request id. Branch oncode, never on the prose — the prose is localised and the code is a contract. - Idempotency
Idempotency-Keyon every POST, replay-safe for twenty-four hours. A retry after a timeout returns the original result rather than starting a second job you will be charged for.- Limits
- Per-key sliding window with standard
RateLimit-*headers; 60 requests a minute on pay-as-you-go, higher under a committed-use contract. The limiter governs request frequency only — throughput is governed by your quota and the queue. - Two meters, never one
- API-key jobs meter to the pay-as-you-go pool; Studio-session jobs draw plan minutes. Neither pool can drain the other, and
GET /v1/usagereports both. Spend caps default to on. - Request-Id
- On every response, success or failure. Quote it in a support request and it resolves end to end — through the job, through every stage, to whatever actually happened.
Rates
What it costs
- First 100 minutes a month
- $0.35
- Up to 1,000
- $0.25
- Up to 10,000
- $0.15
- Beyond that, or committed use
- Talk to us
Per processed minute, times the capability multiplier, billed monthly. No subscription required — an API workspace can be on the free plan. Test mode is free.