Browse the API docs
Endpoint reference

View Tracker: Managed (our scheduler)

The Crayo View Tracker managed endpoints create trackers that refresh on your cadence, keep every reading and push webhooks. Creating a tracker is free, each refresh costs 1 tracker credit, and every stored read is free.

Raw: you call, you schedule, you store. Managed: we refresh on your cadence, keep every reading, and push webhooks. Same credits either way.

Create a tracker

POST/v1/view-tracker/trackers

Starts tracking a profile or a single post. The first refresh runs right away, then every interval_minutes, and every reading is kept. The type is inferred from the URL, so a post URL makes a post tracker.

  • Creating is free, but the first refresh starts immediately and costs 1 credit, like every refresh after it.
  • The tracker comes back with latest set to null. Post trackers usually fill within seconds and profile trackers within a minute or two: wait for the tracker.refreshed webhook, or poll GET /v1/view-tracker/trackers/{id} every few seconds until latest is not null.
  • If the first refresh fails, latest stays null and tracker.refresh_failed fires. After 3 failures in a row the tracker pauses with status paused_failing.
  • A type is inferred from the URL: Instagram /p/, /tv/ and /reel/ links, YouTube watch links and TikTok /video/ links are posts. Send type only to override a URL we cannot classify.
  • If you run out of credits the tracker pauses with status paused_no_credits and resumes by itself when credits arrive.
Credits:
0 now, 1 credit per refresh
Rate limit:
Tracker writes tier, 2/s and 60/min

Parameters

NameInTypeRequiredDescription
urlbodystringNoProfile or post URL. Instagram, YouTube, TikTok and Twitter are supported. Send url, or handle with platform.
typebodystringNoForce the target type when the URL is ambiguous.profilepost
platformbodystringNoRequired with handle. With a url it must match the url's platform, or the request is a 400.instagramyoutubetiktoktwitter
handlebodystringNoProfile handle, instead of url. Needs platform; a handle without platform is a 400.
interval_minutesbodyintegerNoMinutes between refreshes. Each refresh costs 1 credit, so this sets the monthly cost: 43,200 divided by the interval. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440.default 1440
max_postsbodyintegerNoHow many of the newest posts a profile tracker keeps up to date. Ignored for post trackers. It does not change the price: a refresh is 1 credit at any depth.default 10050100200

Request

curl
curl -X POST "https://api.crayo.ai/v1/view-tracker/trackers" \
  -H "Authorization: Bearer $CRAYO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://www.instagram.com/mornings.with.ada/",
  "interval_minutes": 1440,
  "max_posts": 100
}'

Response

200 application/json
{
  "success": true,
  "tracker": {
    "id": "cm9t3k1r20001abcd",
    "type": "profile",
    "platform": "instagram",
    "url": "https://www.instagram.com/mornings.with.ada/",
    "handle": "mornings.with.ada",
    "status": "active",
    "interval_minutes": 1440,
    "max_posts": 100,
    "next_refresh_at": "2026-10-15T09:12:44.000Z",
    "behind": false,
    "last_refreshed_at": null,
    "credits_per_month": 30,
    "credits_spent": 0,
    "refresh_count": 0,
    "created_at": "2026-10-02T14:03:19.000Z",
    "goal_followers": 100000,
    "goal_by": "2026-12-31T00:00:00.000Z",
    "group_name": "Clients",
    "alert_kinds": [
      "viral",
      "milestone"
    ],
    "latest": null
  }
}

Errors

  • 400VALIDATION_ERRORThe URL does not parse, handle was sent without platform, platform does not match the url, the cadence is outside 10 to 10,080 minutes, or the platform is Facebook (raw mode only).
  • 400UNKNOWN_FIELDThe body carries a field this endpoint does not define.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 402INSUFFICIENT_CREDITSYou have no tracker credits to run the first refresh. Buy a pack or wait for your plan to renew.
  • 409TRACKER_EXISTSYou already track this target. error.tracker_id is the existing tracker's id.
  • 409TRACKER_LIMIT_REACHEDYou are at your active target limit (500 by default). The error carries active_trackers and cap. Ask in Discord (crayo.ai/discord) or email support@crayo.ai and we will raise it.
  • 429CONCURRENT_REQUESTAnother create or batch request for your account is still running. Await it, then retry.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Create trackers in a batch

