Skip to content

ATS API — Overview & Quick Start

The Allfeat Organization API is the server-to-server integration for partner backends driving the ATS without the widget. This guide covers the B2B API key family — single bearer tokens (afo_sk_live_…) that let your backend register and update musical works on the Allfeat chain on behalf of your end-users, and receive signed webhook callbacks when they finalize.

The Allfeat Organization API gives your backend a programmatic equivalent of the Allfeat widget:

  • Register a piece of music as a work, anchoring its content hash and authorship metadata on-chain.
  • Update an existing work with a new version (corrected creators, remixed audio, etc.).
  • Track the resulting transaction in real time (REST poll, WebSocket, or signed webhook callback).
  • Reconcile completions back to your own user records via an opaque external_user_ref you control.

Behind the scenes, every successful registration:

  1. Hashes the audio + metadata server-side (you never compute commitments).
  2. Submits a meta-transaction signed with the organization’s wallet (gas paid by the platform’s relayer).
  3. Debits your organization’s AFT credit balance for the network fee + storage fee + service fee.
  4. Posts a work_registered (or work_updated / work_failed) webhook to the URL you configured on the API key — signed with an HMAC only the two of you know.

You never handle private keys, gas, or chain RPC.

┌──────────────────────────────────────────┐
│ Your backend (your servers) │
└───────┬────────────────────┬─────────────┘
│ ▲
Bearer token │ │ Signed webhook
▼ │
┌──────────────────────────────────────────┴─────────┐
│ POST /v1/organizations/{org}/works/init │
│ PUT <upload_url> (presigned S3, audio bytes) │
│ POST /v1/organizations/{org}/works/prepare │
│ POST /v1/organizations/{org}/works/confirm │
└─────────────────────────┬─────────────────────────┘
│ async chain submission
Allfeat blockchain

You make 3 to 4 HTTP calls per registration. Everything else (signing, chain submission, indexing, fee debit, webhook delivery) happens server-side.

In the Allfeat dashboard, open Settings → APIs → Create new key, and set:

  • Name — any human label, e.g. My backend (staging).
  • Scopes — pick at least works:register (and works:update if you need versioning).
  • Webhook URL (optional but recommended) — https://your-app.example.com/allfeat/webhooks.

Click Create. Copy the token and the webhook secret immediately — they are shown only once. They look like:

Token: afo_sk_live_3c9e5b7a4f2d1c8e9b7a4f2d1c8e9b7a4f2d1c8e9b7a4f2d
Webhook secret: xT8yKa…(base64)

Set up your environment:

Terminal window
export AF_API="https://api.allfeat.com"
export AF_TOKEN="afo_sk_live_…" # the token from step 1
export AF_ORG="00000000-0000-0000-0000-000000000000" # your organization UUID
Terminal window
curl -sS -X POST "$AF_API/v1/organizations/$AF_ORG/works/init" \
-H "Authorization: Bearer $AF_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"network": "testnet",
"title": "My first track",
"filename": "track.wav",
"creators": [{
"full_name": "Alice Composer",
"email": "alice@example.com",
"roles": { "author": true, "composer": true, "arranger": false, "adapter": false }
}],
"external_user_ref": "user-42"
}'

Response:

{
"job_id": "8a3f…",
"upload_url": "https://s3.amazonaws.com/…?X-Amz-Signature=…",
"upload_expires_at": "2026-04-30T11:00:00Z"
}

b) Upload — PUT the audio bytes directly to S3

Section titled “b) Upload — PUT the audio bytes directly to S3”
Terminal window
curl -sS -X PUT --upload-file ./track.wav "<upload_url from step a>"
Terminal window
curl -sS -X POST "$AF_API/v1/organizations/$AF_ORG/works/prepare" \
-H "Authorization: Bearer $AF_TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"job_id\":\"8a3f…\"}"

Response (truncated):

{
"job_id": "8a3f…",
"commitment": "0x4f7a…",
"network_fee_credits": 12,
"total_deposit_credits": 50,
"service_fee_credits": 5,
"storage_fee_credits": 8,
"total_price_credits": 75,
"is_valid": true,
"expires_at": "2026-04-30T11:05:00Z"
}

The job is now reserved with the quoted price. You have ~5 minutes to confirm (the exact TTL is in expires_at).

Terminal window
curl -sS -X POST "$AF_API/v1/organizations/$AF_ORG/works/confirm" \
-H "Authorization: Bearer $AF_TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"job_id\":\"8a3f…\"}"

Response (202 Accepted):

{
"transaction_id": "6f1c…",
"ws_url": "/v1/ws/transactions/6f1c…",
"status_url": "/v1/transactions/6f1c…"
}

Credits are debited immediately. The chain submission runs in the background.

Within ~10–30 seconds (testnet block time = 12s) you should receive a POST to your webhook URL:

POST /allfeat/webhooks
Content-Type: application/json
X-Allfeat-Signature: t=1714478345,v1=8c7d…
X-Allfeat-Timestamp: 1714478345
{
"event": "work_registered",
"transaction_id": "6f1c…",
"organization_id": "",
"api_key_id": "",
"external_user_ref": "user-42",
"network": "testnet",
"ats_id": 1024,
"tx_hash": "0xabc…",
"block_number": 1234567,
"block_hash": "0xdef…",
"explorer_url": "https://explorer.allfeat.com/tx/0xabc…",
"finalized_at": "2026-04-30T11:00:42Z"
}

Done. Always verify the signature before trusting the body — see Webhook signatures.

  • Authentication — bearer token format, organization binding, what the key cannot do.
  • Scopes — pick the right capability set for your integration.
  • Registering a work — full reference for the init / upload / prepare / confirm flow.
  • Webhooks — payload shapes, signature verification (Node, Python, Rust).
  • Security checklist — production hardening.