Errors
The IGramAPI error format and every error code you can receive, with the HTTP status, what it means and how to handle it in your code.
Every error uses the same JSON structure, so one handler covers every endpoint.
{
"error": {
"code": "profile_not_found",
"message": "User @example was not found on Instagram.",
"request_id": "req_8c2f9d4e1a7b3c50"
}
}
codeis stable. Branch on it in your code.messageis for humans and may change.request_ididentifies the request. Quote it if you contact support. It is also returned in theX-Request-IDheader.detailsis present on some errors, for examplequota_exceeded.
Failed requests are never charged.
Error codes
Authentication and plan
| Status | Code | What to do |
|---|---|---|
| 401 | missing_api_key |
Send the key in the Authorization header. |
| 401 | invalid_api_key |
Check the key, or create a new one. |
| 402 | quota_exceeded |
Credits are used up. Wait for resets_at or upgrade. |
| 403 | plan_upgrade_required |
This endpoint needs a paid plan. |
| 429 | rate_limit_exceeded |
Wait Retry-After seconds and retry. |
Your request
| Status | Code | What to do |
|---|---|---|
| 400 | invalid_username |
Send a username such as example_creator, with or without @. |
| 400 | invalid_target |
The URL or shortcode could not be understood. |
| 400 | missing_parameter |
A required parameter is missing, for example url or shortcode. |
| 400 | empty_query / empty_hashtag |
Send a non-empty value. |
| 400 | invalid_media_url |
Downloads accept Instagram media links only. |
| 400 | media_url_expired |
The link has expired. Fetch fresh data and use the new URL. |
| 400 | media_too_large |
The file exceeds the download size limit. |
| 422 | validation_error |
A parameter has the wrong type or range. details.fields lists each one. |
The data
| Status | Code | What to do |
|---|---|---|
| 404 | profile_not_found |
The username does not exist. |
| 404 | media_unavailable |
The post was deleted, is private or is blocked in a region. |
| 404 | audio_not_found |
The audio track was not found. |
| 404 | hashtag_not_found |
No public posts were found for the hashtag. |
| 404 | story_not_found |
The requested story has expired or does not exist. |
| 403 | private_account |
The account is private. |
| 403 | login_required |
Instagram only shows this post to signed-in users (for example age-restricted posts). |
Service
| Status | Code | What to do |
|---|---|---|
| 502 | upstream_error |
Instagram could not be reached or did not answer. Retry after a short pause. |
| 503 | service_unavailable |
Temporary problem on our side. Retry with a delay. |
| 500 | internal_error |
Unexpected error. Retry once, then contact support with the request_id. |
A resilient client
async function call(url, key) {
for (let attempt = 0; attempt < 3; attempt++) {
const response = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
if (response.ok) return response.json();
const { error } = await response.json();
const retryable = [429, 502, 503].includes(response.status);
if (!retryable || attempt === 2) throw Object.assign(new Error(error.message), error);
const wait = Number(response.headers.get("Retry-After")) || 2 ** attempt;
await new Promise((resolve) => setTimeout(resolve, wait * 1000));
}
}
Something unclear or missing? Tell us and we will fix the page.