Credits
What a call costs, how metered calls are held and settled, what is free, and where your balance comes from.
Every call is priced per endpoint in credits. A fixed endpoint always costs the same; a metered endpoint quotes a range and charges what the call actually used. Calls that fail or find nothing cost nothing. Your balance is the same one you use for InsightSocial exports.
What does a call cost?
Each endpoint has its own price, listed on its reference page and in the full table at Endpoint pricing. There are two kinds.
Fixed. One number, charged on every successful call.
| Endpoint | Credits |
|---|---|
GET /v1/instagram/profile | 10 |
GET /v1/linkedin/profile | 50 |
GET /v1/tiktok/post/transcript | 100 |
GET /v1/youtube/channel/about | 250 |
Metered. A range. What you pay depends on how much the call reads, for example how many pages of comments it walked.
| Endpoint | Credits |
|---|---|
GET /v1/instagram/profile/posts | 10–130 |
GET /v1/tiktok/search | 10–370 |
GET /v1/linkedin/search/people | 100–500 |
GET /v1/reddit/profile/comments | 20–2,000 |
GET /v1/endpoints returns the same prices as JSON: credits is a number for a fixed endpoint and { "min", "max" } for a metered one. It needs no key and costs nothing.
Reserve the ceiling, settle the actual
Before a call runs, we hold the most it can cost against your balance: the fixed price, or, on a metered endpoint, the most that call can use with the parameters you sent. A call without limit or include holds one plain page, not the top of the range; asking for more rows or a join holds more. When the call finishes, we charge what it really used and release the rest. On a metered endpoint credits_used is often below the hold.
You never pay more than the ceiling. If you send max_pages (see Pagination), the ceiling is the listed maximum multiplied by max_pages, and that product is the most the call can cost.
If your balance cannot cover the ceiling, the call is refused before it starts:
{
"success": false,
"error": {
"type": "INSUFFICIENT_CREDITS",
"message": "This call needs up to 130 credits and 120 remain. Top up at https://www.insightsocial.app/pricing"
},
"request_id": "req_1a2b3c4d5e6f",
"credits_used": 0,
"credits_remaining": 120
}The status is 402 and nothing is charged.
Why a call cost what it did
Every successful response carries charge_reason, so you can tell why credits_used has the value it has.
charge_reason | What happened | Credits |
|---|---|---|
miss | We fetched the data for you | The endpoint's price (metered: what it used) |
shared_cache | The answer came from our shared cache (cached: true) | 2 |
replay | A retry with the same Idempotency-Key | 0 |
no_result | Nothing was found | 0 |
dry_run | You asked for a price quote with dry_run=1 | 0 |
Errors are never charged either: every error response has credits_used: 0. That includes a request refused with 400 UNSUPPORTED_PARAMETER because it sent an analysis parameter that schema 2 does not accept; see Errors.
Repeating a call
Repeating a call is charged like the first time, because a repeat can return newer data. Store responses you need again on your side. A retry with the same Idempotency-Key is the exception: it returns the recorded outcome and costs 0 (replay). See Caching.
Price a call without running it
Add dry_run=1 to any data endpoint to get our price quote instead of the data. Nothing is fetched and nothing is charged:
curl "https://api.insightsocial.app/v1/instagram/profile/posts?handle=nasa&dry_run=1" \
-H "x-api-key: $INSIGHTSOCIAL_API_KEY"{
"success": true,
"platform": "instagram",
"endpoint": "/v1/instagram/profile/posts",
"schema_version": "2",
"data": {
"dry_run": { "credits_min": 10, "credits_max": 130 }
},
"unavailable": [],
"credits_used": 0,
"credits_remaining": 9980,
"request_id": "req_2ac2c2b769ef",
"cached": false,
"idempotent_replay": false,
"charge_reason": "dry_run",
"free_call": false
}credits_min is the least the call can cost and credits_max is what we would hold for those exact parameters, including the max_pages you sent. A quote never uses a free call.
Prices under schema 2
Prices did not change with schema 2. A few metered endpoints hold less of your balance while they run, because the analysis they used to do, and could be charged for, is gone. The charge is still what the call actually used.
Free calls
Every account gets 10 free calls, once, for its lifetime. A free call is any call that would have been charged (a miss or a shared_cache) whose ceiling is 100 credits or less. It comes back with free_call: true and credits_used: 0.
Calls above 100 credits are charged normally even while free calls remain. Empty results, errors and replays of a call we already answered never use one up. The one replay that can use a free call is a replay of a call we never answered successfully, because that replay is charged; see Production checklist.
Where your credits come from
| Source | Credits | Expires |
|---|---|---|
| Free plan | 500 per month | Resets on the 1st of each month (UTC) |
| Pro plan ($9.99/month, or $7.99/month billed yearly) | 10,000 per month | Resets monthly |
| Credit packs (one-time purchase) | Pack size | Never |
The monthly grant is spent first and pack credits second. Referral bonuses are added to your pack credits.
This is one balance, shared with InsightSocial exports. Credits you spend on the API reduce what you can export, and the other way round.
Buy a plan or a pack at insightsocial.app/pricing.
Non-refundable credits
API credits are non-refundable. Failed calls, empty results and dry_run calls are simply never charged in the first place.
How do I check my balance?
- On every response. The body has
credits_remaining, and theX-Credits-Remainingheader carries the same number. The header is left out when the balance could not be read. - With
GET /v1/credits. Needs your key, costs 0 credits. - In the dashboard. The API section of your portal shows balance, usage and an activity log.
curl "https://api.insightsocial.app/v1/credits" \
-H "x-api-key: $INSIGHTSOCIAL_API_KEY"{
"success": true,
"credits_used": 0,
"credits_remaining": 9180,
"plan": { "tier": "pro", "credits_per_month": 10000, "resets_at": "2026-10-01T00:00:00.000Z" },
"usage": { "window_start": "2026-09-01T00:00:00.000Z", "used": 1320, "used_export": 400, "used_api": 920 },
"pack_credits": 500,
"free_calls": { "remaining": 0, "total": 10 },
"key": { "id": "3f6c2a8e-7b41-4d0f-9a52-1c8e5d7b9f20", "name": "production" },
"request_id": "req_1a2b3c4d5e6f"
}Retries with an Idempotency-Key are not charged twice
Send an Idempotency-Key header and retry with the same value. A replay of a call we already answered comes back with idempotent_replay: true, charge_reason: "replay" and credits_used: 0. See Production checklist for the key format and the edge cases.
Next steps
Endpoint pricing
Caching
Pagination
max_pages changes the ceiling.Testing your integration
Endpoints billed per item
/v1/linkedin/profile/all and /v1/pinterest/url-stats take a list in urls and are billed per item: the listed price is for one URL, and a call with three URLs costs three times as much. The hold and the dry_run quote count the URLs the same way.