InsightSocial API

Errors

Every InsightSocial API error type with its status, what to do about it, and copy-paste retry loops.

Every failure returns the same envelope: success: false, an error object with a type to branch on and a readable message, and the usual request_id and credit fields. A failed call is never charged.

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
}
  • error.type is what your code should branch on.
  • error.message explains the failure in a sentence and often names what to change. Show it or log it, but do not parse it.
  • credits_used is 0 on every error.
  • credits_remaining is your balance when we know it, and null when we do not (authentication failures, for example).
  • request_id matches the X-Request-Id header. Include it when you contact support.

Error types

error.typeStatusRetry?What it means
MISSING_API_KEY401NoNo x-api-key header on the request
INVALID_API_KEY401NoThe value is not an InsightSocial key, or no key matches it
API_KEY_REVOKED401NoThe key has been revoked
INSUFFICIENT_CREDITS402NoYour balance is below what this call needs to hold
UNKNOWN_PLATFORM404NoThe first path segment is not one of the nine platforms
UNKNOWN_ENDPOINT404NoThe platform exists but that path does not
RESOURCE_NOT_FOUND404NoNothing exists at the identifier you sent
METHOD_NOT_SUPPORTED405NoThis endpoint is not available through the API
IDEMPOTENCY_IN_PROGRESS409Yes, after Retry-AfterA call with the same Idempotency-Key is still running
RATE_LIMITED429Yes, after Retry-AfterMore than 60 requests in 60 seconds on this key
CONCURRENCY_LIMIT429Yes, after Retry-AfterMore than 10 requests in flight on this key
CLIENT_CLOSED_REQUEST499Your callYour client disconnected before the response
INTERNAL_ERROR500Yes, with backoffSomething went wrong on our side
SERVICE_UNAVAILABLE503Yes, after Retry-After or backoffWe could not complete the call right now
UPSTREAM_ERROR503Yes, after Retry-AfterThe platform did not answer in time
Parameter errors, such as INVALID_REQUEST or BAD_REQUEST400 (or another 4xx)NoA parameter is missing, invalid, or not accepted by this endpoint

Parameter errors can carry different types

When a request is rejected because of its parameters, the error.type is not drawn from a fixed list: you will usually see INVALID_REQUEST or BAD_REQUEST, but other values occur. Treat any 4xx you do not recognise as "fix the request", and read error.message, which says what was wrong.

Which errors to retry

Retry only RATE_LIMITED, CONCURRENCY_LIMIT, IDEMPOTENCY_IN_PROGRESS, SERVICE_UNAVAILABLE, UPSTREAM_ERROR and INTERNAL_ERROR. Everything else is deterministic: the same request fails the same way until you change the request, the key or your balance.

When a response carries Retry-After, wait at least that many seconds. Otherwise back off exponentially with jitter, and give up after a few attempts.

Error reference

MISSING_API_KEY

401. No x-api-key header reached the API. Send the header, and if you already do, make sure nothing between you and the API, such as a proxy or gateway, removes it. A key sent in Authorization is not read and also produces this error. See Authentication.

INVALID_API_KEY

401. Either the value does not look like an InsightSocial key (keys start isk_live_ or isk_test_), or it looks right but matches no key. Copy it again from API keys.

API_KEY_REVOKED

401. The key was revoked in the dashboard. Create a new one in the dashboard.

INSUFFICIENT_CREDITS

402. Before a call runs, we hold the most it can cost. If your balance is below that amount, the call is refused and nothing is charged. credits_remaining shows your balance, and the message states both numbers.

For a metered endpoint, the amount held is the top of its price range, and on endpoints that accept max_pages it is multiplied by the number of pages. You can therefore get a 402 on a call that would have cost less in the end. Fewer pages, or a fixed-price endpoint, holds less. Top up on the pricing page; retrying without a top-up fails the same way.

UNKNOWN_PLATFORM

404. The platform segment of the path is not one we serve. The nine platforms are instagram, tiktok, facebook, linkedin, twitter, threads, youtube, reddit and pinterest.

UNKNOWN_ENDPOINT

404. The path is not in the catalogue. Check it against GET /v1/endpoints or the API reference.

RESOURCE_NOT_FOUND

404. The endpoint exists, but nothing is there for the identifier you sent: a handle that does not exist, a deleted post, and so on. You are not charged. Retrying the same identifier returns the same answer, so record it and move on.

METHOD_NOT_SUPPORTED

