📊 Core API — Usage Reports & Credit Balance
Build your own dashboard on top of your iApp account. The Core API exposes your API usage and credit data as clean, read-only JSON — the same numbers that power the iApp dashboard — so you can pull them into Grafana, Google Sheets, your admin panel, a Slack bot, or anything else that speaks HTTP.
- Same API key you already use for AI APIs — no extra setup
- Read-only by design — every endpoint is
GET; a leaked key can never modify your account through this API - No PII — responses contain only technical telemetry (timestamps, paths, status codes, credits, latency); never names, emails, IPs, or request contents
- Free — Core API calls do not consume credits
Base URL: https://iapp.co.th/api/core/v1
Visit API Key Management to view your key or request a new one.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /ping | Verify your API key works |
GET | /credits | Remaining credit balance |
GET | /usage/summary | Aggregate usage statistics for a date range |
GET | /usage/timeseries | Usage over time (hour/day/week/month buckets) — chart-ready |
GET | /usage/services | Per-service breakdown (requests, credits, latency, error rate) |
GET | /usage/records | Individual API calls with filter, sort and pagination |
All endpoints require the apikey header. Unless stated otherwise, date parameters accept YYYY-MM-DD or full ISO 8601 datetimes, and the default reporting window is the last 30 days.
Authentication
Pass your API key in the apikey header (the x-api-key header also works):
curl "https://iapp.co.th/api/core/v1/ping" \
-H "apikey: YOUR_API_KEY"
{
"success": true,
"data": {
"ok": true,
"apiKeyPrefix": "iapp_liv...",
"timestamp": "2026-08-05T09:30:00.000Z"
}
}
Call the Core API from your backend, scheduled job, or BI tool — never from browser JavaScript. Anyone who can read your page source can read your API key. (Browser calls are additionally blocked by CORS on purpose.)
Credit balance
GET /credits — your remaining iApp Credits (IC).
curl "https://iapp.co.th/api/core/v1/credits" \
-H "apikey: YOUR_API_KEY"
{
"success": true,
"data": {
"balance": 1234.56,
"currency": "IC",
"validUntil": "2027-01-31T16:59:59.000Z"
}
}
Perfect for a low-balance alert: poll once an hour and page yourself when balance drops below your threshold.
Usage summary
GET /usage/summary — the headline numbers for a period.
| Parameter | Type | Default | Description |
|---|---|---|---|
startDate | date | 30 days ago | Period start |
endDate | date | now | Period end |
curl "https://iapp.co.th/api/core/v1/usage/summary?startDate=2026-08-01&endDate=2026-08-05" \
-H "apikey: YOUR_API_KEY"
{
"success": true,
"data": {
"period": { "startDate": "2026-08-01T00:00:00.000Z", "endDate": "2026-08-05T00:00:00.000Z" },
"totalRequests": 18342,
"totalCredits": 2311.75,
"avgLatencyMs": 412,
"successRate": 99.12,
"topEndpoints": [
{ "endpoint": "/thai-ocr/v3.5/ocr-document", "requests": 9120, "credits": 1824.0 },
{ "endpoint": "/v3/store/data/thai-legal/search", "requests": 4210, "credits": 421.0 }
]
}
}
Usage timeseries
GET /usage/timeseries — requests and credits per time bucket, ready to feed straight into a chart library.
| Parameter | Type | Default | Description |
|---|---|---|---|
startDate | date | 30 days ago | Period start |
endDate | date | now | Period end |
groupBy | enum | day | hour, day, week, or month |
curl "https://iapp.co.th/api/core/v1/usage/timeseries?startDate=2026-08-01&endDate=2026-08-05&groupBy=day" \
-H "apikey: YOUR_API_KEY"
{
"success": true,
"data": {
"period": { "startDate": "2026-08-01T00:00:00.000Z", "endDate": "2026-08-05T00:00:00.000Z" },
"groupBy": "day",
"points": [
{ "date": "2026-08-01T00:00:00.000Z", "requests": 4102, "credits": 512.25 },
{ "date": "2026-08-02T00:00:00.000Z", "requests": 3876, "credits": 488.5 },
{ "date": "2026-08-03T00:00:00.000Z", "requests": 5211, "credits": 651.0 }
]
}
}
Bucket timestamps are UTC — convert to your local timezone when rendering.
Per-service breakdown
GET /usage/services — one row per iApp service you called, with quality metrics.
| Parameter | Type | Default | Description |
|---|---|---|---|
startDate / endDate | date | last 30 days | Reporting period |
sortBy | enum | requests | requests, credits, latency, or errorRate |
sortOrder | enum | desc | asc or desc |
curl "https://iapp.co.th/api/core/v1/usage/services?sortBy=credits&sortOrder=desc" \
-H "apikey: YOUR_API_KEY"
{
"success": true,
"data": {
"period": { "startDate": "2026-07-06T09:30:00.000Z", "endDate": "2026-08-05T09:30:00.000Z" },
"services": [
{ "service": "document-ocr", "requests": 9120, "credits": 1824.0, "avgLatencyMs": 890, "errorRate": 0.4 },
{ "service": "thai-legal", "requests": 4210, "credits": 421.0, "avgLatencyMs": 210, "errorRate": 0.1 }
]
}
}
Usage records — filter, sort, paginate
GET /usage/records — the raw call log, one row per API request. This is the workhorse endpoint for custom reporting.
| Parameter | Type | Default | Description |
|---|---|---|---|
startDate / endDate | date | last 30 days | Reporting period |
service | string | — | Only calls to this service (use the service values from /usage/services) |
method | enum | — | GET, POST, PUT, DELETE, PATCH |
status | int | — | Exact HTTP status, e.g. 402 |
statusClass | enum | — | 2xx, 3xx, 4xx, or 5xx (ignored when status is set) |
minCredits | number | — | Only calls that cost at least this many IC |
sortBy | enum | timestamp | timestamp, credits, latency, or status |
sortOrder | enum | desc | asc or desc |
limit | int | 100 | Rows per page, 1–1000 |
offset | int | 0 | Pagination offset (limit + offset ≤ 10,000 — narrow the date range to go deeper) |
Example — my 50 most expensive calls this month:
curl "https://iapp.co.th/api/core/v1/usage/records?startDate=2026-08-01&sortBy=credits&sortOrder=desc&limit=50" \
-H "apikey: YOUR_API_KEY"
Example — all failed calls (4xx) to a service, oldest first:
curl "https://iapp.co.th/api/core/v1/usage/records?service=document-ocr&statusClass=4xx&sortBy=timestamp&sortOrder=asc" \
-H "apikey: YOUR_API_KEY"
{
"success": true,
"data": {
"period": { "startDate": "2026-08-01T00:00:00.000Z", "endDate": "2026-08-05T09:30:00.000Z" },
"records": [
{
"timestamp": "2026-08-04T14:22:31.000Z",
"service": "document-ocr",
"endpoint": "/thai-ocr/v3.5/ocr-document",
"method": "POST",
"status": 402,
"credits": 0,
"latencyMs": 18,
"apiKeyPrefix": "iapp_liv..."
}
],
"pagination": { "total": 3, "limit": 100, "offset": 0, "hasMore": false }
}
}
Paging: repeat the request increasing offset by limit until hasMore is false.
Postman collection
Prefer clicking to curling? Import the ready-made collection — all six endpoints, toggleable filter examples, and 51 built-in assertions (including PII-leak checks):
Import the collection plus an environment, set the apikey environment variable, and go.
Build a dashboard in 20 lines
Python — daily cost report:
import requests
BASE = "https://iapp.co.th/api/core/v1"
HEADERS = {"apikey": "YOUR_API_KEY"}
credits = requests.get(f"{BASE}/credits", headers=HEADERS).json()["data"]
series = requests.get(
f"{BASE}/usage/timeseries",
headers=HEADERS,
params={"startDate": "2026-08-01", "groupBy": "day"},
).json()["data"]
print(f"Balance: {credits['balance']:.2f} IC")
for point in series["points"]:
print(f"{point['date'][:10]} {point['requests']:>6} calls {point['credits']:>8.2f} IC")
Node.js — low-balance alert (run from cron):
const BASE = "https://iapp.co.th/api/core/v1";
const THRESHOLD = 100; // IC
const res = await fetch(`${BASE}/credits`, {
headers: { apikey: process.env.IAPP_API_KEY },
});
const { data } = await res.json();
if (data.balance < THRESHOLD) {
await notifySlack(`⚠️ iApp credits low: ${data.balance} IC left`);
}
Safety & privacy design
The Core API is built so that even in the worst case — your API key leaks — the damage is contained:
- Read-only. Only
GETendpoints exist. There is no way to create keys, spend credits, change settings, or delete anything through this API. - No PII. Responses never include your name, email, user ID, client IP addresses, request headers, or the contents of your API requests/responses. Endpoint paths are stripped of query strings (which could contain input data), and API keys appear only as 8-character prefixes.
- Your data only. The key identifies your account; there is no parameter that can reach another account's data.
- Rate-limited. 120 requests/minute per API key. Responses beyond that return HTTP 429 — poll dashboards at a sensible interval (the data is near-real-time; every 30–60 s is plenty).
If your key does leak, revoke it in API Key Management — usage history stays intact.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid API key |
403 | FORBIDDEN | Account not active |
400 | VALIDATION_ERROR | Bad parameter — the response's error.details.errors lists each problem |
429 | TOO_MANY_REQUESTS | Rate limit exceeded (120/min per key) |
503 | SERVICE_UNAVAILABLE | Temporary backend issue — retry with backoff |
All errors share one shape:
{
"success": false,
"error": { "code": "UNAUTHORIZED", "message": "Invalid API key." }
}
FAQ
Does calling the Core API cost credits? No — it's free and doesn't appear in your usage records.
How fresh is the data? Usage records appear within seconds of the API call completing; credit balance is real-time.
Can I get data older than my dashboard shows? Records are served from our analytics store with the same retention as the web dashboard. For long-term archival, pull /usage/records periodically and store the rows on your side.
Can I use a separate key just for reporting? Yes — create a dedicated key in API Key Management and use it only for the Core API. Each record row shows which key (apiKeyPrefix) made the original call.