Authentication

The BlackLab API supports two authentication methods. Choose the one that fits your integration.

API Keys

For server-to-server integrations. Pass your secret key in the Authorization header.

Authorization: Bearer sk_live_your_api_key_here

API keys carry full permissions of the owning account. Never expose them in client-side code.

OAuth 2.0

For third-party applications acting on behalf of users. Supports Authorization Code and Client Credentials flows.

Parameter Value
Authorization URL https://app.blacklab.studio/oauth/authorize
Token URL https://api.blacklab.studio/v1/oauth/token
Scopes mastering:read mastering:write assets:write account:read

Base URL

# Production
https://api.blacklab.studio/v1

# Sandbox
https://sandbox.api.blacklab.studio/v1

All endpoints use HTTPS. HTTP requests are rejected. The sandbox environment mirrors production with synthetic responses.

Rate Limits

Rate limits use a sliding window algorithm. Limits are applied per API key.

Tier Requests/min Burst
Free 60 10
Pro 300 50
Enterprise 1,000 200

Rate limit headers are included in every response:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1700000060

Idempotency

To safely retry requests without creating duplicate resources, include an Idempotency-Key header on POST requests.

curl -X POST https://api.blacklab.studio/v1/mastering/jobs \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Idempotency-Key: unique-request-id-123" \
  -H "Content-Type: application/json" \
  -d '{"input_url": "...", "preset": "balanced"}'
  • Keys must be unique UUIDs or strings up to 255 characters.
  • Idempotency keys expire after 24 hours.
  • Replayed requests return the original response with a X-Idempotent-Replayed: true header.
  • If the original request is still processing, a 409 Conflict is returned.

POST /v1/mastering/jobs

Submit an audio file for AI mastering. Returns a job object with status and estimated completion time.

Request Body

Field Type Required Description
input_url string Yes URL of the source audio file (WAV, FLAC, AIFF, MP3).
preset string No Mastering preset. One of: balanced, warm, bright, loud. Default: balanced.
format string No Output format: wav, flac, mp3. Default: wav.
sample_rate integer No Output sample rate: 44100, 48000, 96000. Default: source rate.
webhook_url string No URL to receive webhook events for this job.
reference_url string No Reference track URL for style matching.

Example Request

curl -X POST https://api.blacklab.studio/v1/mastering/jobs \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "input_url": "https://storage.example.com/my-track.wav",
    "preset": "balanced",
    "format": "wav",
    "sample_rate": 44100,
    "webhook_url": "https://myapp.com/webhooks/blacklab"
  }'

Example Response 201 Created

{
  "id": "job_abc123def456",
  "status": "queued",
  "preset": "balanced",
  "format": "wav",
  "sample_rate": 44100,
  "estimated_seconds": 120,
  "credits_charged": 1,
  "created_at": "2025-01-15T10:30:00Z",
  "output_url": null
}

GET /v1/mastering/jobs/{id}

Retrieve the current status and details of a mastering job.

Path Parameters

Parameter Type Description
id string The job ID returned from the create endpoint.

Example Response 200 OK

{
  "id": "job_abc123def456",
  "status": "completed",
  "preset": "balanced",
  "format": "wav",
  "sample_rate": 44100,
  "credits_charged": 1,
  "created_at": "2025-01-15T10:30:00Z",
  "completed_at": "2025-01-15T10:32:04Z",
  "output_url": "https://cdn.blacklab.studio/output/job_abc123def456.wav",
  "output_expires_at": "2025-01-16T10:32:04Z"
}

Possible status values: queued, processing, completed, failed, cancelled.

POST /v1/assets/upload-url

Generate a pre-signed upload URL. Use this to upload audio files directly to BlackLab storage before submitting a mastering job.

Request Body

Field Type Required Description
filename string Yes Original filename with extension.
content_type string Yes MIME type: audio/wav, audio/flac, audio/mpeg, audio/aiff.
size_bytes integer Yes File size in bytes. Maximum 200 MB (209715200).

Example Response 200 OK

{
  "upload_url": "https://storage.blacklab.studio/uploads/...",
  "asset_url": "https://storage.blacklab.studio/assets/asset_xyz789.wav",
  "expires_at": "2025-01-15T11:00:00Z"
}

Upload the file with a PUT request to upload_url, then pass asset_url as the input_url to the mastering endpoint.

Webhooks

BlackLab delivers real-time event notifications to your configured webhook endpoints via HTTPS POST.

Setup

  1. Register a webhook URL in your app settings.
  2. BlackLab signs each payload with HMAC-SHA256 using your webhook secret.
  3. Verify the X-BlackLab-Signature header before processing.
  4. Respond with 200 OK within 10 seconds. Failed deliveries are retried up to 5 times with exponential backoff.
# Verify webhook signature (Python)
import hmac, hashlib

def verify_webhook(payload_bytes, signature, secret):
    expected = hmac.new(
        secret.encode(), payload_bytes, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Webhook Events

Event Description Payload
job.done Mastering job completed successfully. Full job object with output_url.
job.failed Mastering job failed. Credits are refunded. Job object with error field.
credits.low Account credit balance below threshold. {"balance": 3, "threshold": 5}

Example Webhook Payload

{
  "event": "job.done",
  "timestamp": "2025-01-15T10:32:04Z",
  "data": {
    "id": "job_abc123def456",
    "status": "completed",
    "output_url": "https://cdn.blacklab.studio/output/job_abc123def456.wav"
  }
}

Error Catalog

All errors follow a consistent JSON structure:

{
  "error": {
    "code": "insufficient_credits",
    "message": "Your account does not have enough credits for this operation.",
    "param": null,
    "doc_url": "https://developers.blacklab.studio/docs#err-insufficient-credits"
  }
}
Code HTTP Status Description
authentication_required 401 Missing or invalid API key / token.
forbidden 403 Valid credentials but insufficient permissions.
not_found 404 Requested resource does not exist.
validation_error 422 Request body failed validation. Check param field.
insufficient_credits 402 Not enough credits to complete the operation.
rate_limited 429 Too many requests. Retry after Retry-After seconds.
idempotency_conflict 409 A request with this idempotency key is already in progress.
file_too_large 413 Uploaded file exceeds the 200 MB limit.
unsupported_format 415 Audio format is not supported.
internal_error 500 Unexpected server error. Contact support if persistent.

HTTP Status Codes

Status Meaning
200Success.
201Resource created successfully.
204Success, no content returned.
400Bad request. Check your request body.
401Authentication required.
402Payment / credits required.
403Forbidden. Insufficient permissions.
404Resource not found.
409Conflict (idempotency or state).
413Payload too large.
415Unsupported media type.
422Validation error.
429Rate limited.
500Internal server error.