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:

HTTP
GET /open-api/v1/tracking
Authorization: Bearer YOUR_API_KEY

Personal 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

NameTypeDescription
requestIdrequiredstring
sourcerequiredstringOne of: stored_profile, tracking_snapshot, tracking_history, public_cache, live.
asOfrequireddate-time | null
creditsUsedrequiredinteger
warningsrequiredstring[]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.
coveragerequiredstringcomplete requires authoritative evidence; page end alone is insufficient. One of: partial, unknown, complete.
hasMorerequiredboolean
nextCursorrequiredstring | null

Error response

JSON
{
  "error": {
    "code": "snapshot_unavailable",
    "message": "No retained readable follower snapshot is available."
  },
  "meta": {
    "requestId": "req_error_example",
    "creditsUsed": 0
  }
}

List my tracked accounts

GET/open-api/v1/tracking

Stored readsScopes:data:read

Defaults to active and paused accounts. Counts and snapshot timestamps are included per account. No fresh provider calls.

Parameters

NameInTypeDescription
includeArchivedquerybooleanInclude readable removed tracking records. Default false.
limitqueryintegerItems per stored read page. 1–100. Default 50.
cursorquerystringOpaque 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

NameTypeDescription
itemsrequiredobject[]
items[].idrequiredstring
items[].usernamerequiredstring
items[].fullNamerequiredstring | null
items[].avatarUrlrequireduri | nullAbsolute 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[].isPrivaterequiredboolean
items[].isVerifiedrequiredboolean
items[].statusrequiredstringOne of: active, paused, archived.
items[].trackedListsrequiredstring[]
items[].followerCountrequiredinteger | null
items[].followingCountrequiredinteger | null
items[].profileAsOfrequireddate-time | null
items[].listSnapshotsrequiredobject
items[].listSnapshots.followersrequireddate-time | null
items[].listSnapshots.followingrequireddate-time | null
Example · 200
{
  "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

GET/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

NameInTypeDescription
usernamerequiredpathstringInstagram username. Pagination remains bound to the resolved stable account ID.

Response

Stored data. No new collection charge.

Fields of data

NameTypeDescription
idrequiredstringStable Instagram account ID, always a string.
usernamerequiredstring
fullNamerequiredstring | null
avatarUrlrequireduri | nullAbsolute 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.
isPrivaterequiredboolean | null
isVerifiedrequiredboolean | null
followerCountrequiredinteger | null
followingCountrequiredinteger | null
trackedListsrequiredstring[]
Example · 200
{
  "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

GET/open-api/v1/accounts/{username}/followers

Stored 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

NameInTypeDescription
usernamerequiredpathstringInstagram username. Pagination remains bound to the resolved stable account ID.
limitqueryintegerItems per stored read page. 1–100. Default 50.
cursorquerystringOpaque 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

NameTypeDescription
accountIdrequiredstring
usernamerequiredstring
availableCountrequiredinteger | nullReadable observed list size, not the profile total. null if unknown.
returnedCountrequiredinteger
itemsrequiredPerson[]
items[].idrequiredstringStable Instagram account ID, always a string.
items[].usernamerequiredstring | null
items[].fullNamerequiredstring | null
items[].avatarUrlrequireduri | nullAbsolute 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[].isPrivaterequiredboolean | null
items[].isVerifiedrequiredboolean | null
Example · 200
{
  "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

GET/open-api/v1/accounts/{username}/following

Stored 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

NameInTypeDescription
usernamerequiredpathstringInstagram username. Pagination remains bound to the resolved stable account ID.
limitqueryintegerItems per stored read page. 1–100. Default 50.
cursorquerystringOpaque 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

NameTypeDescription
accountIdrequiredstring
usernamerequiredstring
availableCountrequiredinteger | nullReadable observed list size, not the profile total. null if unknown.
returnedCountrequiredinteger
itemsrequiredPerson[]
items[].idrequiredstringStable Instagram account ID, always a string.
items[].usernamerequiredstring | null
items[].fullNamerequiredstring | null
items[].avatarUrlrequireduri | nullAbsolute 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[].isPrivaterequiredboolean | null
items[].isVerifiedrequiredboolean | null
Example · 200
{
  "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

GET/open-api/v1/accounts/{username}/changes

Stored 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

NameInTypeDescription
usernamerequiredpathstringInstagram username. Pagination remains bound to the resolved stable account ID.
listquerystringNot needed with a cursor: the cursor keeps the list, dates and timezone. One of: followers, following. Default followers.
fromquerydateInclusive start date. Requires to. Defaults to the last seven calendar days; at most 366 days.
toquerydateInclusive end date. Requires from.
timezonequerystringIANA timezone that defines the date window. Default UTC.
limitqueryintegerItems per stored read page. 1–100. Default 50.
cursorquerystringOpaque 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

NameTypeDescription
accountIdrequiredstring
usernamerequiredstring
listrequiredstringOne of: followers, following.
fromrequireddate
torequireddate
timezonerequiredstring
summaryrequiredobject
summary.addedrequiredinteger | nullnull when observations are insufficient.
summary.removedrequiredinteger | nullnull when observations are insufficient.
summary.netDiscoveredrequiredinteger | nullnull when observations are insufficient.
summary.countNetChangerequiredinteger | nullnull when observations are insufficient.
itemsrequiredobject[]
items[].idrequiredstring
items[].kindrequiredstringOne of: new_follower, lost_follower, new_follow, unfollow.
items[].detectedAtrequireddate-timeDetection time, not exact Instagram action time.
items[].accountrequiredobject
items[].account.idrequiredstring
items[].account.usernamerequiredstring | null
Example · 200
{
  "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

POST/open-api/v1/queries

Online 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

NameInTypeDescription
Idempotency-KeyrequiredheaderstringUnique key for one logical paid query. Preserve for recovery. Same key with a different body conflicts. 8–200 characters.

Request body

NameTypeDescription
usernamerequiredstring
typerequiredstringOne of: profile, followers, following.
maxCreditsrequiredinteger1–1000.
cursorstringOnline cursor from POST /queries only; not permitted for profile.
Example · profile
{
  "username": "sample_creator",
  "type": "profile",
  "maxCredits": 2
}
Example · followers
{
  "username": "sample_creator",
  "type": "followers",
  "maxCredits": 2
}
Example · following
{
  "username": "sample_creator",
  "type": "following",
  "maxCredits": 2
}
Example · nextPage
{
  "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

NameTypeDescription
idrequiredstringStable Instagram account ID, always a string.
usernamerequiredstring
fullNamerequiredstring | null
avatarUrlrequireduri | nullAbsolute 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.
isPrivaterequiredboolean | null
isVerifiedrequiredboolean | null
followerCountrequiredinteger | null
followingCountrequiredinteger | null
trackedListsrequiredstring[]

Fields of data · List page

NameTypeDescription
accountIdrequiredstring
usernamerequiredstring
availableCountrequiredinteger | nullReadable observed list size, not the profile total. null if unknown.
returnedCountrequiredinteger
itemsrequiredPerson[]
items[].idrequiredstringStable Instagram account ID, always a string.
items[].usernamerequiredstring | null
items[].fullNamerequiredstring | null
items[].avatarUrlrequireduri | nullAbsolute 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[].isPrivaterequiredboolean | null
items[].isVerifiedrequiredboolean | null
Example · 200
{
  "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

StatusMeaning
402budget_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.
409idempotency_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.
410cursor_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.

StatusMeaning
400validation_failed: invalid username, filters or cursor. from/to must be supplied together.
401unauthorized: credential missing, expired or revoked.
403insufficient_scope, list_not_authorized or forbidden: current access does not authorize the resource.
404snapshot_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.
409account_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.
410cursor_expired: the stored paging context is no longer available.
429rate_limited: wait before retrying.
500internal: request could not be completed.
503upstream_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.