Skip to content
Euphona

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

Capability endpoints return 202 and a job resource. There are no synchronous processing endpoints and there never will be — a three-minute song at mastering quality isn't a request/response cycle, and an API that pretends otherwise teaches every integration to be written wrong.

Audio goes around the API, not through it

POST /v1/files returns a signed, resumable upload target on files.euphonaai.com. Results come back as signed, expiring download URLs. The API itself is a JSON control plane and never carries a byte of audio.

This API is the product, not a byproduct

Euphona Studio speaks a different, first-party API. That's deliberate: the two are separate products sharing one engine, so a change the app wants can't reach this contract, and this contract’s twelve-month support window isn't a tax the app has to pay. The honest consequence is that the app may do things this API doesn't — when that matters to you, ask, and it becomes a roadmap item rather than a surprise.

The document is the contract

The OpenAPI 3.1 document is the source of truth. Server routes, types and this documentation are generated from it, and a deploy-gated test holds the served routes equal to the declared operations - so drift between what is documented and what is served fails the build rather than being a thing we promise to watch for. SDKs generated from the same document arrive with the developer preview.

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.

Endpoints in the v1 contract
MethodPathWhat it does
POST/v1/filesCreate 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}/downloadA signed, expiring download URL.
GET/v1/jobsThe unified read surface, cursor-paginated.
GET/v1/jobs/{id}Status, stage, progress, metering and the measured report.
POST/v1/jobs/{id}/cancelCancel; no charge before the process stage starts.
GET/v1/jobs/{id}/eventsServer-sent events for the life of the job.
POST/v1/projectsGroup files and jobs; the Track Graph is per project.
GET/v1/usageQuota 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_… and eu_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-readable code, a human detail and the request id. Branch on code, never on the prose — the prose is localised and the code is a contract.
Idempotency
Idempotency-Key on 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/usage reports 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.