405. This path is in the catalogue but cannot be called through the API. Pick another endpoint.

IDEMPOTENCY_IN_PROGRESS

409. An earlier call with the same Idempotency-Key has not finished. Wait for Retry-After, then send the same request with the same key. Once the original has finished, you get its result as a free replay.

RATE_LIMITED

429. This key sent more than 60 requests in a sliding 60-second window. Retry-After is the number of seconds until the oldest request leaves the window. Nothing is charged. See Rate limits.

CONCURRENCY_LIMIT

429. This key already had 10 requests in flight. Retry-After is 1, since a slot frees as soon as any open request returns. Shrink your worker pool.

CLIENT_CLOSED_REQUEST

499. Your client closed the connection before we answered. You only see this in logs, since nobody was listening for the response. Give slow endpoints a generous client timeout.

INTERNAL_ERROR

500. An unexpected error on our side. Nothing was charged. Retry with backoff, and if it keeps happening, contact support with the request_id.

SERVICE_UNAVAILABLE

503. We could not complete the call right now. Causes include being unable to verify your key or read your balance for a moment, or temporarily running out of capacity. Nothing was charged. When Retry-After is present (often 30), wait that long; otherwise retry with backoff.

UPSTREAM_ERROR

503. The platform did not answer, even after our own retries. Nothing was charged. Retry-After is 5.

Parameter errors

400, or another 4xx. A required parameter is missing, a value is in the wrong format, or the endpoint does not accept a parameter you sent. The message says what was rejected and usually names the parameter to fix. Check the endpoint's parameters on its API reference page or in GET /v1/endpoints. Nothing is charged.

Idempotency

Send an Idempotency-Key header, a fresh UUID per logical operation, to make any call safe to retry after a timeout or a dropped connection.

  • A retry with the same key returns the original result with idempotent_replay: true, charge_reason: "replay" and credits_used: 0.
  • A retry that arrives while the original is still running gets 409 IDEMPOTENCY_IN_PROGRESS. Wait for Retry-After and try again with the same key.
  • Keys are scoped to your account.
  • A key longer than 255 characters, or with characters other than letters, digits, ., _, : and -, is ignored. The call then runs normally, with no replay protection.
  • If we never answered the original successfully (for example your client disconnected before it finished), the retry that delivers the data is charged as a normal call (charge_reason: "miss") at exactly the ceiling the call reserved: the listed price, or the top of the range for a metered endpoint, multiplied by max_pages if you sent it. Like any charged call, it can be covered by one of your free calls. It costs 0 if you already own that exact call or if the replay returns nothing.

What is never charged

Every error on this page costs 0 credits. So do empty results, dry_run=1 calls and replays of a call we already answered. API credits are non-refundable, and a call that fails is simply never charged. See Credits.

Retry loops

Each loop retries only the transient statuses (409, 429, 500, 503), honors Retry-After when it is sent, otherwise backs off exponentially with jitter, and stops after five retries.

cURL
#!/usr/bin/env bash
url="https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame"
max_retries=5
attempt=0

while :; do
  body=$(mktemp); headers=$(mktemp)
  status=$(curl -s -o "$body" -D "$headers" -w '%{http_code}' \
    -H "x-api-key: $INSIGHTSOCIAL_API_KEY" "$url")

  if [ "$status" -lt 400 ]; then
    cat "$body"; rm -f "$body" "$headers"; break
  fi

  case "$status" in
    409|429|500|503) ;;
    *) echo "Not retryable: $status"; cat "$body"; rm -f "$body" "$headers"; exit 1 ;;
  esac

  attempt=$((attempt + 1))
  if [ "$attempt" -gt "$max_retries" ]; then
    echo "Giving up after $max_retries retries (last status $status)"
    rm -f "$body" "$headers"; exit 1
  fi

  wait_s=$(grep -i '^retry-after:' "$headers" | tr -d '\r' | awk '{print $2}')
  if [ -z "$wait_s" ]; then
    wait_s=$(awk "BEGIN{srand(); print (2 ^ $attempt) * (0.5 + rand() / 2)}")
  fi
  rm -f "$body" "$headers"
  sleep "$wait_s"
done

Debugging tips

  • Log request_id (also sent as X-Request-Id) with every failure, so support can trace the exact call.
  • A 503 on an input that worked before is usually temporary. Retry after Retry-After.
  • Some calls take a while to answer. Set a client timeout of a minute or more on heavy endpoints rather than aborting early.

Next steps

On this page