POST/v1/view-tracker/trackers/batch

Creates up to 100 trackers in one request, profiles and posts mixed. Top-level interval_minutes and max_posts are the defaults; each target can override them. Every target gets its own result row, so one bad URL does not fail the rest.

  • Each item has status created, exists, invalid or limit_reached. invalid items carry an error string, for example for a Facebook URL (raw mode only) or an unparseable URL; limit_reached items did not fit under your target limit. The HTTP status is 200 whenever the request itself was accepted.
  • exists means you already track that target and costs nothing. The existing tracker is left as it is: interval_minutes and max_posts are not changed. Use PATCH to change them.
  • The batch response carries ids, not readings. To read many latest values at once, call GET /v1/view-tracker/trackers: every item carries latest, 25 per page by default.
  • The batch is refused as a whole when you have fewer available credits than valid targets, so every created tracker can run its first refresh.
  • usage in the response is the same object GET /v1/view-tracker/usage returns.
  • Created trackers have latest set to null until their first refresh finishes (seconds for posts, a minute or two for profiles). Wait for tracker.refreshed, or poll GET /v1/view-tracker/trackers/{id}, before you read a reading.
Credits:
0 now, 1 credit per refresh
Rate limit:
Batch create tier, 1/s and 10/min

Parameters

NameInTypeRequiredDescription
targetsbodyobject[]YesThe targets to track, in order. Results come back in the same order. 1 to 100 targets.
targets.urlbodystringNoProfile or post URL. Send url, or handle with platform.
targets.handlebodystringNoProfile handle, instead of url. Needs platform.
targets.platformbodystringNoRequired with handle. With a url it must match the url's platform.instagramyoutubetiktoktwitter
targets.typebodystringNoprofile or post, when the URL is ambiguous.profilepost
targets.interval_minutesbodyintegerNoOverrides the batch default for this target. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440.default 1440
targets.max_postsbodyintegerNoOverrides the batch default for this target.default 10050100200
interval_minutesbodyintegerNoDefault cadence for targets that do not set their own. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440.default 1440
max_postsbodyintegerNoDefault depth for profile targets that do not set their own.default 10050100200

Request

curl
curl -X POST "https://api.crayo.ai/v1/view-tracker/trackers/batch" \
  -H "Authorization: Bearer $CRAYO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "targets": [
    {
      "url": "https://www.instagram.com/mornings.with.ada/"
    },
    {
      "url": "https://www.tiktok.com/@mornings.with.ada",
      "interval_minutes": 720
    },
    {
      "url": "https://www.tiktok.com/@mornings.with.ada/video/7412345678901234567",
      "type": "post",
      "interval_minutes": 60
    }
  ],
  "interval_minutes": 1440,
  "max_posts": 100
}'

Response

200 application/json
{
  "success": true,
  "items": [
    {
      "url": "https://www.instagram.com/mornings.with.ada/",
      "status": "created",
      "id": "cm9t3k1r20001abcd"
    },
    {
      "url": "https://www.tiktok.com/@mornings.with.ada",
      "status": "exists",
      "id": "cm9t3k1s90002abcd"
    },
    {
      "url": "https://www.tiktok.com/@mornings.with.ada/video/7412345678901234567",
      "status": "created",
      "id": "cm9t3k1t40003abcd"
    }
  ],
  "usage": {
    "credits": {
      "available": 1840,
      "subscription": 1340,
      "purchased": 500,
      "monthly_allotment": 2500,
      "resets_at": "2026-11-03T00:00:00.000Z"
    },
    "projected_monthly": 750,
    "active_trackers": {
      "profile": 1,
      "post": 1,
      "total": 2
    },
    "cap": {
      "limit": 500,
      "remaining": 498,
      "raise_via": {
        "discord": "https://crayo.ai/discord",
        "email": "support@crayo.ai"
      }
    }
  }
}

