InsightSocial API

Response schema

The InsightSocial API envelope, pagination, response headers, idempotent replays and fresh fetches.

Every data endpoint answers in one envelope, success or error, so a single parser handles all nine platforms. The two account endpoints are the exception: GET /v1/credits returns a balance body of its own (it still carries success, credits_used and credits_remaining), and GET /v1/endpoints returns the catalogue in its own shape.

Successful response

Response
{
  "success": true,
  "platform": "instagram",
  "endpoint": "/v1/instagram/profile",
  "data": {
    "author": { "username": "natgeo", "followers": 276000000 }
  },
  "credits_used": 20,
  "credits_remaining": 9980,
  "request_id": "req_1a2b3c4d5e6f",
  "cached": false,
  "idempotent_replay": false,
  "charge_reason": "miss",
  "free_call": false
}

Envelope fields

FieldTypeAlways presentDescription
successbooleanyestrue on success, false on error.
platformstringyesThe platform you called, such as instagram.
endpointstringyesThe path you called, such as /v1/instagram/profile.
dataobjectyesThe platform payload. Its shape depends on the endpoint; see its API reference page.
paginationobjectnoList endpoints only. See List endpoints.
credits_usedintegeryesCredits charged for this call. 0 for replays, owned re-reads, free calls, empty results and failures.
credits_remainingintegeryesYour balance after this call.
request_idstringyesOur identifier for this call, in the form req_ plus 12 hex characters.
cachedbooleanyestrue when the result came from the shared cache rather than a live fetch.
idempotent_replaybooleanyestrue when this is a replay of an earlier call with the same Idempotency-Key.
charge_reasonstringyesWhy credits_used has the value it has. See below.
free_callbooleanyestrue when the call used one of your free calls, so credits_used is 0.

charge_reason

ValueMeaningCredits
missA live fetchThe endpoint's price, or for a metered endpoint what the call used
shared_cacheServed from the shared cache5
ownedYou already paid for this exact call inside its ownership window0
replayAn idempotent replay of a call you already made0
no_resultNothing to charge for, such as an empty result or a dry_run=1 call0

Ownership windows and the other pricing rules are on Credits.

Fields inside data

Two fields live inside data rather than at the root of the envelope.

data.dropped. On list endpoints, counts items left out of the page because they could not be mapped to the endpoint's schema. A healthy page carries "dropped": 0. It is the only sign that a page came back short, so check it on every page instead of judging completeness by the length of items.

dropped is inside data

dropped sits next to items under data, while pagination sits at the root. Reading response.dropped returns undefined, which is easy to mistake for zero.

data._warnings. An array of human-readable notes, present only when something about the data was ambiguous or partial:

Response
{
  "data": {
    "author": { "username": "natgeo" },
    "_warnings": [
      "posts: one call reads one page of 12 posts; pass posts_cursor back as cursor for the next page"
    ]
  }
}

Treat warnings as advisory. The response is still valid. When there is nothing to report, the key is absent.

Endpoints that attach computed fields or labels return them inside data as well.

Error response

Response
{
  "success": false,
  "error": {
    "type": "INSUFFICIENT_CREDITS",
    "message": "This call needs up to 340 credits and 120 remain. Top up at https://www.insightsocial.app/pricing"
  },
  "request_id": "req_1a2b3c4d5e6f",
  "credits_used": 0,
  "credits_remaining": 120
}
FieldDescription
error.typeA stable string to branch on.
error.messageA readable explanation, often naming what to fix. Do not parse it.
request_idQuote it to support.
credits_usedAlways 0: failed calls are never charged.
credits_remainingYour balance when we know it, otherwise null (for example on authentication failures).

The full list of types is on Errors.

Response headers

HeaderValue
X-Request-IdSame as request_id in the body.
X-Credits-UsedCredits charged for this call.
X-Credits-RemainingYour balance after the call. Omitted when it is unknown, never sent as a placeholder 0.
Retry-AfterSeconds to wait. Sent on 429, on 409 IDEMPOTENCY_IN_PROGRESS and on some 503 responses.
Cache-Controlno-store. Do not cache API responses in a shared proxy.

CORS headers are also set, and X-Request-Id, X-Credits-Used, X-Credits-Remaining and Retry-After are exposed to browser code. Keys still belong on your server; see Authentication.

List endpoints

List responses put their rows in data.items and carry a pagination object at the root of the envelope:

Response
{
  "success": true,
  "platform": "tiktok",
  "endpoint": "/v1/tiktok/search",
  "data": {
    "items": [
      /* ... */
    ],
    "dropped": 0
  },
  "pagination": {
    "next_cursor": "is2.eyJ2IjoyLCJwIjoiNDgyMTk5NjAzNzEifQ",
    "has_more": true,
    "page_size": 30
  },
  "credits_used": 20,
  "credits_remaining": 9960,
  "request_id": "req_1a2b3c4d5e6f",
  "cached": false,
  "idempotent_replay": false,
  "charge_reason": "miss",
  "free_call": false
}
FieldDescription
next_cursorSend it back as the cursor query parameter to get the next page. Starts with is2.; pass it unchanged.
has_morefalse on the last page. Stop there.
page_sizeRows on this page.
stopped_atOnly on creator post lists called with since or stop_at_id. Says which boundary ended the walk, such as since.

Some endpoints page with their own parameter, such as page or continuationToken, instead of cursor. Their reference pages name it. The full loop is on Pagination.

Idempotent requests

Send an Idempotency-Key header to make a call safe to retry. Use a fresh UUID for each logical operation.

cURL
curl "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame" \
  -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \
  -H "Idempotency-Key: c3f9d27e-81b4-4e06-a5d2-94be0f6c1a78"
  • A replay returns idempotent_replay: true, charge_reason: "replay" and credits_used: 0.
  • If the original call with the same key is still running, you get 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Wait, then send the same key again.
  • Keys are scoped to your account.
  • A key must be at most 255 characters of letters, digits, ., _, : or -. A key that does not fit is ignored, and the call runs as an ordinary request.

Force a fresh fetch

Repeat calls can be served from the shared cache (cached: true) or free as an owned re-read. To skip both and fetch live, send Cache-Control: no-cache, or add fresh=1 to the query:

cURL
curl "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame" \
  -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \
  -H "Cache-Control: no-cache"

A fresh fetch is always charged at the normal price. See Credits for ownership windows.

Next steps

On this page