API reference
Every endpoint of the Instoryview Open API on one page, generated from the same contract the API is built on.
Version 1.0.0 · OpenAPI 3.1Raw JSON
Base URL and authentication
Base URL: https://instoryview.com/open-api/v1
Send your API Key in the Authorization header on every request:
GET /open-api/v1/tracking
Authorization: Bearer YOUR_API_KEYPersonal Instoryview API Key. OAuth tokens are bound to the MCP resource and are not accepted on these REST endpoints. data:read is required on every operation; online queries also require data:fetch.
Response format
Every response is JSON with two parts: data, described with each endpoint below, and meta. An error has an error object instead of data, with the same meta.
Fields of meta
| Name | Type | Description |
|---|---|---|
requestIdrequired | string | |
sourcerequired | string | One of: stored_profile, tracking_snapshot, tracking_history, public_cache, live. |
asOfrequired | date-time | null | |
creditsUsedrequired | integer | |
warningsrequired | string[] | Machine-readable notes, empty when there are none: partial_list (a list is not proven complete), cached_page_only (reusable public data holds one page), page_limit_reached (the online paging ceiling), list_unavailable (Instagram returned no members although the profile counts some; not an empty list), username_reused (another account has used this username; check the id), detected_changes_only and report coverage notes on changes. New codes can be added. |
coveragerequired | string | complete requires authoritative evidence; page end alone is insufficient. One of: partial, unknown, complete. |
hasMorerequired | boolean | |
nextCursorrequired | string | null |
Error response
{
"error": {
"code": "snapshot_unavailable",
"message": "No retained readable follower snapshot is available."
},
"meta": {
"requestId": "req_error_example",
"creditsUsed": 0
}
}List my tracked accounts
/ open-api/ v1/ trackingStored readsScopes:data:read
Defaults to active and paused accounts. Counts and snapshot timestamps are included per account. No fresh provider calls.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
includeArchived | query | boolean | Include readable removed tracking records. Default false. |
limit | query | integer | Items per stored read page. 1–100. Default 50. |
cursor | query | string | Opaque meta.nextCursor from the previous page of this same endpoint, account and credential. Valid for about one hour. At most 8192 characters. |
Response
Stored data. No new collection charge.
Fields of data
| Name | Type | Description |
|---|---|---|
itemsrequired | object[] | |
items[].idrequired | string | |
items[].usernamerequired | string | |
items[].fullNamerequired | string | null | |
items[].avatarUrlrequired | uri | null | Absolute signed link to the latest known profile picture, valid for about a day. Do not store it; read the account again for a fresh link. |
items[].isPrivaterequired | boolean | |
items[].isVerifiedrequired | boolean | |
items[].statusrequired | string | One of: active, paused, archived. |
items[].trackedListsrequired | string[] | |
items[].followerCountrequired | integer | null | |
items[].followingCountrequired | integer | null | |
items[].profileAsOfrequired | date-time | null | |
items[].listSnapshotsrequired | object | |
items[].listSnapshots.followersrequired | date-time | null | |
items[].listSnapshots.followingrequired | date-time | null |
{
"data": {
"items": [
{
"id": "123456789",
"username": "sample_creator",
"fullName": "Sample Creator",
"avatarUrl": null,
"isPrivate": false,
"isVerified": false,
"status": "active",
"trackedLists": [
"followers"
],
"followerCount": 1200,
"followingCount": 420,
"profileAsOf": "2026-10-11T08:00:00Z",
"listSnapshots": {
"followers": "2026-10-11T09:00:00Z",
"following": null
}
}
]
},
"meta": {
"requestId": "req_example",
"source": "tracking_history",
"asOf": null,
"creditsUsed": 0,
"warnings": [],
"coverage": "partial",
"hasMore": false,
"nextCursor": null
}
}Shared errors400401403404409410429500503
Read existing account profile and totals
/ open-api/ v1/ accounts/ {username}Stored readsScopes:data:read
Reads stored profile or permitted reusable public data. Unknown counts are null. Profile observation time may differ from list time.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
usernamerequired | path | string | Instagram username. Pagination remains bound to the resolved stable account ID. |
Response
Stored data. No new collection charge.
Fields of data
| Name | Type | Description |
|---|---|---|
idrequired | string | Stable Instagram account ID, always a string. |
usernamerequired | string | |
fullNamerequired | string | null | |
avatarUrlrequired | uri | null | Absolute signed link to the latest known profile picture, valid for about a day. Do not store it; read the account again for a fresh link. |
isPrivaterequired | boolean | null | |
isVerifiedrequired | boolean | null | |
followerCountrequired | integer | null | |
followingCountrequired | integer | null | |
trackedListsrequired | string[] |
{
"data": {
"id": "123456789",
"username": "sample_creator",
"fullName": "Sample Member",
"avatarUrl": null,
"isPrivate": false,
"isVerified": false,
"followerCount": 1200,
"followingCount": 420,
"trackedLists": [
"followers",
"following"
]
},
"meta": {
"requestId": "req_profile_example",
"source": "stored_profile",
"asOf": "2026-10-11T08:00:00Z",
"creditsUsed": 0,
"warnings": []
}
}Shared errors400401403404409410429500503
Read an available follower snapshot
/ open-api/ v1/ accounts/ {username}/ followersStored readsScopes:data:read
Selects the caller-readable last usable published follower snapshot. Paused or removed tracking reads only retained authorized-period data. Never-tracked accounts may read reusable public query data. No implicit fresh query.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
usernamerequired | path | string | Instagram username. Pagination remains bound to the resolved stable account ID. |
limit | query | integer | Items per stored read page. 1–100. Default 50. |
cursor | query | string | Opaque meta.nextCursor from the previous page of this same endpoint, account and credential. Valid for about one hour. At most 8192 characters. |
Response
Stored data. No new collection charge.
Fields of data
| Name | Type | Description |
|---|---|---|
accountIdrequired | string | |
usernamerequired | string | |
availableCountrequired | integer | null | Readable observed list size, not the profile total. null if unknown. |
returnedCountrequired | integer | |
itemsrequired | Person[] | |
items[].idrequired | string | Stable Instagram account ID, always a string. |
items[].usernamerequired | string | null | |
items[].fullNamerequired | string | null | |
items[].avatarUrlrequired | uri | null | Absolute signed link to the latest known profile picture, valid for about a day. Do not store it; read the account again for a fresh link. |
items[].isPrivaterequired | boolean | null | |
items[].isVerifiedrequired | boolean | null |
{
"data": {
"accountId": "123456789",
"username": "sample_creator",
"availableCount": 850,
"returnedCount": 1,
"items": [
{
"id": "234567890",
"username": "sample_member",
"fullName": "Sample Member",
"avatarUrl": null,
"isPrivate": false,
"isVerified": false
}
]
},
"meta": {
"requestId": "req_example",
"source": "tracking_snapshot",
"asOf": "2026-10-11T09:00:00Z",
"creditsUsed": 0,
"warnings": [
"partial_list"
],
"coverage": "partial",
"hasMore": false,
"nextCursor": null
}
}Shared errors400401403404409410429500503
Read an available following snapshot
/ open-api/ v1/ accounts/ {username}/ followingStored readsScopes:data:read
Same structure as followers; the following snapshot and entitlement are selected independently. Cursor must come from this endpoint and current caller.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
usernamerequired | path | string | Instagram username. Pagination remains bound to the resolved stable account ID. |
limit | query | integer | Items per stored read page. 1–100. Default 50. |
cursor | query | string | Opaque meta.nextCursor from the previous page of this same endpoint, account and credential. Valid for about one hour. At most 8192 characters. |
Response
Stored data. No new collection charge.
Fields of data
| Name | Type | Description |
|---|---|---|
accountIdrequired | string | |
usernamerequired | string | |
availableCountrequired | integer | null | Readable observed list size, not the profile total. null if unknown. |
returnedCountrequired | integer | |
itemsrequired | Person[] | |
items[].idrequired | string | Stable Instagram account ID, always a string. |
items[].usernamerequired | string | null | |
items[].fullNamerequired | string | null | |
items[].avatarUrlrequired | uri | null | Absolute signed link to the latest known profile picture, valid for about a day. Do not store it; read the account again for a fresh link. |
items[].isPrivaterequired | boolean | null | |
items[].isVerifiedrequired | boolean | null |
{
"data": {
"accountId": "123456789",
"username": "sample_creator",
"availableCount": 850,
"returnedCount": 1,
"items": [
{
"id": "234567890",
"username": "sample_member",
"fullName": "Sample Member",
"avatarUrl": null,
"isPrivate": false,
"isVerified": false
}
]
},
"meta": {
"requestId": "req_following_example",
"source": "tracking_snapshot",
"asOf": "2026-10-11T09:00:00Z",
"creditsUsed": 0,
"warnings": [
"partial_list"
],
"coverage": "partial",
"hasMore": false,
"nextCursor": null
}
}Shared errors400401403404409410429500503
Read detected tracking changes
/ open-api/ v1/ accounts/ {username}/ changesStored readsScopes:data:read
Reads only authorized confirmed changes. Summary covers the readable range; items is one page. Unknown values stay null. Detection time is not action time. The cursor fixes the observation context: for the next page send only cursor (and limit). An account you never tracked returns 403 list_not_authorized.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
usernamerequired | path | string | Instagram username. Pagination remains bound to the resolved stable account ID. |
list | query | string | Not needed with a cursor: the cursor keeps the list, dates and timezone. One of: followers, following. Default followers. |
from | query | date | Inclusive start date. Requires to. Defaults to the last seven calendar days; at most 366 days. |
to | query | date | Inclusive end date. Requires from. |
timezone | query | string | IANA timezone that defines the date window. Default UTC. |
limit | query | integer | Items per stored read page. 1–100. Default 50. |
cursor | query | string | Opaque meta.nextCursor from the previous page of this same endpoint, account and credential. Valid for about one hour. At most 8192 characters. |
Response
Stored data. No new collection charge.
Fields of data
| Name | Type | Description |
|---|---|---|
accountIdrequired | string | |
usernamerequired | string | |
listrequired | string | One of: followers, following. |
fromrequired | date | |
torequired | date | |
timezonerequired | string | |
summaryrequired | object | |
summary.addedrequired | integer | null | null when observations are insufficient. |
summary.removedrequired | integer | null | null when observations are insufficient. |
summary.netDiscoveredrequired | integer | null | null when observations are insufficient. |
summary.countNetChangerequired | integer | null | null when observations are insufficient. |
itemsrequired | object[] | |
items[].idrequired | string | |
items[].kindrequired | string | One of: new_follower, lost_follower, new_follow, unfollow. |
items[].detectedAtrequired | date-time | Detection time, not exact Instagram action time. |
items[].accountrequired | object | |
items[].account.idrequired | string | |
items[].account.usernamerequired | string | null |
{
"data": {
"accountId": "123456789",
"username": "sample_creator",
"list": "followers",
"from": "2026-10-01",
"to": "2026-10-07",
"timezone": "UTC",
"summary": {
"added": 12,
"removed": 3,
"netDiscovered": 9,
"countNetChange": 7
},
"items": [
{
"id": "event_example",
"kind": "new_follower",
"detectedAt": "2026-10-07T09:00:00Z",
"account": {
"id": "234567890",
"username": "sample_member"
}
}
]
},
"meta": {
"requestId": "req_example",
"source": "tracking_history",
"asOf": "2026-10-07T09:00:00Z",
"creditsUsed": 0,
"warnings": [
"detected_changes_only"
],
"coverage": "partial",
"hasMore": false,
"nextCursor": null
}
}Shared errors400401403404409410429500503
Query fresh public account data within a budget
/ open-api/ v1/ queriesOnline queriesScopes:data:readdata:fetch
Explicitly queries a public profile or one list page, including for an untracked account. One page is one source page: usually 25 people, about 50 for a verified account's follower list, which has no further pages. Requires both scopes and a positive maxCredits. Each source call costs 1 credit: a profile 1; a first list page 2 (it reads the profile first), so a first list page with maxCredits below 2 is refused before any call; a next page 1. At most 5 pages per list (page_limit_reached). No implicit tracking or full export. Each online next page is a new logical operation with a new idempotency key and cap. Failures may have confirmed source costs. Recovery preserves the original key and body.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
Idempotency-Keyrequired | header | string | Unique key for one logical paid query. Preserve for recovery. Same key with a different body conflicts. 8–200 characters. |
Request body
| Name | Type | Description |
|---|---|---|
usernamerequired | string | |
typerequired | string | One of: profile, followers, following. |
maxCreditsrequired | integer | 1–1000. |
cursor | string | Online cursor from POST /queries only; not permitted for profile. |
{
"username": "sample_creator",
"type": "profile",
"maxCredits": 2
}{
"username": "sample_creator",
"type": "followers",
"maxCredits": 2
}{
"username": "sample_creator",
"type": "following",
"maxCredits": 2
}{
"username": "sample_creator",
"type": "followers",
"cursor": "ONLINE_CURSOR",
"maxCredits": 2
}Response
Fresh profile or one list page. Idempotent replay returns the original total cost, without charging again.
Fields of data · Profile
| Name | Type | Description |
|---|---|---|
idrequired | string | Stable Instagram account ID, always a string. |
usernamerequired | string | |
fullNamerequired | string | null | |
avatarUrlrequired | uri | null | Absolute signed link to the latest known profile picture, valid for about a day. Do not store it; read the account again for a fresh link. |
isPrivaterequired | boolean | null | |
isVerifiedrequired | boolean | null | |
followerCountrequired | integer | null | |
followingCountrequired | integer | null | |
trackedListsrequired | string[] |
Fields of data · List page
| Name | Type | Description |
|---|---|---|
accountIdrequired | string | |
usernamerequired | string | |
availableCountrequired | integer | null | Readable observed list size, not the profile total. null if unknown. |
returnedCountrequired | integer | |
itemsrequired | Person[] | |
items[].idrequired | string | Stable Instagram account ID, always a string. |
items[].usernamerequired | string | null | |
items[].fullNamerequired | string | null | |
items[].avatarUrlrequired | uri | null | Absolute signed link to the latest known profile picture, valid for about a day. Do not store it; read the account again for a fresh link. |
items[].isPrivaterequired | boolean | null | |
items[].isVerifiedrequired | boolean | null |
{
"data": {
"accountId": "123456789",
"username": "sample_creator",
"availableCount": null,
"returnedCount": 1,
"items": [
{
"id": "234567890",
"username": "sample_member",
"fullName": "Sample Member",
"avatarUrl": null,
"isPrivate": false,
"isVerified": false
}
]
},
"meta": {
"requestId": "req_example",
"source": "live",
"asOf": "2026-10-11T09:00:00Z",
"creditsUsed": 2,
"warnings": [
"partial_list"
],
"coverage": "partial",
"hasMore": false,
"nextCursor": null
}
}Errors specific to this endpoint
| Status | Meaning |
|---|---|
| 402 | budget_exceeded or insufficient_credits: the request cannot fit its own cap (a first list page needs at least 2), the shared daily budget (0 until you set one in Developer settings) or the wallet balance. |
| 409 | idempotency_conflict, request_in_progress, query_outcome_unknown, account_changed or data_changed. Retry in-progress with the original key, at most 60 seconds automatically. Stop automatic retries on unknown outcome and keep the original key: within about 15 minutes the operation is settled (confirmed source calls are charged, calls that got no answer are not), and the same key then returns 503 query_interrupted. account_changed here means the username now belongs to another Instagram account than the one Instoryview knew; send the query again with a new key to read the current one. creditsUsed is null while the cost is not settled. |
| 410 | cursor_expired or result_expired. Expired results never authorize another collection with the old key. |
Shared errors400401403404429500503
Errors
Branch on error.code; error.message is written for people. Quote meta.requestId when you contact support.
| Status | Meaning |
|---|---|
| 400 | validation_failed: invalid username, filters or cursor. from/to must be supplied together. |
| 401 | unauthorized: credential missing, expired or revoked. |
| 403 | insufficient_scope, list_not_authorized or forbidden: current access does not authorize the resource. |
| 404 | snapshot_unavailable (no retained snapshot of this list), data_unavailable (no stored or reusable public data) or not_found (the account does not exist, is private, or was removed from Instoryview). Missing data is not an empty list. |
| 409 | account_changed (the username belongs to two accounts you track, or a cursor names another account) or data_changed (the data or your access changed while paging): read the first page again. |
| 410 | cursor_expired: the stored paging context is no longer available. |
| 429 | rate_limited: wait before retrying. |
| 500 | internal: request could not be completed. |
| 503 | upstream_unavailable: temporarily unavailable. Recover paid operations with their original idempotency key. On POST /queries also query_interrupted: the original operation stopped and was settled; only confirmed source calls were charged and it never runs again. |