Errors

  • 400VALIDATION_ERRORtargets is empty or has more than 100 entries, or a default is out of range.
  • 400UNKNOWN_FIELDThe body carries a field this endpoint does not define.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 402INSUFFICIENT_CREDITSAvailable credits are fewer than the number of distinct valid targets, counting ones you already track. Nothing is created. The error carries required.
  • 429CONCURRENT_REQUESTAnother create or batch request for your account is still running. Await it, then retry.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

List trackers

GET/v1/view-tracker/trackers

Lists your trackers with their latest stored reading. Stored reads are free.

Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
typequerystringNoOnly profile or post trackers.profilepost
platformquerystringNoOnly one platform.instagramyoutubetiktoktwitter
statusquerystringNoOnly one status.activepausedpaused_no_creditspaused_failingpaused_dormant
limitqueryintegerNoHow many items to return. 1 to 100.default 25
cursorquerystringNoThe pagination.next_cursor of the previous page of trackers, passed back unchanged. It only works for the same target and route, from the same account.

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "trackers": [
    {
      "id": "cm9t3k1r20001abcd",
      "type": "profile",
      "platform": "instagram",
      "url": "https://www.instagram.com/mornings.with.ada/",
      "handle": "mornings.with.ada",
      "status": "active",
      "interval_minutes": 1440,
      "max_posts": 100,
      "next_refresh_at": "2026-10-15T09:12:44.000Z",
      "behind": false,
      "last_refreshed_at": "2026-10-14T09:12:44.000Z",
      "credits_per_month": 30,
      "credits_spent": 12,
      "refresh_count": 12,
      "created_at": "2026-10-02T14:03:19.000Z",
      "goal_followers": 100000,
      "goal_by": "2026-12-31T00:00:00.000Z",
      "group_name": "Clients",
      "alert_kinds": [
        "viral",
        "milestone"
      ],
      "latest": {
        "id": "58291034577",
        "username": "mornings.with.ada",
        "display_name": "Ada | Morning routines",
        "url": "https://www.instagram.com/mornings.with.ada/",
        "bio": "Three habits a week that make your mornings easier.",
        "avatar_url": "https://cdn.example.com/avatars/mornings.with.ada.jpg",
        "is_verified": false,
        "is_private": false,
        "external_url": "https://example.com/mornings",
        "links": [
          {
            "title": "Newsletter",
            "url": "https://example.com/mornings"
          }
        ],
        "followers_count": 182400,
        "following_count": 312,
        "content_count": 418,
        "total_likes": null,
        "observed_at": "2026-10-14T09:12:44.000Z",
        "source": "stored"
      }
    },
    {
      "id": "cm9t3k1s90002abcd",
      "type": "post",
      "platform": "instagram",
      "url": "https://www.instagram.com/reel/C9xAbCdEfGh/",
      "handle": null,
      "status": "active",
      "interval_minutes": 60,
      "max_posts": null,
      "next_refresh_at": "2026-10-14T10:12:44.000Z",
      "behind": false,
      "last_refreshed_at": "2026-10-14T09:12:44.000Z",
      "credits_per_month": 720,
      "credits_spent": 52,
      "refresh_count": 52,
      "created_at": "2026-10-12T09:00:12.000Z",
      "goal_followers": null,
      "goal_by": null,
      "group_name": null,
      "alert_kinds": [
        "removed"
      ],
      "latest": {
        "content_id": "3412345678901234567",
        "shortcode": "C9xAbCdEfGh",
        "url": "https://www.instagram.com/reel/C9xAbCdEfGh/",
        "play_count": 1284500,
        "view_count": 1284500,
        "like_count": 96210,
        "comment_count": 1430,
        "share_count": 8120,
        "save_count": 21480,
        "create_time": 1760250000,
        "caption": "Three habits that quietly ruin your mornings",
        "title": null,
        "duration": 31.4,
        "product_type": "clips",
        "video_url": null,
        "thumbnail_url": "https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg",
        "owner": {
          "id": "58291034577",
          "username": "mornings.with.ada",
          "full_name": "Ada | Morning routines",
          "is_verified": false,
          "profile_pic_url": "https://cdn.example.com/avatars/mornings.with.ada.jpg"
        },
        "audio": {
          "id": "1203948572",
          "artist": "mornings.with.ada",
          "song": "Original audio",
          "is_original": true
        },
        "is_video": true,
        "is_sponsored": false,
        "is_pinned": false,
        "tags": [
          "morningroutine",
          "habits"
        ],
        "images": null,
        "observed_at": "2026-10-14T09:12:44.000Z",
        "source": "stored"
      }
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}

Errors

  • 400VALIDATION_ERRORA filter value is not one of the allowed options, or the cursor is invalid.
  • 400UNKNOWN_FIELDThe query carries a parameter this endpoint does not define. There is no provider parameter anywhere.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Get tracker usage

GET/v1/view-tracker/usage

Returns your tracker credits, what your active trackers will spend this month at their cadences, how many targets you have and your target limit. Call it before a batch create and when you plan how many packs to buy.

  • The credits.tracker balance on GET /v1/account is the same number as credits.available here.
Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/usage" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "usage": {
    "credits": {
      "available": 1840,
      "subscription": 1340,
      "purchased": 500,
      "monthly_allotment": 2500,
      "resets_at": "2026-11-03T00:00:00.000Z"
    },
    "projected_monthly": 750,
    "active_trackers": {
      "profile": 1,
      "post": 1,
      "total": 2
    },
    "cap": {
      "limit": 500,
      "remaining": 498,
      "raise_via": {
        "discord": "https://crayo.ai/discord",
        "email": "support@crayo.ai"
      }
    }
  }
}

