Instagram posts & reels
Instagram post and reel metadata is available in sample mode. Live requests are disabled in production pending source authorization and review.
Request
POST /api/v1/posts · authenticate with the x-api-key header.
The reference GET /v1/instagram/post?url=... path is also available for public metadata. region and download_media=true return an unsupported-option error; permanent media downloads are not provided.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | One of url / shortcode | https://www.instagram.com/reel/<code>/, /p/<code>/, /reels/<code>/ or /tv/<code>/. |
shortcode | string | One of url / shortcode | The case-sensitive code from the URL, e.g. DePBA0SxalZ. |
mode | string | No | "live" for real data, "demo" for a free labeled sample. Default "demo". |
freshness | string | No | Oldest cached result you accept: "1h", "24h" (default), "7d", or "live" to force a refresh. |
curl "$SIGNALSHELF_BASE_URL/api/v1/posts" \
-H "Content-Type: application/json" \
-H "x-api-key: $SIGNALSHELF_API_KEY" \
--data '{"url":"https://www.instagram.com/reel/Demo001/","mode":"demo"}'const response = await fetch(`${process.env.SIGNALSHELF_BASE_URL}/api/v1/posts`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.SIGNALSHELF_API_KEY },
body: JSON.stringify({ url: 'https://www.instagram.com/reel/Demo001/', mode: 'demo' }),
});
const { data, meta } = await response.json();import os, requests
response = requests.post(
f"{os.environ['SIGNALSHELF_BASE_URL']}/api/v1/posts",
headers={"x-api-key": os.environ["SIGNALSHELF_API_KEY"]},
json={"url": "https://www.instagram.com/reel/Demo001/", "mode": "demo"},
timeout=30,
)
post = response.json()["data"]Example response
Labeled sample fixture. Values are illustrative and do not describe a real creator.
{
"data": {
"platform": "instagram",
"type": "reel",
"shortcode": "Demo001",
"url": "https://www.instagram.com/reel/Demo001/",
"caption": "Illustrative sample reel for exploring SignalShelf. #sample",
"hashtags": [
"sample"
],
"mentions": [],
"taken_at": "2026-10-01T09:30:00.000Z",
"likes": 4210,
"comments": 87,
"views": null,
"duration_seconds": 21.4,
"owner": {
"username": "samplecreator",
"name": "Sample creator"
},
"sample": true,
"provider": "sample-fixture"
},
"meta": {
"event_id": "sample",
"mode": "demo",
"cache": "SAMPLE",
"credits_charged": 0,
"fetched_at": null,
"age_seconds": null,
"duration_ms": 0
}
}Fields
| Field | Type | Description |
|---|---|---|
type | string | reel, video, image or carousel. |
shortcode | string | Case-sensitive post code. |
id | string | Media ID. |
url | string | Canonical post URL. |
caption | string | null | Full caption text. |
hashtags | array | Hashtags from the caption, lowercase, without #. |
mentions | array | @mentions from the caption. |
taken_at | string | Publish time (ISO 8601). |
likes | number | null | Like count; null when the creator hid it. |
comments | number | Comment count. |
views | null | Instagram does not show view counts to logged-out visitors. |
duration_seconds | number | null | Video length. |
width / height | number | Original dimensions. |
has_audio | boolean | Video has audio. |
thumbnail | string | Cover image URL. |
video_url | string | null | MP4 URL. Signed by Instagram and expires after a few days; download promptly. |
carousel | array | Carousel items { type, url }. |
location | object | null | Tagged location { name, id, lat, lng }. |
music | object | null | Track { title, artist, id }, or the original audio. |
owner | object | Author { id, username, name, avatar }. |
coauthors | array | Collaborator usernames. |
like_counts_hidden | boolean | Creator hid like counts. |
caption_edited | boolean | Caption was edited. |
Latency
Measured on 19–20 Oct 2026 through the API: fresh lookups median 1.2s (p95 1.5s); cached lookups median 1ms (p95 3ms). Browser fallback is limited to eligible parsing gaps or transient failures; access denials and rate limits stop without another request.
Errors
Every failure is free.
| Field | Type | Description |
|---|---|---|
400 INVALID_POST | error | Not an Instagram post/reel URL or shortcode. |
404 PROFILE_NOT_FOUND | error | The post does not exist or was removed. |
503 SOURCE_AUTH_REQUIRED | error | Instagram gated this post (age-restricted or private). Retry later. |
Limitations
Stories and posts from private accounts are not available.
View and play counts are not public to logged-out visitors, so views is null.