yala
← help

public API + webhooks.

everything yala’s admin UI does, you can do via REST. api keys are workspace-scoped Bearer tokens. webhooks are HMAC-SHA256-signed, replay-protected, and retried with exponential backoff. free at every tier.

getting an api key.

  • go to workspace → developer.
  • click + create key. pick a role (viewer / editor / admin) — it determines which routes the key can hit.
  • yala generates a token like yla_live_abc123... (live) or yla_test_abc123... (test). copy it now. we hash it with SHA-256 server-side; we never show the plaintext again.

the admin shows a 12-char prefix so you can identify which key is which. revoke any time — server-side comparison fails on the next request.

authenticating a request.

every request: send the key as a Bearer token.

http
GET /v1/links HTTP/1.1
Host: api.yala.la
Authorization: Bearer yla_live_abc123...
Content-Type: application/json

the routes you’ll use.

full reference at api.yala.la/v1 with OpenAPI spec; the high-leverage subset:

  • POST /v1/scanner/preview — preview a scan without writing anything. accepts source url / UPC / ISRC, returns destinations + artwork.
  • POST /v1/links — create a link. accepts type, title, slug, defaultUrl, optional seedDestinations, optional seedArtworkUrl, optional source (kicks off a real scan job).
  • GET /v1/links/{id} — read a link including destinations + redirects + landing config.
  • PATCH /v1/links/{id} — update title / defaultUrl / fallbackUrl.
  • POST /v1/links/{id}/publish .../unpublish / .../archive / .../unarchive.
  • POST /v1/links/{id}/destinations — upsert a destination row (DSP).
  • POST /v1/links/{id}/redirects — create a conditional redirect.
  • GET /v1/analytics/summary — workspace or per-link KPI summary.
  • POST /v1/dsar/exportFan / eraseFan — GDPR Art. 15 + 17 endpoints. admin role only.

a real-world example.

scan a track + create a link in two calls (the wizard does exactly this):

bash
# 1) preview the scan (no writes)
PREVIEW=$(curl -sX POST https://api.yala.la/v1/scanner/preview \
  -H "authorization: Bearer $YALA_KEY" \
  -H "content-type: application/json" \
  -d '{
    "source": {"kind": "url", "value": "https://open.spotify.com/track/abc"}
  }')

# 2) create the link with the preview destinations seeded
curl -X POST https://api.yala.la/v1/links \
  -H "authorization: Bearer $YALA_KEY" \
  -H "content-type: application/json" \
  -d "$(jq -n --argjson p "$PREVIEW" '{
    type: "release",
    title: "the b-side",
    publish: true,
    seedDestinations: $p.destinations,
    seedArtworkUrl: $p.artworkUrl
  }')"

webhooks.

register an endpoint URL in workspace → developer → webhooks. on every event we POST a JSON payload signed with HMAC-SHA256. verify the signature server-side using your shared secret — the webhook setup UI shows the secret once at creation (rotatable later).

events we fire:

  • link.created
  • link.updated
  • link.archived
  • scan.completed
  • fan.subscribed (email capture or pre-save)
  • fan.unsubscribed
  • broadcast.sent

verifying signatures.

the x-yala-signature header has the format v1=<hex>. compute HMAC-SHA256 over the raw request body using your secret and compare:

ts
import crypto from "node:crypto";

function verify(rawBody: string, headerSig: string, secret: string) {
  const [version, signature] = headerSig.split("=");
  if (version !== "v1") return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex"),
  );
}

retry policy.

we retry up to 5 times with exponential backoff (1m, 5m, 30m, 2h, 8h). after the 5th failure we mark the delivery failed in the delivery log; you can replay it manually from the developer panel.

rate limits.

  • read endpoints: 600/min per workspace.
  • write endpoints: 120/min per workspace.
  • scanner: 60/min per workspace.

429s come back with a Retry-After header. enterprise tier raises these on request.

next upteams + rolesinvite the band, set who can publish vs view-only, audit the room.