Errors

  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Get a tracker

GET/v1/view-tracker/trackers/{id}

Returns one tracker with its latest stored reading. Reading a tracker also tells us you still use it, which keeps it from going dormant.

  • A tracker nobody has read for 30 days pauses itself with status paused_dormant. Any read of it, through the API or the app, wakes it.
Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "tracker": {
    "id": "cm9t3k1r20001abcd",
    "type": "profile",
    "platform": "instagram",
    "url": "https://www.instagram.com/mornings.with.ada/",
    "handle": "mornings.with.ada",
    "status": "active",
    "interval_minutes": 1440,
    "max_posts": 100,
    "next_refresh_at": "2026-10-15T09:12:44.000Z",
    "behind": false,
    "last_refreshed_at": "2026-10-14T09:12:44.000Z",
    "credits_per_month": 30,
    "credits_spent": 12,
    "refresh_count": 12,
    "created_at": "2026-10-02T14:03:19.000Z",
    "goal_followers": 100000,
    "goal_by": "2026-12-31T00:00:00.000Z",
    "group_name": "Clients",
    "alert_kinds": [
      "viral",
      "milestone"
    ],
    "latest": {
      "id": "58291034577",
      "username": "mornings.with.ada",
      "display_name": "Ada | Morning routines",
      "url": "https://www.instagram.com/mornings.with.ada/",
      "bio": "Three habits a week that make your mornings easier.",
      "avatar_url": "https://cdn.example.com/avatars/mornings.with.ada.jpg",
      "is_verified": false,
      "is_private": false,
      "external_url": "https://example.com/mornings",
      "links": [
        {
          "title": "Newsletter",
          "url": "https://example.com/mornings"
        }
      ],
      "followers_count": 182400,
      "following_count": 312,
      "content_count": 418,
      "total_likes": null,
      "observed_at": "2026-10-14T09:12:44.000Z",
      "source": "stored"
    }
  }
}

Errors

  • 400UNKNOWN_FIELDThe query carries a parameter this endpoint does not define. There is no provider parameter anywhere.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Update a tracker

PATCH/v1/view-tracker/trackers/{id}

Changes a tracker's cadence or depth, pauses and resumes it, or sets its goal, group and alerts. Send only the fields you want to change.

Credits:
0, stored
Rate limit:
Tracker writes tier, 2/s and 60/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.
interval_minutesbodyintegerNoNew minutes between refreshes. 10 to 10080. Common values: 10, 30, 60, 180, 720, 1440.default 1440
max_postsbodyintegerNoHow many of the newest posts a profile tracker keeps up to date. Ignored for post trackers. It does not change the price: a refresh is 1 credit at any depth.default 10050100200
statusbodystringNopause with paused, resume with active. Resuming runs a refresh right away.activepaused
goal_followersbodyinteger | nullNoA follower goal, or null to clear it. 0 or more.
goal_bybodystring | nullNoWhen you want to reach the goal, ISO 8601, or null.
group_namebodystring | nullNoA label to group trackers by, or null. Up to 40 characters.
alert_kindsbodystring[]NoWhich events send a tracker.alert webhook. An empty array turns alerts off.viralmilestoneremovednew_postfollower_drop

