Instagram API documentationمستندات Instagram API
IGAPI is a REST API for public Instagram data — profiles, post feeds, single media, stories and highlights. It runs on a managed, multi-account session pool that handles authentication, rate limiting and session rotation, so you only ever make simple HTTP requests. IGAPI یک REST API برای دادهٔ عمومی اینستاگرام است — پروفایل، فید پستها، مدیا، استوری و هایلایت. روی یک استخر چندحسابی اجرا میشود که احراز هویت، محدودیت نرخ و چرخش نشستها را خودش مدیریت میکند؛ شما فقط درخواست ساده HTTP میفرستید.
Every response is JSON. Send your key in the X-API-Key header; its plan sets how many requests it may make per minute, day and month.هر پاسخ JSON است. کلید خود را در هدر X-API-Key بفرستید؛ پلن کلید تعیین میکند در هر دقیقه، روز و ماه چند درخواست مجاز است.
Authenticationاحراز هویت
Send your API key in the X-API-Key request header on every call — not in the URL, the query string or the body. The server reads the key only from that header, and a key in a URL ends up in access logs, browser history and proxies. Keys start with igapi_.کلید API را در هر درخواست در هدر X-API-Key بفرستید — نه در آدرس، نه در query string و نه در بدنهٔ درخواست. سرور کلید را فقط از همین هدر میخواند و کلیدی که در آدرس باشد در لاگها، تاریخچهٔ مرورگر و پروکسیها میماند. کلیدها با igapi_ شروع میشوند.
X-API-Key: igapi_your_key_here
Getting a keyگرفتن کلید
Pick a plan on the pricing page (the same plans are listed under Plans & limits). Its button opens a chat with us that names the plan, and the key is issued in that chat — for example a free trial key to try the API, while a free plan is offered. A plan change keeps the same key. Buying a key on the site itself is planned for a later version. Keep the key secret: whoever has it spends your plan. If it leaks, ask us to revoke it and issue a new one.یک پلن را در صفحهٔ قیمتها انتخاب کنید (همان پلنها در بخش پلنها و محدودیتها هم آمدهاند). دکمهٔ آن گفتوگویی با ما باز میکند که نام پلن در آن هست، و کلید در همان گفتوگو صادر میشود — مثلاً یک کلید رایگان trial برای امتحان API، تا وقتی پلن رایگان ارائه میشود. با تغییر پلن، کلید همان میماند. خرید کلید در خود سایت برای یک نسخهٔ بعدی برنامهریزی شده است. کلید را محرمانه نگه دارید: هر کس آن را داشته باشد از پلن شما مصرف میکند. اگر لو رفت، از ما بخواهید آن را باطل کنیم و کلید تازه بدهیم.
Examplesنمونهها
A profile lookup in four languages: the key in the header, then the two response headers worth reading — X-API-Key-Status and, on 429 / 503, Retry-After (seconds). Call the API from your server, not from a web page on another site: it sends no CORS headers unless we have allowed that site, and a key inside browser code is public. A first lookup of a profile visits it on Instagram and can take several seconds, so allow a generous timeout (60–90 s).گرفتن یک پروفایل در چهار زبان: کلید در هدر، و دو هدر پاسخ که ارزش خواندن دارند — X-API-Key-Status و در پاسخهای 429 / 503، هدر Retry-After (ثانیه). API را از سرور خودتان صدا بزنید، نه از صفحهٔ وب یک سایت دیگر: API هدر CORS نمیفرستد مگر ما آن سایت را مجاز کرده باشیم، و کلیدی که در کد مرورگر باشد عمومی است. اولین درخواستِ یک پروفایل آن را در اینستاگرام باز میکند و ممکن است چند ثانیه طول بکشد، پس timeout را بلند بگیرید (۶۰ تا ۹۰ ثانیه).
# -i also prints the response headers: X-API-Key-Status, and Retry-After on a 429 / 503 curl -i https://igapi.online/api/userinfo/nasa \ -H "X-API-Key: igapi_your_key_here"
<?php require 'vendor/autoload.php'; // composer require guzzlehttp/guzzle $client = new GuzzleHttp\Client([ 'base_uri' => 'https://igapi.online/api/', 'headers' => ['X-API-Key' => 'igapi_your_key_here'], 'http_errors' => false, // read the JSON of 4xx / 5xx answers yourself 'timeout' => 90, ]); $res = $client->get('userinfo/nasa'); $data = json_decode((string) $res->getBody(), true); if ($res->getHeaderLine('X-API-Key-Status') === 'invalid') { // the key is unknown or revoked: check it or ask for a new one } if (in_array($res->getStatusCode(), [429, 503], true)) { $wait = (int) ($res->getHeaderLine('Retry-After') ?: 30); // seconds // sleep($wait) and send the same request again }
// Node 18+ (server side) const res = await fetch("https://igapi.online/api/userinfo/nasa", { headers: { "X-API-Key": "igapi_your_key_here" }, signal: AbortSignal.timeout(90_000), }); if (res.headers.get("X-API-Key-Status") === "invalid") { // the key is unknown or revoked: check it or ask for a new one } if (res.status === 429 || res.status === 503) { const wait = Number(res.headers.get("Retry-After") || 30); // seconds // wait, then send the same request again } const data = await res.json();
import time import requests r = requests.get("https://igapi.online/api/userinfo/nasa", headers={"X-API-Key": "igapi_your_key_here"}, timeout=90) if r.headers.get("X-API-Key-Status") == "invalid": print("key not recognised: check it or ask for a new one") if r.status_code in (429, 503): time.sleep(int(r.headers.get("Retry-After", "30"))) # then send it again data = r.json()
Without a key, or with a key the server does not knowبدون کلید، یا با کلیدی که سرور نمیشناسد
When a request sends X-API-Key, the answers of the data endpoints and of /api/health carry an X-API-Key-Status header: ok, or invalid when the key is unknown or revoked — every answer, also an input error (400) or the maintenance answer (503). An unrecognised key is handled by this server's rule for requests without a key (below): served, limited, or refused with 401 api_key_invalid. When a per-IP limit stops such a request, the 429 message says the X-API-Key you sent is not recognised on this server and the body adds "apiKeyStatus": "invalid". To check a key without spending a request, call GET /api/health with the header: its JSON then includes "apiKey": "ok" or "invalid".وقتی درخواست هدر X-API-Key دارد، پاسخ سرویسهای داده و /api/health هدر X-API-Key-Status را هم دارد: ok، یا invalid وقتی کلید ناشناخته یا باطلشده است — در همهی پاسخها، حتی خطای ورودی (400) یا پاسخ حالت تعمیر (503). با کلیدِ ناشناخته طبق قاعدهٔ این سرور برای درخواستِ بدون کلید رفتار میشود (پایین): انجام میشود، محدود میشود یا با 401 api_key_invalid رد میشود. اگر سقفِ هر IP چنین درخواستی را متوقف کند، پیام 429 میگوید کلیدِ ارسالی روی این سرور شناخته نشد و بدنه فیلد "apiKeyStatus": "invalid" را هم دارد. برای بررسی کلید بدون مصرف درخواست، GET /api/health را با همین هدر صدا بزنید: JSON پاسخ فیلد "apiKey": "ok" یا "invalid" را هم دارد.
curl https://igapi.online/api/health -H "X-API-Key: igapi_your_key_here" X-API-Key-Status: ok { "status": "ok", "active_sessions": 14, "total_sessions": 16, "uptime": 86400, "version": "2.1.1", "apiKey": "ok" }
Right now this server also answers requests without a key, or with an unknown or revoked one: they count against no plan, and only per-IP limits can apply to them.در حال حاضر این سرور به درخواستِ بدون کلید، یا با کلید ناشناخته یا باطلشده، هم پاسخ میدهد: از هیچ پلنی کم نمیشود و فقط سقفهای هر IP ممکن است رویش اعمال شود.
A malformed username or link is answered 400 first, under every setting. A 401 from the data endpoints, /api/proxy-image or /api/download only ever means a missing or unrecognised key (api_key_required, api_key_invalid); apart from that, 401 comes only from the admin console's own endpoints. A 403 from a data endpoint always means a private profile. Requests with a valid key count against that key's plan; other requests never count against a key.نام کاربری یا لینکِ نادرست، در هر تنظیمی، اول پاسخ 400 میگیرد. 401 از سرویسهای داده، /api/proxy-image یا /api/download همیشه یعنی کلید نیست یا شناخته نشد (api_key_required، api_key_invalid)؛ جز این، 401 فقط از سرویسهای خودِ کنسول مدیریت میآید. 403 از یک سرویس داده همیشه یعنی پیج خصوصی. درخواستِ با کلید معتبر از پلن همان کلید کم میکند؛ درخواستهای دیگر هرگز از کلیدی کم نمیکنند.
Base URLآدرس پایه
All endpoints are relative to this base URL, under the /api prefix.همهٔ سرویسها نسبت به این آدرس پایه و زیر پیشوند /api هستند.
https://igapi.online/api
Domain change. The service moved to https://igapi.online. The old address https://igapi.igapi.online still answers every /api/* request exactly as before (same keys, same responses, no redirect), so existing integrations keep working; only its web pages now open on the new address. Switch your base URL when convenient. The old address will be retired only after every customer has moved, and with at least 30 days' notice.تغییر دامنه. سرویس به https://igapi.online منتقل شد. آدرس قدیم https://igapi.igapi.online همچنان به همهٔ درخواستهای /api/* دقیقاً مثل قبل پاسخ میدهد (همان کلیدها، همان پاسخها، بدون redirect)، پس اتصالهای فعلی کار میکنند؛ فقط صفحههای وب آن حالا روی آدرس جدید باز میشوند. هر وقت برایتان راحت بود آدرس پایه را عوض کنید. آدرس قدیم فقط وقتی کنار گذاشته میشود که همهٔ مشتریها منتقل شده باشند، و دستکم ۳۰ روز پیش از آن اعلام میشود.
Plans & rate limitsپلنها و محدودیتها
Every plan reaches the same endpoints. A plan can cap a key's requests per minute, per day and per month; the windows are UTC (the minute, the day from 00:00 UTC, the calendar month) and the counters survive server restarts. Only the six data endpoints (userinfo, feed, media, stories, highlights, highlight) count; /api/download, /api/proxy-image and /api/health never use up a plan. A request refused with 429 is not counted, nor one the input checks refuse before Instagram is asked (400 for a malformed username, post link, highlight id or max_id). A request answered 503 no_sessions (no Instagram account of the server was free) is given back to the key. The table lists the plans offered today; they can change.همهٔ پلنها به یک مجموعه سرویس دسترسی دارند. پلن میتواند درخواستهای یک کلید را در هر دقیقه، هر روز و هر ماه محدود کند؛ بازهها به وقت UTC هستند (دقیقه، روز از ساعت ۰۰:۰۰ UTC، ماه تقویمی) و شمارندهها با ریاستارت سرور صفر نمیشوند. فقط شش سرویس داده (userinfo، feed، media، stories، highlights، highlight) شمرده میشوند؛ /api/download، /api/proxy-image و /api/health از سهمیه کم نمیکنند. درخواستی که با 429 رد شود شمرده نمیشود، و نه درخواستی که بررسی ورودی پیش از پرسیدن از اینستاگرام ردش کند (400 برای یوزرنیم، لینک پست، شناسهی هایلایت یا max_id نادرست). درخواستی که پاسخ 503 no_sessions بگیرد (هیچ اکانت اینستاگرامِ سرور آزاد نبود) به سهمیهٔ کلید برگردانده میشود. جدول، پلنهایی است که همین سرور الان ارائه میدهد؛ ممکن است تغییر کنند.
| Planپلن | Per minuteدر دقیقه | Per dayدر روز | Per monthدر ماه | Priceقیمت |
|---|---|---|---|---|
| Free | 10 | 50 | — | Freeرایگان |
| Pro | 50 | — | 50,000 | 26.99 USD / month/ ماه |
| Mega | 300 | — | 1,000,000 | 199.99 USD / month/ ماه |
| Ultra | 50 | — | 200,000 | 59.99 USD / month/ ماه |
— = no cap in that window. Prices, what each plan includes and how to buy: Pricing.— یعنی در آن بازه سقفی نیست. قیمتها، آنچه هر پلن دارد و روش خرید: قیمتها.
When a plan limit is reachedوقتی به سقف پلن برسید
The data endpoints answer 429 with a Retry-After header (seconds) until the window resets. window says which cap was hit (minute, day or month); when several are full, the longest one is reported, so waiting retryAfterMs is always enough.سرویسهای داده تا پایان بازه 429 با هدر Retry-After (ثانیه) برمیگردانند. window میگوید کدام سقف پر شده (minute، day یا month)؛ اگر چند سقف پر باشد طولانیترینش گزارش میشود، پس صبر به اندازهٔ retryAfterMs همیشه کافی است.
{
"error": "plan_limit_exceeded",
"plan": "trial",
"window": "day",
"limit": 50,
"current": 50,
"retryAfterMs": 22226666,
"resetAt": "2026-11-01T00:00:00.000Z",
"message": "This API key's plan \"Trial\" allows 50 requests per day (UTC), …"
}
Requests without a keyدرخواست بدون کلید
Requests without a valid key (no key, or an unknown or revoked one) follow this server's rule, stated under Authentication: served with per-IP limits only (none on the data endpoints by default), given the trial plan's limits per IP address (the plan named Trial on the pricing page), or refused with 401. Past a limit you get 429 with a Retry-After header (seconds) and a JSON body that also gives the wait in milliseconds; under the trial plan's limits the body also names the window, resetAt and "plan": "trial".درخواستهای بدون کلیدِ معتبر (بدون کلید، یا با کلید ناشناخته یا باطلشده) از قاعدهٔ این سرور پیروی میکنند که در بخش احراز هویت آمده: فقط با سقفهای هر IP انجام میشوند (روی سرویسهای داده بهطور پیشفرض بیسقف)، سقفهای پلن trial را برای هر نشانی IP میگیرند (پلنی که در صفحهٔ قیمتها Trial نام دارد)، یا با 401 رد میشوند. بیش از سقف، پاسخ 429 با هدر Retry-After (ثانیه) و یک بدنهٔ JSON برمیگردد که زمان انتظار را برحسب میلیثانیه هم میگوید؛ با سقفهای پلن trial بدنه window، resetAt و "plan": "trial" را هم دارد.
{
"error": "rate_limit_exceeded",
"message": "Too many requests without an API key: …",
"limit": 20,
"current": 20,
"retryAfterMs": 38400
}
Errorsخطاها
Errors use standard HTTP status codes. The six data endpoints always answer JSON with an error code and a message for people, plus extra fields for some codes; branch on error, never on the message text. /api/proxy-image and /api/download answer {"error": "<short text>"}. Errors of the Instagram CDN itself are passed through by /api/proxy-image with their status and an empty body; /api/download answers them as Link expired (CDN 403 / 404 / 410, same status) or Proxy error (any other CDN status, 502), both with upstreamStatus, so a 429 from it is always the server's own limit.خطاها از کدهای وضعیت استاندارد HTTP استفاده میکنند. شش سرویس داده همیشه JSON برمیگردانند: کد error و یک message برای انسان، و برای بعضی کدها فیلدهای بیشتر؛ تصمیم را بر اساس error بگیرید، نه متن پیام. /api/proxy-image و /api/download پاسخ {"error": "<متن کوتاه>"} میدهند. خطاهای خودِ CDN اینستاگرام را /api/proxy-image با همان کد و بدنهٔ خالی عبور میدهد (passed through)؛ /api/download آنها را بهصورت Link expired (CDN با 403 / 404 / 410، همان کد) یا Proxy error (هر کد دیگر CDN، 502) برمیگرداند، هر دو با upstreamStatus؛ پس 429 از آن همیشه محدودیت خودِ سرور است.
{
"error": "not_found",
"message": "User not found: ghost.user.123"
}
Retry policyسیاست تکرار درخواست
- 400, 403, 404, 413, 415 — the request itself is the problem: fix it; sending it again unchanged gives the same answer.400، 403، 404، 413، 415 — مشکل از خودِ درخواست است: اصلاحش کنید؛ تکرارِ بدون تغییر همان جواب را میگیرد.
- 429 and 503 — wait for
Retry-After(seconds; the body repeats it asretryAfterMs), then send the same request again. When there is noRetry-After(no_sessions), use exponential backoff starting at 30 s. A request refused with429does not count against your plan, and one answered503no_sessionsis given back.429 و 503 — به اندازهٔRetry-After(ثانیه؛ بدنه همان را بهصورتretryAfterMsهم دارد) صبر کنید و همان درخواست را دوباره بفرستید. وقتیRetry-Afterنیست (no_sessions)، با backoff نمایی از ۳۰ ثانیه شروع کنید. درخواستی که429بگیرد از پلن شما کم نمیکند و درخواستی که503no_sessionsبگیرد برگردانده میشود. - 500 and 502 — retry with exponential backoff (for example 2 s, 4 s, 8 s) and give up after three tries.500 و 502 — با backoff نمایی (مثلاً ۲، ۴، ۸ ثانیه) دوباره بفرستید و بعد از سه بار رها کنید.
| Status | error | Endpointsسرویسها | What to doچه کنید |
|---|---|---|---|
| 400 | invalid_username | userinfo, feed, stories, highlights | Fix the usernameنام کاربری را اصلاح کنید |
| 400 | invalid_input | feed, media, highlight | Fix the parameterپارامتر را اصلاح کنید |
| 400 | bad_request, invalid_json | allهمه | Fix the URL encoding; send no bodyکدگذاری آدرس را اصلاح کنید؛ بدنه نفرستید |
| 400 | Invalid URL | proxy-image, download | Pass an https Instagram CDN URLیک آدرس https از CDN اینستاگرام بدهید |
| 401 | api_key_required, api_key_invalid | data endpoints, proxy-image, downloadسرویسهای داده، proxy-image، download | Only when this server requires a key (see Authentication): send a valid X-API-Keyفقط وقتی این سرور کلید را لازم کرده (بخش احراز هویت): یک X-API-Key معتبر بفرستید |
| 403 | private_account | feed, stories, highlights, userinfo (media, highlight) | Do not retry: the profile is privateتکرار نکنید: پیج خصوصی است |
| 404 | not_found | allهمه | Check the username / link / idنام کاربری / لینک / شناسه را بررسی کنید |
| 403 404 410 | Link expired | download | Fetch the post again for a fresh URLپست را دوباره بگیرید تا لینک تازه بگیرید |
| 413 | Image too large, File too large, payload_too_large | proxy-image, download | Use a smaller renditionنسخهٔ کوچکتر را بگیرید |
| 415 | Not an image, Not an image or video | proxy-image, download | Pass a media URLآدرس خودِ مدیا را بدهید |
| 429 | plan_limit_exceeded | userinfo, feed, media, stories, highlights, highlight | Wait Retry-After or move to a bigger planبه اندازهٔ Retry-After صبر کنید یا پلن بزرگتر بگیرید |
| 429 | rate_limit_exceeded | all, without a valid keyهمه، بدون کلید معتبر | Wait Retry-After or send a valid keyصبر کنید یا کلید معتبر بفرستید |
| 429 | rate_limited | userinfo, feed, media, stories, highlights, highlight | Wait Retry-After (60 s)۶۰ ثانیه صبر کنید |
| 500 | server_error | allهمه | Retry with backoffبا backoff تکرار کنید |
| 502 | upstream_failed | stories | Retry with backoffبا backoff تکرار کنید |
| 502 | Proxy error | proxy-image, download | Retry once, then fetch a fresh URLیک بار تکرار، بعد لینک تازه بگیرید |
| 503 | session_unavailable | userinfo, feed, media, stories, highlights, highlight | Wait Retry-After (30–60 s), retryبه اندازهٔ Retry-After صبر و تکرار کنید |
| 503 | no_sessions | userinfo, feed, media, stories, highlights, highlight | Retry later with backoffبعداً با backoff تکرار کنید |
| 503 | site_busy | this site's lookup tools onlyفقط ابزارهای جستوجوی همین سایت | Wait Retry-After, retryبه اندازهٔ Retry-After صبر و تکرار کنید |
| 503 | busy | proxy-image, download | Wait Retry-After (2 s), retry۲ ثانیه صبر و تکرار کنید |
| 503 | maintenance | all data endpoints, proxy-image, downloadهمهٔ سرویسهای داده، proxy-image، download | Wait Retry-After (300 s), retry۳۰۰ ثانیه صبر و تکرار کنید |
Every error, with an exampleهمهٔ خطاها، با نمونه
invalid_usernameuserinfo · feed · stories · highlightsThe :username is not a plain Instagram username: only letters, digits, . and _, at most 30 characters — no @, no link.:username یک نام کاربری سادهٔ اینستاگرام نیست: فقط حروف، عدد، . و _، حداکثر ۳۰ نویسه — بدون @ و بدون لینک.
What to do: strip the @ or take the name out of the profile link; do not retry the same value.@ را بردارید یا نام را از لینک پروفایل جدا کنید؛ همان مقدار را تکرار نکنید.
{ "error": "invalid_username", "message": "Invalid username. Please enter a plain Instagram username (e.g. instagram), not a URL or link." }
invalid_inputfeed · media · highlightA parameter is missing or malformed: /api/media without url / shortcode / id or with a link that holds no post id; a highlight id that is not 5–25 digits; a max_id with characters a cursor never has. Also sent when Instagram itself rejects the input.پارامتری غایب یا نامعتبر است: /api/media بدون url / shortcode / id یا با لینکی که شناسهٔ پست ندارد؛ شناسهٔ هایلایتی که ۵ تا ۲۵ رقم نیست؛ max_id با نویسههایی که یک cursor ندارد. وقتی خود اینستاگرام ورودی را رد کند هم همین میآید.
What to do: fix the parameter (pass nextMaxId exactly as you got it); do not retry unchanged.پارامتر را اصلاح کنید (nextMaxId را دقیقاً همانطور که گرفتید بفرستید)؛ بدون تغییر تکرار نکنید.
{ "error": "invalid_input", "message": "Provide a post ?url= (or ?id= / ?shortcode=)" }
bad_requestallThe URL could not be decoded, for example a broken percent-escape in the path.آدرس قابل decode نیست، مثلاً یک percent-escape ناقص در مسیر.
What to do: URL-encode path and query values once (encodeURIComponent, urlencode).مقدارهای مسیر و query را یک بار URL-encode کنید.
{ "error": "bad_request", "message": "Failed to decode param '%E0%A4%A'" }
invalid_jsonallThe request had a JSON body that could not be parsed. Every public endpoint is GET and needs no body.درخواست یک بدنهٔ JSON خراب داشت. همهٔ سرویسهای عمومی GET هستند و بدنه لازم ندارند.
What to do: send no body and no Content-Type: application/json.بدنه و هدر Content-Type: application/json نفرستید.
{ "error": "invalid_json", "message": "Request body is not valid JSON" }
payload_too_largeallA request body over 1 MB. As above, the public endpoints take no body.بدنهٔ درخواست بیش از ۱ مگابایت. مثل بالا، سرویسهای عمومی بدنه نمیگیرند.
What to do: send no body.بدنه نفرستید.
{ "error": "payload_too_large", "message": "Request body is too large" }
api_key_requireddata endpoints · proxy-image · downloadSent only when this server requires a key (see Authentication) and the request has no X-API-Key header. The answer carries WWW-Authenticate: ApiKey realm="IGAPI" and is never cached.فقط وقتی فرستاده میشود که این سرور کلید را لازم کرده (بخش احراز هویت) و درخواست هدر X-API-Key ندارد. پاسخ هدر WWW-Authenticate: ApiKey realm="IGAPI" دارد و هرگز کش نمیشود.
What to do: send your key in the X-API-Key header; how to get one: Getting a key.کلیدتان را در هدر X-API-Key بفرستید؛ گرفتن کلید: گرفتن کلید.
{
"error": "api_key_required",
"message": "This API needs a key: send it in the X-API-Key header. How to get one: https://igapi.online/pricing",
"apiKeyStatus": "missing",
"docs": "https://igapi.online/docs#auth"
}
api_key_invaliddata endpoints · proxy-image · downloadSent only when this server requires a key and the X-API-Key you sent is unknown or revoked; the answer also has the header X-API-Key-Status: invalid. Under the other settings such a key is handled like a request without a key.فقط وقتی فرستاده میشود که این سرور کلید را لازم کرده و X-API-Key ارسالی ناشناخته یا باطلشده است؛ پاسخ هدر X-API-Key-Status: invalid را هم دارد. در تنظیمهای دیگر با چنین کلیدی مثل درخواستِ بدون کلید رفتار میشود.
What to do: check the key (GET /api/health with it shows "apiKey": "invalid" without spending a request), or ask us for a new one.کلید را بررسی کنید (GET /api/health با همان کلید بدون مصرف درخواست "apiKey": "invalid" نشان میدهد) یا از ما کلید تازه بخواهید.
{
"error": "api_key_invalid",
"message": "The X-API-Key you sent is not recognised on this server (unknown or revoked). Check the key or ask for a new one: https://igapi.online/pricing",
"apiKeyStatus": "invalid",
"docs": "https://igapi.online/docs#auth"
}
private_accountfeed · stories · highlights · userinfo · media · highlightThe profile is private. /api/feed always refuses a private profile; stories and highlights are refused unless one of the server's accounts follows it; /api/media and /api/highlight/:id refuse only when strict privacy is turned on. user (when present) has the public part of the profile, so you can still show a card.پیج خصوصی است. /api/feed همیشه پیج خصوصی را رد میکند؛ استوری و هایلایت رد میشوند مگر یکی از اکانتهای سرور آن را فالو کند؛ /api/media و /api/highlight/:id فقط وقتی حالت سختگیرانه روشن باشد. user (اگر باشد) بخش عمومی پروفایل را دارد تا هنوز بتوانید کارت پروفایل را نشان دهید.
What to do: do not retry; show that the account is private.تکرار نکنید؛ نشان دهید که اکانت خصوصی است.
{
"error": "private_account",
"message": "This account is private",
"isPrivate": true,
"user": { "pk": "1440211", "username": "some.private.user", "fullName": "Some User", "isPrivate": true, "profilePic": "https://scontent.cdninstagram.com/v/t51.2885-19/p.jpg" }
}
not_foundallNo such user, post or highlight on Instagram — or no such endpoint on this server (No such endpoint: GET /api/…).چنین کاربر، پست یا هایلایتی در اینستاگرام نیست — یا چنین سرویسی روی این سرور نیست (No such endpoint: GET /api/…).
What to do: check the spelling or the link; a renamed account answers 404 under its old name.املای نام یا لینک را بررسی کنید؛ اکانتی که نامش عوض شده با نام قدیم 404 میدهد.
{ "error": "not_found", "message": "User not found: ghost.user.123" }
plan_limit_exceededuserinfo · feed · media · stories · highlights · highlightYour key used up its plan in one window (window: minute, day or month, UTC). resetAt is when that window ends; Retry-After / retryAfterMs is how long to wait.کلید شما سهمیهٔ پلنش را در یک بازه مصرف کرده (window: minute، day یا month، به وقت UTC). resetAt زمان پایان آن بازه است و Retry-After / retryAfterMs مدت انتظار.
What to do: wait until resetAt (retrying earlier is refused again but not counted), or ask us for a bigger plan.تا resetAt صبر کنید (تکرار زودتر دوباره رد میشود ولی شمرده نمیشود)، یا از ما پلن بزرگتر بخواهید.
{
"error": "plan_limit_exceeded",
"plan": "starter",
"window": "minute",
"limit": 30,
"current": 30,
"retryAfterMs": 21000,
"resetAt": "2026-11-01T09:15:00.000Z",
"message": "This API key's plan \"Starter\" allows 30 requests per minute, and this key has used 30. Try again in 21 s (resets at 2026-11-01T09:15:00.000Z), or ask for a bigger plan."
}
rate_limit_exceededall, without a valid keyToo many requests from your IP without a valid key. The data endpoints have this limit only when it is turned on; /api/download allows 30 and /api/proxy-image 600 keyless requests a minute by default, each a separate budget. "apiKeyStatus": "invalid" means you did send a key but the server does not know it (unknown or revoked). When this server gives requests without a key the trial plan's limits, the body also has window (minute or day), resetAt and "plan": "trial".درخواستِ بدون کلیدِ معتبرِ زیاد از IP شما. سرویسهای داده این سقف را فقط وقتی دارند که روشن شده باشد؛ /api/download بهطور پیشفرض ۳۰ و /api/proxy-image ۶۰۰ درخواست بدون کلید در دقیقه، هر کدام سهمیهٔ جدا. "apiKeyStatus": "invalid" یعنی کلید فرستادهاید ولی سرور آن را نمیشناسد (ناشناخته یا باطلشده). وقتی این سرور به درخواستهای بدون کلید سقفهای پلن trial را میدهد، بدنه window (minute یا day)، resetAt و "plan": "trial" را هم دارد.
What to do: wait Retry-After, or send a valid X-API-Key (a valid key lifts this limit).به اندازهٔ Retry-After صبر کنید یا یک X-API-Key معتبر بفرستید (کلید معتبر این سقف را برمیدارد).
{
"error": "rate_limit_exceeded",
"message": "Too many requests: the X-API-Key you sent is not recognised on this server (unknown or revoked), so this request was treated as one without a key — at most 60 per minute per IP. Check the key or ask for a new one.",
"limit": 60,
"current": 60,
"retryAfterMs": 38400,
"apiKeyStatus": "invalid"
}
rate_limiteduserinfo · feed · media · stories · highlights · highlightInstagram is rate-limiting the account that served the request — not your key. Retry-After: 60.اینستاگرام اکانتی را که درخواست را انجام داد محدود کرده — نه کلید شما را. Retry-After: 60.
What to do: wait a minute and retry; another account usually serves it.یک دقیقه صبر کنید و دوباره بفرستید؛ معمولاً اکانت دیگری جواب میدهد.
{ "error": "rate_limited", "message": "Instagram is rate-limiting the service — retry in a minute.", "retryAfterMs": 60000 }
server_errorallThe request failed on the server or on the way to Instagram (an error it could not classify).درخواست روی سرور یا در مسیر اینستاگرام شکست خورد (خطایی که دستهبندی نشد).
What to do: retry with exponential backoff, at most three times; tell us if it persists.با backoff نمایی، حداکثر سه بار، دوباره بفرستید؛ اگر ادامه داشت به ما بگویید.
{ "error": "server_error", "message": "The request failed on the server — please retry." }
upstream_failedstoriesThe profile was read but Instagram's story request failed — an empty list would wrongly mean "no stories".پروفایل خوانده شد ولی درخواست استوری اینستاگرام شکست خورد — لیست خالی به اشتباه یعنی «استوری ندارد».
What to do: retry with backoff.با backoff دوباره بفرستید.
{ "error": "upstream_failed", "message": "Stories unavailable right now, retry" }
no_sessionsuserinfo · feed · media · stories · highlights · highlightNo Instagram account of the server is available right now (all challenged, disabled or at their own limit). There is no Retry-After; GET /api/health shows "status": "no_sessions" while this lasts. It costs your key nothing: the request is given back to its plan.فعلاً هیچ اکانت اینستاگرامی از سرور در دسترس نیست (همه challenge خورده، غیرفعال یا به سقف خودشان رسیدهاند). Retry-After ندارد؛ تا وقتی این وضع هست، GET /api/health مقدار "status": "no_sessions" را نشان میدهد. از کلید شما چیزی کم نمیشود: درخواست به پلن آن برگردانده میشود.
What to do: retry later with exponential backoff (30 s, 60 s, 120 s …).بعداً با backoff نمایی (۳۰، ۶۰، ۱۲۰ ثانیه …) دوباره بفرستید.
{ "error": "no_sessions", "message": "No active sessions available" }
site_busythis site's lookup tools onlyOnly the lookup tools on this website get this answer — never a request from your own code. It means all visitors of the tools together reached the per-minute limit this server sets for them (only when requests without a key are limited or need a key). Retry-After gives the wait in seconds.فقط ابزارهای جستوجوی همین سایت این پاسخ را میگیرند — هرگز درخواستی از کد خودتان. یعنی همهٔ بازدیدکنندگان ابزارها رویهم به سقف دقیقهای که این سرور برایشان گذاشته رسیدهاند (فقط وقتی درخواستِ بدون کلید محدود است یا کلید لازم دارد). Retry-After زمان انتظار را برحسب ثانیه میگوید.
What to do: wait Retry-After and try again.به اندازهٔ Retry-After صبر کنید و دوباره امتحان کنید.
{ "error": "site_busy", "message": "The lookup tools are busy right now. Try again in a moment.", "retryAfterMs": 12000 }
Image proxy and downloadپروکسی تصویر و دانلود
Invalid URLproxy-image · downloadNo url, not https, not an Instagram CDN host (*.cdninstagram.com, *.fbcdn.net), or (download) a port or user name in it.url نیست، https نیست، میزبانش CDN اینستاگرام (*.cdninstagram.com، *.fbcdn.net) نیست، یا (در دانلود) پورت یا نام کاربری دارد.
What to do: pass a media URL from one of the data endpoints, URL-encoded.آدرس مدیایی را که یکی از سرویسهای داده داده، URL-encode شده بفرستید.
{ "error": "Invalid URL" }
Image too largeproxy-imageThe image is over 8 MB.تصویر بیش از ۸ مگابایت است.
What to do: use a smaller candidate from images, or /api/download.نسخهٔ کوچکتری از images را بگیرید، یا /api/download.
{ "error": "Image too large" }
File too largedownloadThe file is bigger than the server's download cap (500 MB by default). A file without a declared size that grows past it is cut off mid-stream instead.فایل از سقف دانلود سرور (پیشفرض ۵۰۰ مگابایت) بزرگتر است. فایلی که حجمش اعلام نشده و از سقف بگذرد، وسط کار قطع میشود.
What to do: pick a lower-resolution entry from videos.نسخهٔ با کیفیت پایینتر را از videos بگیرید.
{ "error": "File too large" }
Not an imageproxy-imageThe URL answered something that is not an image (for example a video).آدرس چیزی جز تصویر برگرداند (مثلاً ویدیو).
What to do: use thumbnailUrl for pictures and /api/download for videos.برای تصویر thumbnailUrl و برای ویدیو /api/download را استفاده کنید.
{ "error": "Not an image" }
Not an image or videodownloadThe URL answered neither an image nor a video.آدرس نه تصویر برگرداند نه ویدیو.
What to do: pass a mediaUrl / images / videos URL.یک آدرس mediaUrl / images / videos بدهید.
{ "error": "Not an image or video" }
Proxy errorproxy-image · downloadThe CDN did not answer in time (15 s for the headers) or the connection failed. /api/proxy-image passes other CDN errors (403, 404, 410 …) through with the CDN's status and an empty body — CDN links expire after a while. /api/download also answers 502 Proxy error when the CDN itself answered an error other than 403 / 404 / 410 (for example its own 429 or a 5xx); then the body has upstreamStatus and a message, and there is no Retry-After.CDN بهموقع جواب نداد (۱۵ ثانیه برای هدرها) یا اتصال قطع شد. /api/proxy-image خطاهای دیگر CDN (403، 404، 410 …) را با همان کد CDN و بدنهٔ خالی عبور میدهد — لینکهای CDN بعد از مدتی منقضی میشوند. /api/download وقتی خودِ CDN خطایی غیر از 403 / 404 / 410 داده باشد (مثلاً 429 خودش یا 5xx) هم 502 Proxy error میدهد؛ آنوقت بدنه upstreamStatus و message دارد و Retry-After ندارد.
What to do: retry once; for 403 / 404 / 410 fetch the post again to get a fresh URL.یک بار تکرار کنید؛ برای 403 / 404 / 410 پست را دوباره بگیرید تا لینک تازه بگیرید.
{ "error": "Proxy error" }
{ "error": "Proxy error", "upstreamStatus": 429, "message": "The Instagram CDN answered 429. Retry once; if it fails again, fetch the post again for a fresh URL." }
Link expireddownloadThe Instagram CDN refused the file URL (403), no longer has it (404) or says it is gone (410). The status is the CDN's own; upstreamStatus repeats it. CDN URLs are signed and expire after a while, so this usually means the URL came from an older response. It is never the server's limit and never about your key.CDN اینستاگرام آدرس فایل را رد کرد (403)، دیگر آن را ندارد (404) یا میگوید حذف شده (410). کد همان کدِ خودِ CDN است و upstreamStatus آن را تکرار میکند. آدرسهای CDN امضاشدهاند و بعد از مدتی منقضی میشوند؛ پس معمولاً یعنی آدرس از پاسخی قدیمی آمده. هیچوقت محدودیت سرور یا مشکل کلید شما نیست.
What to do: do not retry the same URL: fetch the post, story or highlight again and download its fresh URL.همان آدرس را تکرار نکنید: پست، استوری یا هایلایت را دوباره بگیرید و آدرس تازهاش را دانلود کنید.
{ "error": "Link expired", "upstreamStatus": 403, "message": "The Instagram CDN answered 403: this link has expired or the file is gone. Fetch the post again for a fresh URL." }
busyproxy-image · downloadToo many image or download requests in progress on the whole server; yours waited up to 10 s for a free slot. Retry-After: 2.درخواست تصویر یا دانلودِ در جریان در کل سرور زیاد است؛ درخواست شما تا ۱۰ ثانیه برای جای خالی صبر کرد. Retry-After: 2.
What to do: wait 2 s and retry; load fewer images at once.۲ ثانیه صبر و تکرار کنید؛ تصویرهای کمتری را همزمان بگیرید.
{ "error": "busy", "message": "Too many image requests in progress on this server — retry in a moment.", "retryAfterMs": 2000 }
maintenanceuserinfo · feed · media · stories · highlights · highlight · proxy-image · downloadThe API is in maintenance mode; message is our note. Retry-After: 300. GET /api/health then carries "maintenance": true, so a client can poll it for free instead of the data endpoints. Requests with a valid key may be let through during maintenance.API در حالت تعمیر است؛ message یادداشت ماست. Retry-After: 300. در این حالت GET /api/health فیلد "maintenance": true دارد، پس کلاینت میتواند بهجای سرویسهای داده آن را (رایگان) بپرسد. ممکن است درخواستهای با کلید معتبر در حالت تعمیر آزاد باشند.
What to do: back off — retry after Retry-After, or poll /api/health until maintenance is gone.عقب بکشید — بعد از Retry-After دوباره بفرستید، یا /api/health را بپرسید تا maintenance برداشته شود.
{ "error": "maintenance", "message": "The API is down for maintenance. Please try again in a few minutes.", "retryAfterMs": 300000 }
Endpointsسرویسها
All endpoints are GET. The six data endpoints (userinfo, feed, media, stories, highlights, highlight) read Instagram through the server's account pool; requests with a valid key count against its plan, requests without one against the per-IP limit when one is set. /api/proxy-image and /api/download only relay files from Instagram's CDN and never use up a plan. Field names are stable; new fields may be added, so ignore the ones you do not know. URLs of Instagram's CDN in a response expire after a while — fetch the data again for fresh ones.همهٔ سرویسها GET هستند. شش سرویس داده (userinfo، feed، media، stories، highlights، highlight) از طریق استخر اکانتهای سرور از اینستاگرام میخوانند؛ درخواستِ با کلید معتبر از پلن آن کم میشود و درخواستِ بدون کلید، اگر سقفی گذاشته شده باشد، از محدودیتِ هر IP. /api/proxy-image و /api/download فقط فایل را از CDN اینستاگرام رد میکنند و از هیچ پلنی کم نمیکنند. نام فیلدها ثابت است ولی ممکن است فیلد تازه اضافه شود؛ فیلدهایی را که نمیشناسید نادیده بگیرید. آدرسهای CDN اینستاگرام در پاسخها بعد از مدتی منقضی میشوند — برای آدرس تازه دوباره درخواست بدهید.
Full public profile: counts, bio, verification and contact fields. A repeat lookup of the same profile within 3 minutes is answered from the server's cache. posts_viewable and stories_viewable say whether /api/feed and /api/stories / /api/highlights will serve this profile: the feed never serves a private profile; stories and highlights of a private profile are served when the server's account that looked it up follows it (unless that is turned off). The server keeps using that account for this profile's lookups while it is available, so the flag stays true after the 3-minute cache; if that account is out of service, /api/stories may still answer 403 private_account.پروفایل عمومی کامل: شمارشها، بیو، تأیید و اطلاعات تماس. درخواست دوباره برای همان پروفایل تا ۳ دقیقه از حافظهٔ سرور جواب داده میشود. posts_viewable و stories_viewable میگویند /api/feed و /api/stories / /api/highlights این پروفایل را سرویس میدهند یا نه: فید هیچوقت پیج خصوصی را نمیدهد؛ استوری و هایلایت پیج خصوصی وقتی داده میشود که اکانتِ سرور که آن را دیده دنبالش کند (مگر این خاموش شده باشد). سرور تا وقتی آن اکانت در دسترس است برای این پروفایل همان را به کار میبرد، پس فیلد بعد از ۳ دقیقهٔ حافظه هم درست میماند؛ اگر آن اکانت از کار افتاده باشد /api/stories ممکن است باز ۴۰۳ private_account بدهد.
| Param | In | Descriptionتوضیح |
|---|---|---|
| username * | path | Instagram username, without the @.نام کاربری اینستاگرام، بدون @. |
{
"pk": "25025320",
"username": "instagram",
"full_name": "Instagram",
"biography": "Discover what's new on Instagram",
"follower_count": 672000000,
"following_count": 160,
"posts": 694,
"reels": 310,
"is_verified": true,
"is_private": false,
"is_business": true,
"category": "Product/service",
"external_url": "https://about.instagram.com",
"public_email": "",
"public_phone": "",
"city": "",
"profile_pic": "https://scontent.cdninstagram.com/v/t51.2885-19/instagram_s150.jpg",
"hd_profile_pic": "https://scontent.cdninstagram.com/v/t51.2885-19/instagram_hd.jpg",
"has_stories": true,
"has_highlights": true,
"is_threads_active": true,
"is_whatsapp_linked": false,
"posts_viewable": true,
"stories_viewable": true
}
Paginated posts (about 12 a page). Pass the previous response's nextMaxId as max_id to page forward; hasMore: false is the last page. A private profile answers 403 private_account.پستهای صفحهبندیشده (حدود ۱۲ تا در هر صفحه). nextMaxId پاسخ قبلی را بهعنوان max_id بفرستید تا صفحهٔ بعد را بگیرید؛ hasMore: false صفحهٔ آخر است. پیج خصوصی پاسخ 403 private_account میگیرد.
| Param | In | Descriptionتوضیح |
|---|---|---|
| username * | path | Target username.نام کاربری هدف. |
| max_id | query | Pagination cursor from a prior response.مکاننمای صفحهبندی از پاسخ قبلی. |
| Post fieldفیلد پست | Descriptionتوضیح |
|---|---|
| type | image | video | carousel | unknown |
| mediaUrl / thumbnailUrl | The best image, or for a video the best video file and its cover image; for a carousel both are the first item's image.بهترین تصویر، یا برای ویدیو بهترین فایل ویدیو و تصویر کاورش؛ برای کاروسل هر دو تصویر آیتم اول است. |
| images / videos | Every rendition, largest first (videos, viewCount, videoDuration, hasAudio only on videos).همهٔ نسخهها، بزرگترین اول (videos، viewCount، videoDuration، hasAudio فقط برای ویدیو). |
| carouselItems | Carousel only: [{ type, mediaUrl, thumbnailUrl, width, height, images, videos? }].فقط کاروسل: [{ type, mediaUrl, thumbnailUrl, width, height, images, videos? }]. |
| timestamp | Unix seconds.ثانیهٔ Unix. |
{
"user": { "pk": "528817151", "username": "nasa", "fullName": "NASA", "profilePic": "https://scontent.cdninstagram.com/v/t51.2885-19/nasa_s150.jpg", "hdProfilePic": "https://scontent.cdninstagram.com/v/t51.2885-19/nasa_hd.jpg", "isPrivate": false, "isVerified": true },
"posts": [
{
"id": "3480000000000000001_528817151", "pk": "3480000000000000001", "shortcode": "DBx1AbCdEfG",
"type": "image", "timestamp": 1730000000, "caption": "Saturn's rings, up close.",
"likeCount": 120044, "commentCount": 812, "width": 1080, "height": 1350,
"mediaUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/post_1080.jpg",
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/post_1080.jpg",
"images": [ { "url": "https://scontent.cdninstagram.com/v/t51.2885-15/post_1080.jpg", "width": 1080, "height": 1350 } ]
},
{
"id": "3479000000000000002_528817151", "pk": "3479000000000000002", "shortcode": "DBw2HiJkLmN",
"type": "video", "timestamp": 1729900000, "caption": "Launch day.",
"likeCount": 98000, "commentCount": 640, "width": 720, "height": 1280,
"mediaUrl": "https://scontent.cdninstagram.com/o1/v/t16/clip_720.mp4",
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/clip_cover.jpg",
"images": [ { "url": "https://scontent.cdninstagram.com/v/t51.2885-15/clip_cover.jpg", "width": 720, "height": 1280 } ],
"videos": [ { "url": "https://scontent.cdninstagram.com/o1/v/t16/clip_720.mp4", "width": 720, "height": 1280, "type": 101 } ],
"viewCount": 2500000, "videoDuration": 31.4, "hasAudio": true
}
],
"pagination": { "hasMore": true, "nextMaxId": "3479000000000000002_528817151", "count": 12 }
}
Resolve a single post or reel. Provide one of url, shortcode or id. The answer has the same fields as a feed post, plus kind, mediaId, repostCount, audio and the author in user.یک پست یا ریل را resolve میکند. یکی از url، shortcode یا id را بدهید. پاسخ همان فیلدهای پست فید را دارد، بهعلاوهٔ kind، mediaId، repostCount، audio و نویسنده در user.
| Param | In | Descriptionتوضیح |
|---|---|---|
| url | query | Full post / reel URL (/p/, /reel/, /tv/), URL-encoded.آدرس کامل پست / ریل (/p/، /reel/، /tv/)، URL-encode شده. |
| shortcode | query | The post shortcode.شورتکد پست. |
| id | query | The numeric media id.شناسهٔ عددی مدیا. |
| Fieldفیلد | Descriptionتوضیح |
|---|---|
| kind | image | video | reel | carousel (a reel is a video with type: "video")(ریل یک ویدیو با type: "video" است) |
| type | image | video | carousel | unknown |
| viewCount | Videos and reels; null otherwise.ویدیو و ریل؛ در بقیه null. |
| audio | Videos only: { url, source: "music" | "original" | "dash", title, artist, durationSec, coverUrl } or null.فقط ویدیو: { url, source: "music" | "original" | "dash", title, artist, durationSec, coverUrl } یا null. |
{
"id": "3479000000000000002_528817151", "pk": "3479000000000000002", "shortcode": "DBw2HiJkLmN",
"type": "video", "kind": "reel", "mediaId": "3479000000000000002",
"timestamp": 1729900000, "caption": "Launch day.",
"likeCount": 98000, "commentCount": 640, "viewCount": 2500000, "repostCount": 120,
"width": 720, "height": 1280, "videoDuration": 31.4, "hasAudio": true,
"mediaUrl": "https://scontent.cdninstagram.com/o1/v/t16/clip_720.mp4",
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/clip_cover.jpg",
"images": [ { "url": "https://scontent.cdninstagram.com/v/t51.2885-15/clip_cover.jpg", "width": 720, "height": 1280 } ],
"videos": [ { "url": "https://scontent.cdninstagram.com/o1/v/t16/clip_720.mp4", "width": 720, "height": 1280, "type": 101 } ],
"audio": { "url": "https://scontent.cdninstagram.com/o1/v/t2/audio.m4a", "source": "original", "title": "Original audio", "artist": "nasa", "durationSec": 31, "coverUrl": null },
"user": { "pk": "528817151", "username": "nasa", "fullName": "NASA", "isVerified": true, "isPrivate": false, "profilePicUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/nasa_s150.jpg" }
}
Currently active stories for a public account (an empty items means none right now). type is image or video; timestamp and expiresAt are Unix seconds; duration (seconds) only on videos.استوریهای فعال فعلی یک حساب عمومی (items خالی یعنی الان استوری ندارد). type برابر image یا video است؛ timestamp و expiresAt ثانیهٔ Unix؛ duration (ثانیه) فقط برای ویدیو.
| Param | In | Descriptionتوضیح |
|---|---|---|
| username * | path | Target username.نام کاربری هدف. |
{
"user": { "pk": "528817151", "username": "nasa", "fullName": "NASA", "isPrivate": false, "profilePic": "https://scontent.cdninstagram.com/v/t51.2885-19/nasa_s150.jpg" },
"items": [
{ "id": "3480500000000000101", "type": "image", "timestamp": 1730000000, "expiresAt": 1730086400,
"mediaUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/story_1.jpg", "thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/story_1.jpg",
"width": 1080, "height": 1920, "duration": null },
{ "id": "3480500000000000102", "type": "video", "timestamp": 1730003600, "expiresAt": 1730090000,
"mediaUrl": "https://scontent.cdninstagram.com/o1/v/t16/story_2.mp4", "thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/story_2.jpg",
"width": 720, "height": 1280, "duration": 15 }
]
}
The highlight trays shown on a profile. Open one with /api/highlight/:id, passing the same username.سینیهای هایلایت نمایشدادهشده روی پروفایل. هر کدام را با /api/highlight/:id و همان username باز کنید.
| Param | In | Descriptionتوضیح |
|---|---|---|
| username * | path | Target username.نام کاربری هدف. |
{
"user": { "pk": "528817151", "username": "nasa", "fullName": "NASA", "isPrivate": false, "profilePic": "https://scontent.cdninstagram.com/v/t51.2885-19/nasa_s150.jpg" },
"items": [
{ "id": "17890000000000001", "title": "Moon", "coverUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/moon_cover.jpg", "mediaCount": 12 }
]
}
The items inside one highlight tray — the same item fields as a story.آیتمهای داخل یک سینی هایلایت — همان فیلدهای آیتم استوری.
| Param | In | Descriptionتوضیح |
|---|---|---|
| id * | path | Highlight id (5–25 digits), with or without the highlight: prefix.شناسهٔ هایلایت (۵ تا ۲۵ رقم)، با یا بدون پیشوند highlight:. |
| username | query | Owner username (recommended: the request then continues on the account that just opened that profile).نام کاربری صاحب (توصیهشده: درخواست روی همان اکانتی ادامه پیدا میکند که تازه آن پروفایل را باز کرده). |
{
"id": "17890000000000001",
"title": "Moon",
"user": { "pk": "528817151", "username": "nasa" },
"items": [
{ "id": "3100000000000000201", "type": "image", "timestamp": 1690000000, "expiresAt": null,
"mediaUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/moon_1.jpg", "thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.2885-15/moon_1.jpg",
"width": 1080, "height": 1920, "duration": null }
]
}
Show an Instagram picture from your own origin: <img src="/api/proxy-image?url=…">. Instagram's CDN often refuses images embedded on other sites; this endpoint fetches the image and returns its bytes with its own Content-Type (image/* only) and Cache-Control: public, max-age=86400. Only https://*.cdninstagram.com and https://*.fbcdn.net URLs are accepted, redirects are not followed, the CDN must answer within 15 s and the image may be at most 8 MB. Recent images are kept in the server's memory for 30 minutes. It does not use an Instagram account and never counts against a plan. Without a valid key: 600 requests a minute per IP (this can change); at most 48 run at once on the whole server.نمایش تصویر اینستاگرام از دامنهٔ خودتان: <img src="/api/proxy-image?url=…">. CDN اینستاگرام اغلب تصویری را که در سایت دیگری گذاشته شده رد میکند؛ این سرویس تصویر را میگیرد و بایتهایش را با Content-Type خودش (فقط image/*) و Cache-Control: public, max-age=86400 برمیگرداند. فقط آدرسهای https://*.cdninstagram.com و https://*.fbcdn.net پذیرفته میشوند، redirect دنبال نمیشود، CDN باید تا ۱۵ ثانیه جواب دهد و تصویر حداکثر ۸ مگابایت (8 MB) است. تصویرهای اخیر ۳۰ دقیقه در حافظهٔ سرور میمانند. از اکانت اینستاگرام استفاده نمیکند و از هیچ پلنی کم نمیکند. بدون کلید معتبر: ۶۰۰ درخواست در دقیقه برای هر IP (قابل تغییر)؛ در کل سرور حداکثر ۴۸ درخواست همزمان.
| Param | In | Descriptionتوضیح |
|---|---|---|
| url * | query | An image URL from another endpoint's response (thumbnailUrl, profile_pic, coverUrl …), URL-encoded.آدرس تصویری از پاسخ سرویسهای دیگر (thumbnailUrl، profile_pic، coverUrl …)، URL-encode شده. |
<img src="https://igapi.online/api/proxy-image?url=https%3A%2F%2Fscontent.cdninstagram.com%2Fv%2Ft51.2885-15%2Fpost_1080.jpg" alt=""> HTTP/1.1 200 OK Content-Type: image/jpeg Cache-Control: public, max-age=86400
| Status | Meaningمعنی |
|---|---|
| 400 | Invalid URL — missing, not https, or not an Instagram CDN host.آدرس نیست، https نیست، یا میزبانش CDN اینستاگرام نیست. |
| 413 | Image too large — over 8 MB.بیش از ۸ مگابایت. |
| 415 | Not an image — the URL does not serve an image.آدرس تصویر برنمیگرداند. |
| 429 | rate_limit_exceeded — per-IP limit without a valid key; wait for Retry-After.سقف هر IP بدون کلید معتبر؛ به اندازهٔ Retry-After صبر کنید. |
| 502 | Proxy error — the CDN did not answer; other CDN errors (403, 404 …) are passed through with an empty body.CDN جواب نداد؛ خطاهای دیگر CDN (403، 404 …) با بدنهٔ خالی عبور داده میشوند. |
| 503 | busy — too many image requests at once on the server; Retry-After: 2.درخواست تصویر همزمان در سرور زیاد است؛ Retry-After: 2. |
Save a photo or video. Pass a media URL from another endpoint's response (for example a post's image or video URL); the file is streamed back as an attachment, so a browser saves it instead of opening it. Only Instagram CDN URLs (https://*.cdninstagram.com, https://*.fbcdn.net) are accepted. It does not use an Instagram account, so it does not count against your key's quota. Without a valid key a transfer is cut off after 30 minutes (the connection closes and the file is incomplete); with a key there is no time limit.ذخیرهٔ یک عکس یا ویدیو. آدرس مدیایی را که در پاسخ سرویسهای دیگر آمده (مثلاً آدرس عکس یا ویدیوی یک پست) بدهید؛ فایل بهصورت پیوست (attachment) برمیگردد تا مرورگر آن را ذخیره کند، نه اینکه باز کند. فقط آدرسهای CDN اینستاگرام (https://*.cdninstagram.com و https://*.fbcdn.net) پذیرفته میشوند. این سرویس از اکانت اینستاگرام استفاده نمیکند و از سهمیهٔ کلید شما کم نمیشود. بدون کلید معتبر، انتقال بعد از ۳۰ دقیقه قطع میشود (اتصال بسته میشود و فایل ناقص میماند)؛ با کلید محدودیت زمانی نیست.
| Param | In | Descriptionتوضیح |
|---|---|---|
| url * | query | The image or video URL, URL-encoded.آدرس عکس یا ویدیو، URL-encode شده. |
| name | query | Suggested file name. Only letters, digits, ., _ and - are kept (at most 80 characters) and the right extension is added; non-English letters are kept in the filename* form. Default: the file name in the URL.نام پیشنهادی فایل. فقط حروف، اعداد، .، _ و - میمانند (حداکثر ۸۰ نویسه) و پسوند درست اضافه میشود؛ حروف غیرانگلیسی در شکل filename* حفظ میشوند. پیشفرض: نام فایل در خودِ آدرس. |
curl -OJ "https://igapi.online/api/download?url=https%3A%2F%2Fscontent.cdninstagram.com%2F...%2Fclip.mp4&name=nasa_reel"
HTTP/1.1 200 OK
Content-Type: video/mp4
Content-Length: 4718302
Content-Disposition: attachment; filename="nasa_reel.mp4"
| Status | Meaningمعنی |
|---|---|
| 400 | Invalid URL — missing, not https, or not an Instagram CDN host.آدرس نیست، https نیست، یا میزبانش CDN اینستاگرام نیست. |
| 413 | File too large — bigger than the server's download cap (500 MB by default).بزرگتر از سقف دانلود سرور (پیشفرض ۵۰۰ مگابایت). |
| 415 | Not an image or video — the URL does not serve an image or a video.آدرس، عکس یا ویدیو برنمیگرداند. |
| 429 | rate_limit_exceeded — without a valid key, either 30 downloads per minute per IP (a separate budget from the data endpoints), or more than 4 downloads open at once from one IP (Retry-After: 5; the message says "at once"). Wait for Retry-After or for a download to finish. A valid X-API-Key lifts both.بدون کلید معتبر، یا ۳۰ دانلود در دقیقه برای هر IP (جدا از سهمیهٔ سرویسهای داده)، یا بیش از ۴ دانلود باز همزمان از یک IP (Retry-After: 5؛ پیامش «at once» دارد). به اندازهٔ Retry-After یا تا تمام شدن یک دانلود صبر کنید. کلید معتبر در X-API-Key هر دو را برمیدارد. |
| 403 404 410 | Link expired — the CDN answered this status: the URL has expired or the file is gone; fetch the post again for a fresh one. The body is JSON with upstreamStatus.CDN همین کد را داد: آدرس منقضی شده یا فایل دیگر نیست؛ پست را دوباره بگیرید تا آدرس تازه بگیرید. بدنه JSON با upstreamStatus است. |
| 502 | Proxy error — the CDN did not answer in time, or answered another error (its own 429, a 5xx …; then with upstreamStatus). Retry once, then fetch a fresh URL. A CDN error is never passed through as-is, so a 429 here is always the server's own limit.CDN بهموقع پاسخ نداد یا خطای دیگری داد (429 خودش، 5xx و …؛ آنوقت با upstreamStatus). یک بار تکرار کنید، بعد آدرس تازه بگیرید. خطای CDN هیچوقت همانطور عبور داده نمیشود، پس 429 در این endpoint همیشه محدودیت خود سرور است. |
| 503 | busy — too many downloads at once on the server (16 by default); wait for Retry-After (2 s).دانلود همزمان در سرور زیاد است (پیشفرض ۱۶)؛ به اندازهٔ Retry-After (۲ ثانیه) صبر کنید. |
Live playgroundمحیط آزمایش زنده
Send a real request to this deployment. Your key is used only for this call and never stored.یک درخواست واقعی به همین استقرار بفرستید. کلید فقط برای همین درخواست استفاده میشود و ذخیره نمیشود.