# Social Media API Pricing: Quoted Credits Match Invoice (https://www.socialcrawl.dev/blog/social-media-api-pricing) > 6 credits for two URLs: social media API pricing as YouTube 1 + Instagram 5 in legs[]. A mangled comments cursor is a free 400. Lookup quotes 1 or 5 credits. Social media API pricing on SocialCrawl is prepaid credits per composite call. After the 2026-09-07 Prism honesty wave, the figure on the [Prism docs](/docs/prism) is the figure on the invoice. On 2026-09-08 we ran the calls live. `POST /v1/prism/post-stats` with two URLs billed **6** credits (YouTube **1** + Instagram **5**, named in `legs[]`). A mangled `prism/comments` cursor returned **400 at 0 credits** with no ledger row. `prism/lookup` charged **1 or 5** and set `resolved.endpoint` to the billed route. Auth is one `x-api-key`. Every envelope carries `success`, `data`, `credits_used`, and `request_id`. [Credits never expire](/pricing). This is not official-platform seat pricing. Three captured request/response pairs follow, plus the doc-correction table. Labels moved. Prices did not go up. A matte invoice slip beside a clay-amber dial gauge, the quoted credits a social media API pricing composite writes onto the invoice. ## What is a social media API actually charging you for? A live `POST /v1/prism/post-stats` with two URLs billed **6** credits, named in `legs[]`. The batch POST exists so one social media API call can take mixed-platform URLs and return one invoice. You already have a list of post links. You do not want to branch on platform before the request. Send the URLs; Prism fans out; you read `results[].cost` and `legs[]`. The published example used to be a GET. A GET does nothing useful, and it does not cost you anything either. ```bash curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \ "https://www.socialcrawl.dev/v1/prism/post-stats" ``` Trimmed 405 from 2026-09-08 (`req-4A2LtjSjaAg8dGdW`). Header `Allow: POST`. No ledger row. ```json { "success": false, "error": { "type": "METHOD_NOT_ALLOWED", "message": "Method GET is not allowed. This endpoint accepts POST only.", "status": 405, "doc_url": "https://www.socialcrawl.dev/docs/errors#method-not-allowed" }, "credits_used": 0, "credits_remaining": null } ``` The [error taxonomy](/docs/errors) names the type. HTTP [405 Method Not Allowed](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405) with `Allow: POST` is the spec-correct response; `credits_used` is 0 because the router rejected the method before any leg ran. The live call is POST with a JSON body. Same two public URLs: a YouTube watch link and an Instagram post. ```bash curl -s -X POST \ -H "x-api-key: $SOCIALCRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{"urls":["https://www.youtube.com/watch?v=dQw4w9WgXcQ","https://www.instagram.com/p/CnpPou9hWqq/"]}' \ "https://www.socialcrawl.dev/v1/prism/post-stats" ``` Trimmed 200 (`req-fpJQRsFyRD8XO8rS`). `cached` was `false`. Envelope `credits_used` is **6**. ```json { "success": true, "data": { "results": [ { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "platform": "youtube", "status": "ok", "id": "dQw4w9WgXcQ", "engagement": { "views": 1813133350, "likes": 19376214, "comments": 2457358 }, "cost": 1 }, { "url": "https://www.instagram.com/p/CnpPou9hWqq/", "platform": "instagram", "status": "ok", "id": "3020013795029641898", "shortcode": "CnpPou9hWqq", "engagement": { "views": 45016384, "likes": 1393062, "comments": 16437, "shares": 46 }, "cost": 5 } ], "summary": { "total": 2, "ok": 2, "coverage": 1, "credits_charged": 6, "credits_refunded": 0 }, "legs": [ { "endpoint": "/v1/youtube/video", "status": 200, "credits_used": 1, "latency_ms": 135, "error": null }, { "endpoint": "/v1/instagram/post/stats", "status": 200, "credits_used": 5, "latency_ms": 1997, "error": null } ] }, "credits_used": 6, "cached": false } ``` Read that as an invoice. YouTube `cost` is 1, Instagram `cost` is 5, `summary.credits_charged` is 6. The billed routes are in the body: `/v1/youtube/video` at 135 ms and `/v1/instagram/post/stats` at 1,997 ms. Instagram API pricing on this composite is **5 credits on that leg**, not a [Meta Instagram API](https://developers.facebook.com/docs/instagram-platform) seat. If you persist invoices, store `request_id` next to `credits_used`. The two numbers that explain a 6-credit charge are already in `legs[]`: 1 + 5. You do not need a separate pricing table at read time for this call. Both rows were `status: ok` and `cached: false`, so this 6 is a live fetch, not a free replay. Two sibling batch routes behave the same way. `GET /v1/prism/profiles` (`req-49IymhIF77MnUAow`) and `GET /v1/prism/comment-lookup` (`req-T2Hsccp5by1UlyAE`) also returned 405, `Allow: POST`, `credits_used: 0`. The matching POSTs ran and billed. Profiles with platform `tiktok` and handle `mkbhd` billed **1** via `/v1/tiktok/profile` (followers 2,335,225, `req-eqRPt75dfK1RTqmS`) — TikTok API pricing as credits per call, not a [TikTok API](https://developers.tiktok.com/doc/tiktok-api-v2-introduction) developer-tier page. Comment-lookup on a TikTok `comment_url` billed **2** on `results[0].cost` (`req-in1zIa6PWiTBlM3s`); that success body had no `legs[]`. ## Why is a mangled comments cursor a free 400, not a rebill? Failure billing is the other half of the honesty wave. Before 2026-09-07, a truncated cursor on `prism/comments` returned page one as a 200 and rebilled, up to 200 credits a lap. Same class of cursor as [Twitter API pagination](/blog/twitter-api-pagination) — pass `next_cursor` back verbatim — except here a mangled token used to silently restart and charge you for it. That path now costs 0 credits, because validation fails before any page is fetched. ```bash curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \ "https://www.socialcrawl.dev/v1/prism/comments?url=https://www.youtube.com/watch?v=dQw4w9WgXcQ&cursor=not-one-of-ours" ``` Trimmed 400 (`req-UkthrGypeEGzlweX`). Envelope `credits_used` is **0**. The ledger has no row for this `request_id`. ```json { "success": false, "error": { "type": "INVALID_REQUEST", "message": "Invalid pagination cursor for GET /v1/prism/comments. Pass back the `next_cursor` value from a previous response verbatim; this endpoint issues every cursor it accepts, and a truncated one would silently re-serve the first page.", "status": 400, "doc_url": "https://www.socialcrawl.dev/docs/errors#invalid-request" }, "credits_used": 0 } ``` The error tells you what to pass back. HTTP [400 Bad Request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400) is validation, not a billed fetch: this endpoint issues every cursor it accepts, and a truncated one would re-serve the first page. We did not run a comments success page (metered, up to 200 credits). Same never-on-ledger class: incomplete `GET /v1/prism/crisis-radar` with no params returned 400 at 0 credits, ledger absent (`req-vEBh4ArTgNybbquq`). That message names the missing field: "Missing required parameter(s): brand. This endpoint accepts: brand (required)." We did not run the 15–45 credit success path, so there is no success body to show. A different 400 is not free in the same way. `korea-gap` with `include=digest` (`req-k2HGzXVq3jMC29Is`), `reputation` with `include=digest` (`req-jVyEzZS7gCzOkyBB`), and `org-radar` with `include=not-a-legal-value` (`req-p36sXmbAzZdHjvff`) are 400 at envelope 0, but the ledger held then refunded — −15/+15, −30/+30, −26/+26. The live error is generic on all three: "Invalid request parameters for this endpoint. Your credits have been refunded." It does not name the legal `include` list. Those values live in the [Prism docs](/docs/prism), not in the error. Envelope `credits_used: 0` is not the same as "never billed." A single URL tag splitting into three unlabeled pipes of different thickness, the 1-credit versus 5-credit bands a Prism API lookup bills. ## How does Prism API quote the credits you are actually charged? Paste a URL into the Prism API lookup. Prism resolves the platform endpoint and you pay that endpoint's price. There is no routing surcharge. ```bash curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \ "https://www.socialcrawl.dev/v1/prism/lookup?url=https://www.youtube.com/watch?v=dQw4w9WgXcQ" ``` Trimmed 200 (`req-0FFXd8arjWBhkqYr`). `cached` was `false`. Charge is **1**, and `resolved.endpoint` is `/v1/youtube/video`. ```json { "success": true, "data": { "resolved": { "platform": "youtube", "endpoint": "/v1/youtube/video", "params": { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }, "archetype": "Post" }, "post": { "id": "dQw4w9WgXcQ", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "content": { "text": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)", "duration_seconds": 214 }, "author": { "display_name": "Rick Astley" }, "engagement": { "views": 1813133350, "likes": 19376214, "comments": 2457358 }, "published_at": "2009-10-25T06:57:33.000Z" }, "computed": { "engagement_rate": 0.012042, "language": "en", "content_category": "other", "estimated_reach": 2175760020 }, "legs": [ { "endpoint": "/v1/youtube/video", "status": 200, "credits_used": 1, "latency_ms": 66, "error": null } ] }, "credits_used": 1, "cached": false } ``` The row includes `computed`: `engagement_rate` 0.012042, `language` en, `estimated_reach` 2,175,760,020. You did not ask for those fields. They come with the canonical post. The same lookup on a repo URL and a product URL billed the resolved route's price, not a flat lookup fee. | Input URL | `resolved.platform` | `resolved.endpoint` | credits_used | request_id | | --- | --- | --- | ---: | --- | | `https://www.youtube.com/watch?v=dQw4w9WgXcQ` | youtube | `/v1/youtube/video` | 1 | `req-0FFXd8arjWBhkqYr` | | `https://github.com/facebook/react` | github | `/v1/github/repo` | 1 | `req-XoYMu4VmUwWDgKzP` | | `https://www.amazon.com/dp/B07FZ8S74R` | amazon | `/v1/amazon/product` | 5 | `req-kYa5H3QmGYEYKdBN` | GitHub came back as archetype **`Author`**, `username` `react/react`, followers 249,635. That is what the body contained. We are not relabeling it as a repo object. A billing script should key off `resolved.endpoint`, not `resolved.archetype`. The billed route is `/v1/github/repo` at 1 credit; the archetype is a separate (and, here, surprising) field. Amazon billed **5** (`req-kYa5H3QmGYEYKdBN`). Title: Echo Dot (3rd Gen, 2018 release). Rating 4.7 from 1,038,003 reviews. The product leg took 14,685 ms. That is the other lookup band: most social item links are 1 credit; Amazon is 5. The call succeeded — 14.7 s is latency on this pull, not a timeout. ```json { "success": true, "data": { "resolved": { "platform": "amazon", "endpoint": "/v1/amazon/product", "params": { "asin": "B07FZ8S74R" }, "archetype": "Product" }, "product": { "id": "B07FZ8S74R", "url": "https://www.amazon.com/dp/B07FZ8S74R", "title": "Echo Dot (3rd Gen, 2018 release) - Smart speaker with Alexa - Charcoal", "brand": "Amazon", "rating": { "average": 4.7, "count": 1038003 }, "availability": "In Stock" }, "legs": [ { "endpoint": "/v1/amazon/product", "status": 200, "credits_used": 5, "latency_ms": 14685, "error": null } ] }, "credits_used": 5, "cached": false } ``` Until 2026-09-07, lookup was advertised at **0** and charged **1–5**. After: [llms-prism.txt](https://www.socialcrawl.dev/llms-prism.txt) quotes the resolved endpoint's own price (1 for most social item links, 5 for Amazon and LinkedIn). These 1 / 1 / 5 figures are live charges (`cached: false` on all three). A later replay of the same URL may be a free cache hit. Two limits still apply. Live [Prism docs](/docs/prism) reject profile, channel, and storefront URLs as a free 400 — item links only. This run used watch, repo, and product URLs. Lookup currently fails with a refunded 502 on TikTok, Reddit, and LinkedIn. Those URLs were not called here. Until that dispatch fix ships, call those platforms' own endpoints. ## How do social media API credits work on a composite invoice? Social media API pricing here is prepaid API credits, not a monthly seat. They never expire. Empty balance is `402 INSUFFICIENT_CREDITS` and the call is not made. Public [credit packs](/pricing): | Pack | Credits | Price | | --- | ---: | --- | | Free | 100 | £0, one-time | | Starter | 2,500 | £15 | | Growth | 20,000 | £49 | | Pro | 150,000 | £299 | No auto-renewal. Sitewide non-Prism bands are Standard 1 / Advanced 5 / Premium 10 credits. Prism overrides those bands. A unified social media API here is one key, one credit ledger, and [the unified schema](/docs) across composites. Social media data API pricing lands on one invoice. The 2026-09-07 wave did not raise a price. It moved labels so [the page](/docs/prism) now matches the invoice. No endpoint returns fewer rows than before. The rows below were not re-run at the new label (brand-mentions at 50 credits was over this run's budget). The 1 / 1 / 5 lookup charges and the comments 400 are live from 2026-09-08. | Surface | Before | After | | --- | --- | --- | | `prism/lookup` | advertised 0, charged 1–5 | advertised 1–5 (this run: 1, 1, 5) | | `brand-mentions`, `leads` | page 20, invoice 50 | page 50 | | `truthsocial-pulse` | page 8, invoice 20 | page 20 | | `launch-echo` | 10 → 20 | 20 | | `devtool-pulse` | 15 → 20 | 20 | | `earned-media` | 20 → 25 | 25 | | `crisis-radar` stage 1 | 10 → 15 | 15 (span 15–45) | | Bad cursor on `prism/comments` | 200 + up to 200 cr | 400 / 0 cr (live) | | Incomplete `crisis-radar` | 400 / 0 cr, unnamed | 400 / 0 cr, names `brand` (live) | | Three batch POST examples | published GET → 405 | published POST runs (live) | A social listening API composite (`brand-mentions`) sits on the invoice at 50 because that is what it always billed — the page caught up. That 50 is the 2026-09-07 label correction in the table, not a success call from this run. Listening recipes belong in the [social media monitoring API](/blog/social-media-monitoring-api) post; this one is the invoice. `legs[]` had the same honesty problem. Five composites used to report a content-analysis leg at 5 credits when it costs 20, so a 30-credit `prism/reputation` invoice could not be added up from its own `legs[]`. All nine of those composites now report 20. We did not re-run a reputation success; the only reputation call on this run is the invalid-`include` 400. What this wave did not change: 1. **Empty-success still bills.** Sixteen Prism composites charge full price when every leg is 200 and the answer is genuinely empty. `prism/employer-brand` bills 30 credits for no themes when all thirteen legs returned 200. That is a pricing decision, not this wave. It conflicts with the [/pricing FAQ](/pricing) line "You only pay for calls that return data." Both are true in their own scope: failed calls and empty *non-composite* reads refund; those sixteen composites do not. 2. Lookup currently 502s (and refunds) on TikTok, Reddit, and LinkedIn. Call those platforms' own endpoints until that dispatch fix ships. Profile and channel URLs are already a free 400 on the live docs — item links only. 3. `prism/app-reviews` can time out at 49–54 s against a 48 s budget; the timed-out call is refunded. Not called on this run. 4. Invalid `include` is hold-then-refund, not never-billed. See the three ledger pairs above. Instagram API pricing and TikTok API pricing in this cluster mean credits per call on one ledger, not official developer seats. Per-endpoint figures live on [/docs/endpoint-pricing](/docs/endpoint-pricing). ## How do you replay these calls with one API key? 1. Get a key. The free pack is 100 credits, and they never expire — [packs and signup](/pricing). 2. Check the ledger, then replay the cheapest named route against the SocialCrawl API. `GET /v1/credits/balance` first. Then the YouTube lookup curl from the previous section (1 credit, names `resolved.endpoint`). Batch routes are POST plus JSON; GET is a free 405. ```bash curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \ "https://www.socialcrawl.dev/v1/credits/balance" ``` 3. From there: paste the same URL in the [Explorer](/explorer) and see the data before writing a single line. Composite list: [Prism docs](/docs/prism). Per-call figures: [endpoint credit list](/docs/endpoint-pricing). Error types: [error taxonomy](/docs/errors). Reconcile as we did. Read `credits_used` on the envelope, then `GET /v1/credits/transactions?limit=50` against each `request_id`. Invalid `include` shows a hold then a refund. A mangled cursor does not appear on the ledger at all. Replay lookup from the [Prism docs](/docs/prism). Credit packs are on [/pricing](/pricing). ## Frequently asked questions ### How do social media API credits work? Prepaid packs, never expire, no monthly seat. Prism composites bill the sum of successful legs — the post-stats 6 above is YouTube 1 plus Instagram 5. Envelope `credits_used` is the net. Cache hits cost 0. Empty balance is 402 and the call is not made. Packs are in the table above. ### How can I tell what an API call costs before I send it? The Prism page figure is the invoice figure after 2026-09-07. The response names the billed route: `legs[].endpoint` plus `legs[].credits_used` on composites, `resolved.endpoint` on lookup. Cross-check [Prism docs](/docs/prism), [endpoint pricing](/docs/endpoint-pricing), and [llms-prism.txt](https://www.socialcrawl.dev/llms-prism.txt). Lookup was the counter-example (advertised 0, charged 1–5) and is now labeled 1–5. ### Why did my API example return 405? Batch Prism routes (`post-stats`, `profiles`, `comment-lookup`) accept **POST only**. A GET returns 405 `METHOD_NOT_ALLOWED`, `Allow: POST`, `credits_used: 0`. The published examples used to be GETs; they are POSTs with a JSON body now. Cite `req-4A2LtjSjaAg8dGdW` above. ### Why is a bad pagination cursor a free 400 instead of a rebill? A truncated `prism/comments` cursor used to 200, re-serve page one, and full-charge (up to 200 credits a lap). Now: 400 `INVALID_REQUEST` at 0 credits, no ledger row, and the message says pass `next_cursor` verbatim. Cite `req-UkthrGypeEGzlweX`. Distinct from invalid-`include` hold-then-refund. ### Is this X API pricing or Twitter API pricing? No. This post is credit pricing for Prism composites — credits per call, never-expire packs. It is not X API pricing, and it is not Twitter API pricing. If you want seat-tier math for the official [X developer platform](https://developer.x.com/en/docs/twitter-api), this is the wrong page. ### Do advertised credits match the invoice on a Prism composite? Yes, after 2026-09-07. `prism/lookup` was advertised at 0 and charged 1–5; this run billed **1, 1, and 5** with `cached: false`. `brand-mentions` and `leads` were labeled 20 and invoiced 50; the page is now 50. The 2026-09-07 table above is the label correction. Prices did not go up. ### What happens when a composite returns empty but every leg succeeded? Sixteen Prism composites still charge full price when every leg is 200 and the answer is genuinely empty. `prism/employer-brand` bills 30 credits for no themes when all thirteen legs returned 200. That is a pricing decision, not this wave. It conflicts with the [/pricing FAQ](/pricing) line "You only pay for calls that return data." Failed calls and empty non-composite reads refund; those sixteen composites do not.