Request

curl
curl -X PATCH "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd" \
  -H "Authorization: Bearer $CRAYO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "interval_minutes": 60
}'

Response

200 application/json
{
  "success": true,
  "tracker": {
    "id": "cm9t3k1r20001abcd",
    "type": "profile",
    "platform": "instagram",
    "url": "https://www.instagram.com/mornings.with.ada/",
    "handle": "mornings.with.ada",
    "status": "active",
    "interval_minutes": 60,
    "max_posts": 100,
    "next_refresh_at": "2026-10-15T09:12:44.000Z",
    "behind": false,
    "last_refreshed_at": "2026-10-14T09:12:44.000Z",
    "credits_per_month": 720,
    "credits_spent": 12,
    "refresh_count": 12,
    "created_at": "2026-10-02T14:03:19.000Z",
    "goal_followers": 100000,
    "goal_by": "2026-12-31T00:00:00.000Z",
    "group_name": "Clients",
    "alert_kinds": [
      "viral",
      "milestone"
    ],
    "latest": {
      "id": "58291034577",
      "username": "mornings.with.ada",
      "display_name": "Ada | Morning routines",
      "url": "https://www.instagram.com/mornings.with.ada/",
      "bio": "Three habits a week that make your mornings easier.",
      "avatar_url": "https://cdn.example.com/avatars/mornings.with.ada.jpg",
      "is_verified": false,
      "is_private": false,
      "external_url": "https://example.com/mornings",
      "links": [
        {
          "title": "Newsletter",
          "url": "https://example.com/mornings"
        }
      ],
      "followers_count": 182400,
      "following_count": 312,
      "content_count": 418,
      "total_likes": null,
      "observed_at": "2026-10-14T09:12:44.000Z",
      "source": "stored"
    }
  }
}

Errors

  • 400VALIDATION_ERRORThe body is empty, or a value is out of range.
  • 400UNKNOWN_FIELDThe body carries a field this endpoint does not define.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 402INSUFFICIENT_CREDITSYou tried to resume without any tracker credits.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Delete a tracker

DELETE/v1/view-tracker/trackers/{id}

Stops a tracker and deletes it with every reading we kept. This cannot be undone.

Credits:
0, stored
Rate limit:
Tracker writes tier, 2/s and 60/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.

Request

curl
curl -X DELETE "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "id": "cm9t3k1r20001abcd",
  "deleted": true
}

Errors

  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Refresh a tracker now

POST/v1/view-tracker/trackers/{id}/refresh

Queues a refresh ahead of schedule. It returns immediately; the result arrives as a tracker.refreshed webhook, or poll last_refreshed_at on the tracker.

Credits:
1 credit, charged when it runs
Rate limit:
Tracker writes tier, 2/s and 60/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.

Request

curl
curl -X POST "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd/refresh" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "tracker": {
    "id": "cm9t3k1r20001abcd",
    "type": "profile",
    "platform": "instagram",
    "url": "https://www.instagram.com/mornings.with.ada/",
    "handle": "mornings.with.ada",
    "status": "active",
    "interval_minutes": 1440,
    "max_posts": 100,
    "next_refresh_at": "2026-10-15T09:12:44.000Z",
    "behind": false,
    "last_refreshed_at": "2026-10-14T09:12:44.000Z",
    "credits_per_month": 30,
    "credits_spent": 12,
    "refresh_count": 12,
    "created_at": "2026-10-02T14:03:19.000Z",
    "goal_followers": 100000,
    "goal_by": "2026-12-31T00:00:00.000Z",
    "group_name": "Clients",
    "alert_kinds": [
      "viral",
      "milestone"
    ],
    "latest": {
      "id": "58291034577",
      "username": "mornings.with.ada",
      "display_name": "Ada | Morning routines",
      "url": "https://www.instagram.com/mornings.with.ada/",
      "bio": "Three habits a week that make your mornings easier.",
      "avatar_url": "https://cdn.example.com/avatars/mornings.with.ada.jpg",
      "is_verified": false,
      "is_private": false,
      "external_url": "https://example.com/mornings",
      "links": [
        {
          "title": "Newsletter",
          "url": "https://example.com/mornings"
        }
      ],
      "followers_count": 182400,
      "following_count": 312,
      "content_count": 418,
      "total_likes": null,
      "observed_at": "2026-10-14T09:12:44.000Z",
      "source": "stored"
    }
  },
  "refresh": {
    "status": "queued"
  }
}

