{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "SocialTap API changelog",
  "home_page_url": "https://staging.socialtap.dev/docs/changelog/",
  "feed_url": "https://staging.socialtap.dev/changelog.json",
  "description": "Additions, deprecations, retirements and fixes to the SocialTap API.",
  "language": "en",
  "items": [
    {
      "id": "https://staging.socialtap.dev/docs/changelog/#2026-10-26-accounts",
      "url": "https://staging.socialtap.dev/docs/changelog/#2026-10-26-accounts",
      "title": "Self-serve signup, test keys, API key management and usage",
      "content_html": "<p>You can now get started without talking to anyone, test for free, and manage your account through the API.</p>\n<ul>\n<li><strong>Sign up</strong> with your email address: the emailed link creates your account with free credits, a live key and a\ntest key, and opens the dashboard (keys, usage, balance, credit packs). <strong>AI agents</strong> can sign up with\n<code>POST /v1/agent_signup</code>: they get a test key at once and a live key that works once you confirm by email.</li>\n<li><strong>Test keys</strong> (<code>st_test_…</code>) answer every endpoint from recorded responses, free and deterministic, and reserved\n&quot;magic&quot; inputs trigger each error code, so integrations and CI can exercise every branch at no cost.</li>\n<li><strong>API keys</strong> have scopes (<code>endpoints</code>, <code>jobs</code>, <code>account:read</code>, <code>admin</code>), optional spend limits per day or month\n(<code>spend_limit_reached</code>), expiry and IP allowlists, managed through <code>/v1/api_keys</code>.</li>\n<li><strong>Account and usage</strong>: <code>GET /v1/account</code> (balance, plan, the calling key), <code>GET /v1/usage</code> (requests and credits\nover time by endpoint, key and outcome) and <code>GET /v1/credit_transactions</code> (the ledger). Set\n<code>low_balance_threshold</code> to get a <code>credits.low</code> email and event.</li>\n<li><code>meta.mode</code> says whether a response came from a live or a test key. <code>forbidden</code> is now returned (with\n<code>details.reason</code>), and a missing key&#39;s <code>unauthorized</code> says where to get one.</li>\n</ul>\n<details><summary>Contract changes (104)</summary><ul class=\"changes\"><li><code>endpoint facebook.transcript: accepts video links</code></li><li><code>endpoint instagram.transcript: accepts video links</code></li><li><code>endpoint instagram.transcript: accepts post links</code></li><li><code>endpoint tiktok.transcript: accepts video links</code></li><li><code>endpoint tiktok.transcript: accepts post links</code></li><li><code>endpoint youtube.transcript: accepts video links</code></li><li><code>error code endpoint_retired added (HTTP 410)</code></li><li><code>error code forbidden added (HTTP 403)</code></li><li><code>error code idempotency_key_in_progress added (HTTP 409)</code></li><li><code>error code idempotency_key_reused added (HTTP 422)</code></li><li><code>error code insufficient_credits: details key credits_required added</code></li><li><code>error code insufficient_credits: details key credits_available added</code></li><li><code>error code invalid_cursor: details key reason added</code></li><li><code>error code invalid_input: details key suggestion added</code></li><li><code>error code invalid_input: details key accepted_params added</code></li><li><code>error code invalid_input: details key url_kind added</code></li><li><code>error code invalid_input: details key url_platform added</code></li><li><code>error code invalid_input: details key accepted_url_kinds added</code></li><li><code>error code invalid_input: details key endpoints added</code></li><li><code>error code invalid_input: details key fields added</code></li><li><code>error code job_not_found added (HTTP 404)</code></li><li><code>error code overloaded: details key retry_after added</code></li><li><code>error code rate_limited: details key retry_after added</code></li><li><code>error code spend_limit_reached added (HTTP 402)</code></li><li><code>header cache-control added</code></li><li><code>header deprecation added</code></li><li><code>header link added</code></li><li><code>header ratelimit added</code></li><li><code>header ratelimit-policy added</code></li><li><code>header sunset added</code></li><li><code>header traceparent added</code></li><li><code>header x-client-request-id added</code></li><li><code>common param fields added</code></li><li><code>warning code deprecated_endpoint added</code></li><li><code>shared param country added</code></li><li><code>shared param lang added</code></li><li><code>shared param since added</code></li><li><code>shared param sort added</code></li><li><code>shared param until added</code></li><li><code>meta fields are part of the locked contract</code></li><li><code>page fields are part of the locked contract</code></li><li><code>error fields are part of the locked contract</code></li><li><code>MCP tool find_endpoint added</code></li><li><code>MCP tool get_transcript added</code></li><li><code>header authorization added</code></li><li><code>error code forbidden: details key reason added</code></li><li><code>error code forbidden: details key required_scope added</code></li><li><code>error code spend_limit_reached: details key api_key_id added</code></li><li><code>error code spend_limit_reached: details key spend_limit added</code></li><li><code>error code spend_limit_reached: details key interval added</code></li><li><code>error code spend_limit_reached: details key used added</code></li><li><code>error code spend_limit_reached: details key credits_required added</code></li><li><code>error code spend_limit_reached: details key resets_at added</code></li><li><code>error code unauthorized: details key signup_url added</code></li><li><code>error code unauthorized: details key agent_signup_url added</code></li><li><code>meta: field mode added</code></li><li><code>MCP tool get_account added</code></li><li><code>error code insufficient_credits: details key max_credits added</code></li><li><code>header idempotency-key added</code></li><li><code>header idempotent-replayed added</code></li><li><code>header location added</code></li><li><code>header prefer added</code></li><li><code>header preference-applied added</code></li><li><code>header webhook-id added</code></li><li><code>header webhook-signature added</code></li><li><code>header webhook-timestamp added</code></li><li><code>event type job.completed added</code></li><li><code>event type job.canceled added</code></li><li><code>event type job.expired added</code></li><li><code>event type credits.low added</code></li><li><code>event type credits.depleted added</code></li><li><code>event type api_key.spend_limit_reached added</code></li><li><code>event type webhook.test added</code></li><li><code>operation DELETE /v1/webhook_endpoints/{id} added (webhook_endpoints.delete)</code></li><li><code>operation GET /v1/events added (events.list)</code></li><li><code>operation GET /v1/events/{id} added (events.get)</code></li><li><code>operation GET /v1/jobs added (jobs.list)</code></li><li><code>operation GET /v1/jobs/{id} added (jobs.get)</code></li><li><code>operation GET /v1/jobs/{id}/results added (jobs.results.list)</code></li><li><code>operation GET /v1/jobs/{id}/results.jsonl added (jobs.results.download)</code></li><li><code>operation GET /v1/webhook_endpoints added (webhook_endpoints.list)</code></li><li><code>operation GET /v1/webhook_endpoints/{id} added (webhook_endpoints.get)</code></li><li><code>operation GET /v1/webhook_endpoints/{id}/deliveries added (webhook_endpoints.deliveries.list)</code></li><li><code>operation PATCH /v1/webhook_endpoints/{id} added (webhook_endpoints.update)</code></li><li><code>operation POST /v1/events/{id}/redeliver added (events.redeliver)</code></li><li><code>operation POST /v1/jobs added (jobs.create)</code></li><li><code>operation POST /v1/jobs/{id}/cancel added (jobs.cancel)</code></li><li><code>operation POST /v1/webhook_endpoints added (webhook_endpoints.create)</code></li><li><code>operation POST /v1/webhook_endpoints/{id}/rotate_secret added (webhook_endpoints.rotate_secret)</code></li><li><code>operation POST /v1/webhook_endpoints/{id}/test added (webhook_endpoints.test)</code></li><li><code>MCP tool create_job added</code></li><li><code>MCP tool get_job added</code></li><li><code>endpoint tiktok.profile added (/v1/tiktok/profile)</code></li><li><code>resource profile is live</code></li><li><code>MCP tool get_profile added</code></li><li><code>endpoint instagram.post added (/v1/instagram/post)</code></li><li><code>resource post is live</code></li><li><code>MCP tool get_post added</code></li><li><code>endpoint facebook.search_ads added (/v1/facebook/search_ads)</code></li><li><code>resource ad is live</code></li><li><code>MCP tool search added</code></li><li><code>endpoint youtube.comments added (/v1/youtube/comments)</code></li><li><code>resource comment is live</code></li><li><code>MCP tool list_comments added</code></li></ul></details>",
      "date_published": "2026-10-26T00:00:00Z",
      "tags": [
        "added"
      ],
      "_socialtap": {
        "kind": "added",
        "endpoints": [],
        "changes": [
          "endpoint facebook.transcript: accepts video links",
          "endpoint instagram.transcript: accepts video links",
          "endpoint instagram.transcript: accepts post links",
          "endpoint tiktok.transcript: accepts video links",
          "endpoint tiktok.transcript: accepts post links",
          "endpoint youtube.transcript: accepts video links",
          "error code endpoint_retired added (HTTP 410)",
          "error code forbidden added (HTTP 403)",
          "error code idempotency_key_in_progress added (HTTP 409)",
          "error code idempotency_key_reused added (HTTP 422)",
          "error code insufficient_credits: details key credits_required added",
          "error code insufficient_credits: details key credits_available added",
          "error code invalid_cursor: details key reason added",
          "error code invalid_input: details key suggestion added",
          "error code invalid_input: details key accepted_params added",
          "error code invalid_input: details key url_kind added",
          "error code invalid_input: details key url_platform added",
          "error code invalid_input: details key accepted_url_kinds added",
          "error code invalid_input: details key endpoints added",
          "error code invalid_input: details key fields added",
          "error code job_not_found added (HTTP 404)",
          "error code overloaded: details key retry_after added",
          "error code rate_limited: details key retry_after added",
          "error code spend_limit_reached added (HTTP 402)",
          "header cache-control added",
          "header deprecation added",
          "header link added",
          "header ratelimit added",
          "header ratelimit-policy added",
          "header sunset added",
          "header traceparent added",
          "header x-client-request-id added",
          "common param fields added",
          "warning code deprecated_endpoint added",
          "shared param country added",
          "shared param lang added",
          "shared param since added",
          "shared param sort added",
          "shared param until added",
          "meta fields are part of the locked contract",
          "page fields are part of the locked contract",
          "error fields are part of the locked contract",
          "MCP tool find_endpoint added",
          "MCP tool get_transcript added",
          "header authorization added",
          "error code forbidden: details key reason added",
          "error code forbidden: details key required_scope added",
          "error code spend_limit_reached: details key api_key_id added",
          "error code spend_limit_reached: details key spend_limit added",
          "error code spend_limit_reached: details key interval added",
          "error code spend_limit_reached: details key used added",
          "error code spend_limit_reached: details key credits_required added",
          "error code spend_limit_reached: details key resets_at added",
          "error code unauthorized: details key signup_url added",
          "error code unauthorized: details key agent_signup_url added",
          "meta: field mode added",
          "MCP tool get_account added",
          "error code insufficient_credits: details key max_credits added",
          "header idempotency-key added",
          "header idempotent-replayed added",
          "header location added",
          "header prefer added",
          "header preference-applied added",
          "header webhook-id added",
          "header webhook-signature added",
          "header webhook-timestamp added",
          "event type job.completed added",
          "event type job.canceled added",
          "event type job.expired added",
          "event type credits.low added",
          "event type credits.depleted added",
          "event type api_key.spend_limit_reached added",
          "event type webhook.test added",
          "operation DELETE /v1/webhook_endpoints/{id} added (webhook_endpoints.delete)",
          "operation GET /v1/events added (events.list)",
          "operation GET /v1/events/{id} added (events.get)",
          "operation GET /v1/jobs added (jobs.list)",
          "operation GET /v1/jobs/{id} added (jobs.get)",
          "operation GET /v1/jobs/{id}/results added (jobs.results.list)",
          "operation GET /v1/jobs/{id}/results.jsonl added (jobs.results.download)",
          "operation GET /v1/webhook_endpoints added (webhook_endpoints.list)",
          "operation GET /v1/webhook_endpoints/{id} added (webhook_endpoints.get)",
          "operation GET /v1/webhook_endpoints/{id}/deliveries added (webhook_endpoints.deliveries.list)",
          "operation PATCH /v1/webhook_endpoints/{id} added (webhook_endpoints.update)",
          "operation POST /v1/events/{id}/redeliver added (events.redeliver)",
          "operation POST /v1/jobs added (jobs.create)",
          "operation POST /v1/jobs/{id}/cancel added (jobs.cancel)",
          "operation POST /v1/webhook_endpoints added (webhook_endpoints.create)",
          "operation POST /v1/webhook_endpoints/{id}/rotate_secret added (webhook_endpoints.rotate_secret)",
          "operation POST /v1/webhook_endpoints/{id}/test added (webhook_endpoints.test)",
          "MCP tool create_job added",
          "MCP tool get_job added",
          "endpoint tiktok.profile added (/v1/tiktok/profile)",
          "resource profile is live",
          "MCP tool get_profile added",
          "endpoint instagram.post added (/v1/instagram/post)",
          "resource post is live",
          "MCP tool get_post added",
          "endpoint facebook.search_ads added (/v1/facebook/search_ads)",
          "resource ad is live",
          "MCP tool search added",
          "endpoint youtube.comments added (/v1/youtube/comments)",
          "resource comment is live",
          "MCP tool list_comments added"
        ]
      }
    },
    {
      "id": "https://staging.socialtap.dev/docs/changelog/#2026-10-26-api-conventions",
      "url": "https://staging.socialtap.dev/docs/changelog/#2026-10-26-api-conventions",
      "title": "Request conventions, richer errors and response metadata",
      "content_html": "<p>Every endpoint now follows the same request conventions, and every response tells you more about itself.</p>\n<ul>\n<li><strong>Unknown parameters are rejected</strong> with <code>invalid_input</code>, free, naming the parameter and the one you most likely\nmeant (<code>username</code> → <code>handle</code>). Previously they were ignored. Common parameters (<code>max_age</code>, <code>fields</code>) are always\nknown.</li>\n<li><strong>Errors carry everything needed to react</strong> without parsing the message: <code>status</code>, <code>retryable</code>, <code>param</code>,\n<code>remediation</code>, <code>doc_url</code>, <code>details</code> (for example <code>credits_required</code>, or the endpoint a link belongs to) and\n<code>charged</code> (always false). <code>retry-after</code> is never sent on credit errors.</li>\n<li><strong>A link of the wrong kind</strong> (a profile link sent to a video endpoint, a link from another platform) is answered with\nthe endpoint that takes it.</li>\n<li><strong><code>meta</code></strong> gains <code>input</code> (what your url resolved to), <code>credits_remaining</code>, <code>client_request_id</code> and <code>warnings</code>.</li>\n<li><strong><code>fields</code></strong> selects only the fields you need, after the cache, at no cost.</li>\n<li><strong>Lists</strong> gain <code>page.end_reason</code> and a <code>Link: rel=&quot;next&quot;</code> header; <code>since</code> stops paging on newest-first lists.</li>\n<li><strong>Headers</strong>: send <code>x-client-request-id</code> to have your own ID echoed and logged, and <code>traceparent</code> to match traces.\n<code>RateLimit-Policy</code> and <code>RateLimit</code> describe the account&#39;s runaway-protection ceiling, and <code>Cache-Control: max-age</code>\nworks like <code>max_age</code>.</li>\n<li>Deprecated endpoints will announce themselves with <code>Deprecation</code> and <code>Sunset</code> headers and a warning, and answer\n<code>endpoint_retired</code> after their sunset. This changelog is also a <a href=\"/changelog.json\">JSON Feed</a>.</li>\n</ul>\n",
      "date_published": "2026-10-26T00:00:00Z",
      "tags": [
        "changed"
      ],
      "_socialtap": {
        "kind": "changed",
        "endpoints": [],
        "changes": []
      }
    },
    {
      "id": "https://staging.socialtap.dev/docs/changelog/#2026-10-26-jobs",
      "url": "https://staging.socialtap.dev/docs/changelog/#2026-10-26-jobs",
      "title": "Background jobs and batches, webhooks, events and Idempotency-Key",
      "content_html": "<p>Run many requests, or one long one, without holding a connection open, and hear back when they are done.</p>\n<ul>\n<li><strong>Jobs</strong>: <code>POST /v1/jobs</code> runs a batch of endpoint requests in the background, at each endpoint&#39;s own price, and\n<code>max_pages</code> walks a whole list server-side. With <code>?wait</code> a short job answers inline (a synchronous batch); otherwise\npoll <code>GET /v1/jobs/{id}</code> (free), page through <code>GET /v1/jobs/{id}/results</code> as items finish, or download every result\nfrom the job&#39;s signed <code>results_url</code>. <code>Prefer: respond-async</code> turns any endpoint request into a one-request job.</li>\n<li><strong>Credits</strong> are set aside per job (<code>max_credits</code>) and charged per item as it ends; failed items are free. A key&#39;s\nspend limit holds through its jobs, and a test key&#39;s jobs answer from recorded responses, free.</li>\n<li><strong>Webhooks</strong> (Standard Webhooks signatures, retried for days, secrets rotated without downtime) deliver\n<code>job.completed</code>, <code>job.canceled</code>, <code>job.expired</code>, <code>credits.low</code>, <code>credits.depleted</code> and\n<code>api_key.spend_limit_reached</code>; <code>/v1/events</code> lists every event and redelivers one on request.</li>\n<li><strong>Idempotency-Key</strong> on every POST: retrying with the same key and body never repeats the work.</li>\n<li>The SDKs gain <code>jobs</code>, <code>webhookEndpoints</code> and <code>events</code>, a create-and-wait helper and webhook signature verification.</li>\n</ul>\n",
      "date_published": "2026-10-26T00:00:00Z",
      "tags": [
        "added"
      ],
      "_socialtap": {
        "kind": "added",
        "endpoints": [],
        "changes": []
      }
    }
  ]
}
