100 free credits. No credit card required.Start building
Logo
Back to blog

Social Media API Pricing: Quoted Credits Match Invoice

·17 min read

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: Quoted Credits Match Invoice

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 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. 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 names the type. HTTP 405 Method Not Allowed 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 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 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 — 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 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, 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 URLresolved.platformresolved.endpointcredits_usedrequest_id
https://www.youtube.com/watch?v=dQw4w9WgXcQyoutube/v1/youtube/video1req-0FFXd8arjWBhkqYr
https://github.com/facebook/reactgithub/v1/github/repo1req-XoYMu4VmUwWDgKzP
https://www.amazon.com/dp/B07FZ8S74Ramazon/v1/amazon/product5req-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 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 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:

PackCreditsPrice
Free100£0, one-time
Starter2,500£15
Growth20,000£49
Pro150,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 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 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.

SurfaceBeforeAfter
prism/lookupadvertised 0, charged 1–5advertised 1–5 (this run: 1, 1, 5)
brand-mentions, leadspage 20, invoice 50page 50
truthsocial-pulsepage 8, invoice 20page 20
launch-echo10 → 2020
devtool-pulse15 → 2020
earned-media20 → 2525
crisis-radar stage 110 → 1515 (span 15–45)
Bad cursor on prism/comments200 + up to 200 cr400 / 0 cr (live)
Incomplete crisis-radar400 / 0 cr, unnamed400 / 0 cr, names brand (live)
Three batch POST examplespublished GET → 405published 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 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 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.

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.
  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"
  1. From there: paste the same URL in the Explorer and see the data before writing a single line. Composite list: Prism docs. Per-call figures: endpoint credit list. Error types: error taxonomy.

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. Credit packs are on /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, endpoint pricing, and 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, 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 line "You only pay for calls that return data." Failed calls and empty non-composite reads refund; those sixteen composites do not.

Topics
#social-media-api-pricing#api-credits#social-media-api#prism-api#social-listening-api#instagram-api-pricing#tiktok-api-pricing#unified-social-media-api

Related posts

🤖 AI agent or LLM? Read this page as markdown