Errors

  • 400VALIDATION_ERRORThe tracker is paused. Resume it with PATCH and status active first.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 402INSUFFICIENT_CREDITSYou have no tracker credits left. error.credit_type is tracker, and error.remaining and error.required are numbers inside the error object. Nothing was charged.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429REFRESH_IN_PROGRESSA refresh is already queued or running, or the last attempt was less than 60 seconds ago. The error carries retry_after_seconds, and so does the Retry-After header.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

List a tracker's snapshots

GET/v1/view-tracker/trackers/{id}/snapshots

Returns the stored series of the target itself: profile snapshots (followers, following, posts) for a profile tracker, post snapshots (views, likes, comments and more) for a post tracker. This is your chart data.

  • Readings are kept hourly for the last 14 days and daily beyond that. Newest first.
Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.
fromquerystringNoOldest reading to return, ISO 8601.
toquerystringNoNewest reading to return, ISO 8601.
limitqueryintegerNoHow many items to return. 1 to 500.default 100
cursorquerystringNoThe pagination.next_cursor of the previous page of snapshots, passed back unchanged. It only works for the same target and route, from the same account.

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd/snapshots" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "snapshots": [
    {
      "observed_at": "2026-10-14T09:12:44.000Z",
      "followers": 182400,
      "following": 312,
      "posts": 418,
      "total_views": null,
      "total_likes": null
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}

Errors

  • 400VALIDATION_ERRORfrom, to, limit or cursor is invalid.
  • 400UNKNOWN_FIELDThe query carries a parameter this endpoint does not define. There is no provider parameter anywhere.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

List a tracker's events

GET/v1/view-tracker/trackers/{id}/events

What changed on the target between refreshes: new, viral, removed and milestone posts, caption and pin changes, profile edits, follower milestones and drops. Newest first, kept for 90 days.

Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.
limitqueryintegerNoHow many items to return. 1 to 200.default 50
cursorquerystringNoThe pagination.next_cursor of the previous page of events, passed back unchanged. It only works for the same target and route, from the same account.

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd/events" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "events": [
    {
      "id": "cm9t3r8v10009abcd",
      "kind": "post.viral",
      "at": "2026-10-14T09:12:44.000Z",
      "post_id": "cm9t3p4q50003abcd",
      "before": null,
      "after": null,
      "value": 412380
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}

Errors

  • 400VALIDATION_ERRORlimit or cursor is invalid.
  • 400UNKNOWN_FIELDThe query carries a parameter this endpoint does not define. There is no provider parameter anywhere.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

List a profile tracker's posts

GET/v1/view-tracker/trackers/{id}/posts

