REST API · v1 · JSON over HTTPS

Podcast Backlinks API.

Build podcast backlinks into your workflow. Place orders, track fulfillment, pull reports — programmatically.

Authentication
Bearer token in every request
JSON in, JSON out
Idempotency keys supported
Typed errors
Stable error codes you can switch on

Authentication

Get your key from the dashboard. Send it as a Bearer token in the Authorization header.

Authorization: Bearer pk_live_a1b2c3d4e5f6...
Content-Type: application/json
Idempotency-Key: 8f3c-...   # optional, dedupes retries

Base URL: https://api.podcastbacklinks.com/v1

Place an order

POST/orders

Submit a new podcast backlink order.

Request body

{
  "package": "growth",                  // starter | growth | scale
  "target_url": "https://acme.com/blog/post",
  "anchor_text": "best CRM for startups",
  "episode_title": "How AI is reshaping SaaS in 2025",
  "niche": "saas",                      // see /niches for list
  "content": {
    "type": "html",                     // html | gdocs_url
    "body": "<p>Episode show notes...</p>"
  },
  "callback_url": "https://acme.com/webhooks/podcast-backlinks",
  "metadata": { "client_id": "cus_42" }
}

Response — 201 Created

{
  "id": "ord_01HZX9P7R8MA3K4VYTQ",
  "status": "queued",
  "package": "growth",
  "links_total": 3,
  "links_delivered": 0,
  "target_url": "https://acme.com/blog/post",
  "created_at": "2025-03-14T10:22:31Z",
  "estimated_delivery_at": "2025-03-14T18:00:00Z",
  "report_url": null
}

Track an order

GET/orders/{id}

Get current status and per-placement progress.

{
  "id": "ord_01HZX9P7R8MA3K4VYTQ",
  "status": "in_progress",              // queued | in_progress | delivered | failed
  "links_total": 3,
  "links_delivered": 2,
  "placements": [
    { "platform": "spotify",  "url": "https://...", "live_at": "2025-03-14T13:01:00Z", "indexed": true },
    { "platform": "apple",    "url": "https://...", "live_at": "2025-03-14T13:18:00Z", "indexed": true },
    { "platform": "iheart",   "url": null,          "live_at": null,                    "indexed": false }
  ],
  "report_url": null
}
GET/orders

List orders. Supports status, limit, cursor.

Pull the report

GET/orders/{id}/report

Returns the full PDF + JSON breakdown once status = delivered.

{
  "order_id": "ord_01HZX9P7R8MA3K4VYTQ",
  "pdf_url": "https://reports.podcastbacklinks.com/ord_01HZX9P7R8MA3K4VYTQ.pdf",
  "summary": {
    "links_total": 3,
    "indexed": 3,
    "average_da": 92,
    "delivered_in_hours": 5.7
  },
  "placements": [ /* full list with platform, url, indexed_at */ ]
}

See a real one: sample report PDF.

Account stats

GET/account
{
  "balance_usd": 412.50,
  "credits": { "starter": 0, "growth": 2, "scale": 1, "expires_at": "2026-03-14T00:00:00Z" },
  "orders_total": 47,
  "orders_in_progress": 3,
  "links_delivered_30d": 86
}

Webhooks

Set callback_url on an order, or configure a global URL in the dashboard. Every event is signed with HMAC-SHA256 in X-PodcastBacklinks-Signature.

{
  "type": "order.delivered",            // order.created | order.progress | order.delivered | order.failed
  "created_at": "2025-03-14T18:02:11Z",
  "data": { /* full order object */ }
}

Errors

Every error returns the same shape. Switch on code — strings are stable.

{
  "error": {
    "code": "insufficient_funds",
    "message": "Your balance ($12.00) is below the order total ($149.00).",
    "doc_url": "https://podcastbacklinks.com/api#insufficient_funds",
    "request_id": "req_01HZX9..."
  }
}
HTTPCodeMeaning
400invalid_requestMissing or malformed parameters (e.g. target_url is not a valid URL).
401unauthenticatedMissing or invalid API key in Authorization header.
402insufficient_fundsYour balance is too low to cover this order. Top up and retry.
403url_blockedTarget URL is blacklisted (spammy domain, malware host, deindexed).
409duplicate_orderAn identical order is already in progress for this URL.
422content_rejectedSubmitted content violates our guidelines (spam, adult, illegal).
422niche_unavailableNo podcasts currently available for that niche. Try a broader category.
429rate_limitedToo many requests. Default limit is 60/min — back off and retry.
500internal_errorSomething broke on our side. Safe to retry with the same idempotency key.

Quickstart

curl -X POST https://api.podcastbacklinks.com/v1/orders \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "package": "starter",
    "target_url": "https://acme.com",
    "anchor_text": "acme crm",
    "niche": "saas",
    "content": { "type": "html", "body": "<p>...</p>" }
  }'

Ready to integrate?

Grab a key from the dashboard, or first read the content guidelines. Pricing on the pricing page.

Request API access