Skip to navigation

Usage reports

This endpoint is live. Everything on this page is callable except the Instagram breakdown by entry point, which is still pre-release and marked where it begins.

One endpoint reports activity for every robot on your account.

curl "https://api-chat.parstechai.com/v1/usage?from=2026-09-01T00:00:00Z&to=2026-09-30T23:59:59Z" \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx"
Response
{
"window": { "from": "2026-09-01T00:00:00Z", "to": "2026-09-30T23:59:59Z" },
"data": [
{
"robot_id": "a3f9c21b4e7d40a8",
"external_id": "shop_10422",
"name": "Rose Flower Shop",
"messages": {
"total": 1840,
"units": 1840,
"by_role": { "client": 900, "ai": 820, "operator": 120 }
},
"conversations": { "total": 312 },
"channels_connected": 1
}
],
"pagination": { "limit": 50, "offset": 0, "total_count": 128, "has_more": true },
"metadata": {
"processed_at": "2026-10-01T09:15:22Z",
"cache_hit": false
}
}

by_role separates AI answers from human ones, which is what you need to show your own customers how much of their support the automation is carrying.

messages.total and messages.units are not the same number. A robot using the enhanced-accuracy model consumes two units per message, so a customer who sent 1,000 messages on that model shows total: 1000 and units: 2000.

Reconcile billing against units. Show total to your customer as a message count.

external_id is your identifier for the robot. It is null until robot creation over the API ships, so today every robot returns null here — match on robot_id in the meantime.

The window defaults to the last 30 days and may not span more than a year. Requesting a wider window, a from after your to, or a limit above 100 returns 400.

This reports robot activity, not your remaining balance. It answers “how much did this customer use?” rather than “how much is left on the account?”. Plan balance is out of scope for this API.

metadata.processed_at is the moment the figures are accurate as of. Usage is computed periodically, so a conversation from seconds ago may not be counted yet.

One robot

Pass robot_id to narrow the report to a single robot.

curl "https://api-chat.parstechai.com/v1/usage?robot_id=a3f9c21b4e7d40a8&from=2026-09-01T00:00:00Z&to=2026-09-30T23:59:59Z" \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx"

Paging

Page with limit and offset. pagination.total_count is the number of robots matching your query across every page, so you know how many calls to make before you start.

curl "https://api-chat.parstechai.com/v1/usage?from=2026-09-01T00:00:00Z&to=2026-09-30T23:59:59Z&limit=50&offset=50" \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx"
Python
import math, requests
params = {"from": FROM, "to": TO, "limit": 50, "offset": 0}
first = requests.get(URL, headers=HEADERS, params=params, timeout=30).json()
pages = math.ceil(first["pagination"]["total_count"] / first["pagination"]["limit"])
robots = list(first["data"])
for page in range(1, pages):
params["offset"] = page * params["limit"]
robots += requests.get(URL, headers=HEADERS, params=params, timeout=30).json()["data"]

Instagram breakdown by entry point

Pre-release — not callable yet. This section commits to the shape, not to a date. Passing breakdown=source today returns the standard payload above without the extra fields. Everything else on this page is live.

A customer whose volume comes mostly from story replies has a different product than one driven by comments, and a single total hides that.

curl "https://api-chat.parstechai.com/v1/usage?robot_id=a3f9c21b4e7d40a8&from=2026-09-01T00:00:00Z&to=2026-09-30T23:59:59Z&breakdown=source" \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxx"
Response
{
"data": [
{
"robot_id": "rbt_8fK2mQ",
"external_id": "shop_10422",
"channel": "instagram",
"window": { "from": "2026-09-01T00:00:00Z", "to": "2026-09-30T23:59:59Z" },
"messages": {
"total": 1840,
"by_role": { "client": 900, "ai": 820, "operator": 120 }
},
"conversations": { "total": 312 },
"channels_connected": 1,
"by_source": {
"direct": { "conversations": 180, "messages": 1120 },
"comment": { "conversations": 84, "messages": 310 },
"story_reply": { "conversations": 36, "messages": 290 },
"story_mention": { "conversations": 12, "messages": 120 }
},
"totals": { "conversations": 312, "messages": 1840 }
}
],
"pagination": { "limit": 50, "offset": 0, "total_count": 1, "has_more": false },
"metadata": {
"request_id": "req_8f2Kq9mR",
"processed_at": "2026-10-01T09:15:22Z"
}
}

breakdown=source adds fields rather than replacing them. messages, conversations and channels_connected are still there, so one parser handles both shapes.

SourceMeaning
directA DM the customer started
commentTriggered by a comment on a post
story_replyThe customer replied to a story
story_mentionThe customer mentioned the account in their story
reelOriginated from a reel

The same source vocabulary appears on every message event, so you can attribute an event to its entry point without a second call.

Reconciling a gap

If a webhook delivery exhausted its retries, this API is how you find out. Compare the counts here against what you stored for the same window.