Lists the posts a profile tracker is following, with their latest counts and when each was first and last seen. Removed posts are hidden unless you ask for them.

Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.
sortquerystringNoHow to order the posts.default recentrecentviewslikescommentsshares
sincequerystringNoOnly posts published at or after this time. ISO 8601 or Unix seconds.
include_removedquerybooleanNoInclude posts that were deleted, made private or restricted.default false
limitqueryintegerNoHow many items to return. 1 to 200.default 50
cursorquerystringNoThe pagination.next_cursor of the previous page of posts, passed back unchanged. It only works for the same target and route, from the same account.

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd/posts" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "posts": [
    {
      "content_id": "3412345678901234567",
      "shortcode": "C9xAbCdEfGh",
      "url": "https://www.instagram.com/reel/C9xAbCdEfGh/",
      "play_count": 1284500,
      "view_count": 1284500,
      "like_count": 96210,
      "comment_count": 1430,
      "share_count": 8120,
      "save_count": 21480,
      "create_time": 1760250000,
      "caption": "Three habits that quietly ruin your mornings",
      "title": null,
      "duration": 31.4,
      "product_type": "clips",
      "video_url": null,
      "thumbnail_url": "https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg",
      "owner": {
        "id": "58291034577",
        "username": "mornings.with.ada",
        "full_name": "Ada | Morning routines",
        "is_verified": false,
        "profile_pic_url": "https://cdn.example.com/avatars/mornings.with.ada.jpg"
      },
      "audio": {
        "id": "1203948572",
        "artist": "mornings.with.ada",
        "song": "Original audio",
        "is_original": true
      },
      "is_video": true,
      "is_sponsored": false,
      "is_pinned": false,
      "tags": [
        "morningroutine",
        "habits"
      ],
      "images": null,
      "observed_at": "2026-10-14T09:12:44.000Z",
      "source": "stored",
      "id": "cm9t3p4q50003abcd",
      "first_seen_at": "2026-10-12T09:00:12.000Z",
      "last_seen_at": "2026-10-14T09:12:44.000Z",
      "removed_at": null,
      "removed_status": null
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}

Errors

  • 400VALIDATION_ERRORA parameter is out of range, or the cursor is invalid.
  • 400UNKNOWN_FIELDThe query carries a parameter this endpoint does not define. There is no provider parameter anywhere.
  • 400NOT_A_PROFILEThe tracker follows a single post. Use its snapshots instead.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Get a tracked post

GET/v1/view-tracker/trackers/{id}/posts/{post_id}

Returns one tracked post with the comments we stored for it. The comments array sits inside the post object: up to 20, pinned first, each with the time we fetched it.

Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.
post_idpathstringYesThe tracked post's id from the posts list (the id field, not the platform's content_id).

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd/posts/cm9t3p4q50003abcd" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "post": {
    "content_id": "3412345678901234567",
    "shortcode": "C9xAbCdEfGh",
    "url": "https://www.instagram.com/reel/C9xAbCdEfGh/",
    "play_count": 1284500,
    "view_count": 1284500,
    "like_count": 96210,
    "comment_count": 1430,
    "share_count": 8120,
    "save_count": 21480,
    "create_time": 1760250000,
    "caption": "Three habits that quietly ruin your mornings",
    "title": null,
    "duration": 31.4,
    "product_type": "clips",
    "video_url": null,
    "thumbnail_url": "https://cdn.example.com/thumbs/C9xAbCdEfGh.jpg",
    "owner": {
      "id": "58291034577",
      "username": "mornings.with.ada",
      "full_name": "Ada | Morning routines",
      "is_verified": false,
      "profile_pic_url": "https://cdn.example.com/avatars/mornings.with.ada.jpg"
    },
    "audio": {
      "id": "1203948572",
      "artist": "mornings.with.ada",
      "song": "Original audio",
      "is_original": true
    },
    "is_video": true,
    "is_sponsored": false,
    "is_pinned": false,
    "tags": [
      "morningroutine",
      "habits"
    ],
    "images": null,
    "observed_at": "2026-10-14T09:12:44.000Z",
    "source": "stored",
    "id": "cm9t3p4q50003abcd",
    "first_seen_at": "2026-10-12T09:00:12.000Z",
    "last_seen_at": "2026-10-14T09:12:44.000Z",
    "removed_at": null,
    "removed_status": null,
    "comments": [
      {
        "id": "17912345678901234",
        "text": "Number two is exactly why I never made it to the gym",
        "created_at": "2026-10-13T18:22:10.000Z",
        "like_count": 412,
        "reply_count": 9,
        "is_pinned": false,
        "is_hearted": true,
        "author": {
          "id": "40128839012",
          "username": "late.riser.lena",
          "display_name": "Lena",
          "avatar_url": "https://cdn.example.com/avatars/late.riser.lena.jpg",
          "is_verified": false,
          "url": "https://www.instagram.com/late.riser.lena/"
        },
        "fetched_at": "2026-10-14T09:12:44.000Z"
      }
    ]
  }
}

Errors

  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

List a tracked post's snapshots

GET/v1/view-tracker/trackers/{id}/posts/{post_id}/snapshots

Returns the stored series for one post inside a profile tracker: views, likes, comments, shares and saves over time.

  • Readings are kept hourly for the last 14 days and daily beyond that. Newest first.
Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.
post_idpathstringYesThe tracked post's id from the posts list (the id field, not the platform's content_id).
fromquerystringNoOldest reading to return, ISO 8601.
toquerystringNoNewest reading to return, ISO 8601.
limitqueryintegerNoHow many items to return. 1 to 500.default 100
cursorquerystringNoThe pagination.next_cursor of the previous page of snapshots, passed back unchanged. It only works for the same target and route, from the same account.

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd/posts/cm9t3p4q50003abcd/snapshots" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "snapshots": [
    {
      "observed_at": "2026-10-14T09:12:44.000Z",
      "counts": {
        "views": 1284500,
        "plays": 1284500,
        "likes": 96210,
        "comments": 1430,
        "shares": 8120,
        "saves": 21480
      }
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}

Errors

  • 400VALIDATION_ERRORfrom, to, limit or cursor is invalid.
  • 400UNKNOWN_FIELDThe query carries a parameter this endpoint does not define. There is no provider parameter anywhere.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.

Get a tracker's insights

GET/v1/view-tracker/trackers/{id}/insights

Our optional math on top of the stored readings: follower growth over 7 days, posting pace, median views, engagement rate, which posts went viral and how consistent the account is. An empty object for post trackers. Readings elsewhere are never adjusted; this is the only place we interpret them.

  • A post tracker returns an empty insights object.
Credits:
0, stored
Rate limit:
Tracker reads tier, 5/s and 300/min

Parameters

NameInTypeRequiredDescription
idpathstringYesThe tracker id.

Request

curl
curl "https://api.crayo.ai/v1/view-tracker/trackers/cm9t3k1r20001abcd/insights" \
  -H "Authorization: Bearer $CRAYO_API_KEY"

Response

200 application/json
{
  "success": true,
  "insights": {
    "followers_delta_7d": 2310,
    "posts_per_week": 3.5,
    "median_views": 412000,
    "engagement_rate": 0.083,
    "viral_post_ids": [
      "cm9t3p4q50003abcd"
    ],
    "consistency": 0.82
  }
}

Errors

  • 400UNKNOWN_FIELDThe query carries a parameter this endpoint does not define. There is no provider parameter anywhere.
  • 401MISSING_API_KEYNo Authorization header was sent, or it does not carry a crayo_sk_ key.
  • 401UNAUTHORIZEDThe key sent is malformed, expired, or revoked.
  • 404NOT_FOUNDNo tracker with that id belongs to your account.
  • 429RATE_LIMITEDOver this tier's limit, counted per account. Raw lookups also answer this when 10 are already in flight. Wait the number of seconds in the Retry-After header.
  • 429RATE_LIMITEDOver the rate limit. Wait Retry-After seconds.
  • 500SERVER_ERRORSomething failed on our side. Retry with backoff.
New to the Crayo API? See what it is forUse cases, pricing and the console walkthrough live on the API feature page.

FAQs

Frequent questions

interval_minutes accepts 10 to 10080 and defaults to 1440. Each refresh costs 1 credit, so the monthly cost is 43,200 divided by the interval. Profile trackers keep 50, 100, 200 newest posts up to date, 100 by default.

500 active trackers per account, 100 targets per batch create, 3 refreshes running at once and 60 seconds between manual refreshes of one tracker. Creating trackers is one request at a time per account.

tracker.refreshed with the latest reading, snapshot, new posts and removed post ids; tracker.refresh_failed; tracker.paused; tracker.alert for viral, milestone, removed, new_post and follower_drop alerts; and credits.low once per cycle.

Snapshots are kept hourly for the last 14 days and daily beyond that, events for 90 days. A tracker nobody reads for 30 days pauses as paused_dormant and any read wakes it. Raw history lookups go back 60 days.

Still have questions?

Contact our 24/7 support team for any concerns or inquiries.

Get in touch