Metrics API
Read request totals, throughput by status class, response-time percentiles and the weekly traffic pattern for an environment, bucket or filtered request set.
These operations return the numbers behind the dashboard charts: how many requests you served, how fast, and how many failed. Each one covers one environment over a time range you choose, optionally narrowed to a bucket. For the metric names used in alerts and the MCP server, see the metrics reference.
Permissions: any member, or a user or administrator API token. Metrics are available on every plan.
All times are ISO 8601 in UTC and must end in Z, for example 2026-10-19T00:00:00.000Z.
Get summary metrics
GET https://api.apitraffic.io/v1/accounts/{accountSid}/metrics/summary
Returns the totals for a time range: requests, average response time and errors.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
startTime (query, string, required): Start of the range (ISO 8601, UTC).
-
endTime (query, string, required): End of the range (ISO 8601, UTC).
-
environmentSid (query, string, required): The environment.
-
bucketSid (query, string): Only this bucket.
Response
Each metric has current, previous and change, each with an amount and units.
-
requests (object, required): Requests in the range.
current.unitsisrequests. -
responseTime (object, required): Average response time.
current.unitsismilliseconds. -
errors (object, required): Requests that returned a status of 400 or above.
current.unitsisrequests. -
blocked (object, required): Reserved for requests blocked by the firewall.
Note: Only
currentis filled in today.previous,changeand the whole ofblockedare returned as0. To compare with an earlier period, call the operation again for that period. Firewall blocks are reported by the firewall’s own analytics in the app.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/metrics/summary \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'startTime=2026-10-19T00:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T00:00:00.000Z' \
--data-urlencode 'environmentSid=prd7k2' \
--data-urlencode 'bucketSid=k3m9p2x'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-19T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
environmentSid: 'prd7k2',
bucketSid: 'k3m9p2x',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/metrics/summary?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const summary = await response.json();
const errorRate = summary.errors.current.amount / summary.requests.current.amount;
{
"requests": {
"current": { "amount": 10412, "units": "requests" },
"previous": { "amount": 0, "units": "requests" },
"change": { "amount": 0, "units": "percent" }
},
"responseTime": {
"current": { "amount": 142.6, "units": "milliseconds" },
"previous": { "amount": 0, "units": "milliseconds" },
"change": { "amount": 0, "units": "milliseconds" }
},
"errors": {
"current": { "amount": 538, "units": "requests" },
"previous": { "amount": 0, "units": "requests" },
"change": { "amount": 0, "units": "percent" }
},
"blocked": {
"current": { "amount": 0, "units": "requests" },
"previous": { "amount": 0, "units": "requests" },
"change": { "amount": 0, "units": "percent" }
}
}
Get throughput metrics
GET https://api.apitraffic.io/v1/accounts/{accountSid}/metrics/throughput
Returns request counts and rates over time, split by status class (2xx, 3xx, 4xx, 5xx), plus a summary for the whole range. Narrow it to any set of requests with criteria.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
startTime (query, string, required): Start of the range (ISO 8601, UTC).
-
endTime (query, string, required): End of the range (ISO 8601, UTC).
-
environmentSid (query, string, required): The environment.
-
bucketSid (query, string): Only this bucket.
-
criteria (query, string): Only requests matching this filter, in the search syntax. URL-encode it.
-
resolution (query, string): Width of each period:
1min,10min,1hr,2hr,1dor1mo. Defaults to1minfor a range of an hour or less, otherwise10min. -
units (query, string, default rps): How
averageis expressed:rps(requests per second) orrpm(requests per minute).
Response
- summary (object, required):
The whole range:
startTime,endTime,averageUnits,totalandhttpStatus.
summary
-
total (object):
count(requests) andaverage(requests peraverageUnits) across every status. -
httpStatus (object): The same
countandaveragefor each status class, keyed200,300,400and500. -
periods (object[], required): One entry per period, in time order, with the same fields as
summary. Periods without traffic are included with zeros. -
source (string):
metricswhen the answer came from pre-aggregated metrics,eventswhen it was computed from the requests themselves.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/metrics/throughput \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'startTime=2026-10-19T14:00:00.000Z' \
--data-urlencode 'endTime=2026-10-19T15:00:00.000Z' \
--data-urlencode 'environmentSid=prd7k2' \
--data-urlencode 'criteria=url_path like "/v1/payments/*"' \
--data-urlencode 'resolution=10min' \
--data-urlencode 'units=rpm'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-19T14:00:00.000Z',
endTime: '2026-10-19T15:00:00.000Z',
environmentSid: 'prd7k2',
criteria: 'url_path like "/v1/payments/*"',
resolution: '10min',
units: 'rpm',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/metrics/throughput?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { periods } = await response.json();
const failing = periods.filter((period) => period.httpStatus['500'].count > 0);
{
"summary": {
"startTime": "2026-10-19T14:00:00.000Z",
"endTime": "2026-10-19T15:00:00.000Z",
"averageUnits": "rpm",
"total": { "count": 126, "average": 2.1 },
"httpStatus": {
"200": { "count": 81, "average": 1.35 },
"300": { "count": 0, "average": 0 },
"400": { "count": 3, "average": 0.05 },
"500": { "count": 42, "average": 0.7 }
}
},
"periods": [
{
"startTime": "2026-10-19T14:00:00.000Z",
"endTime": "2026-10-19T14:10:00.000Z",
"averageUnits": "rpm",
"total": { "count": 23, "average": 2.3 },
"httpStatus": {
"200": { "count": 11, "average": 1.1 },
"300": { "count": 0, "average": 0 },
"400": { "count": 1, "average": 0.1 },
"500": { "count": 11, "average": 1.1 }
}
}
],
"source": "metrics"
}
Get response time metrics
GET https://api.apitraffic.io/v1/accounts/{accountSid}/metrics/responseTime
Returns response time over time: average, minimum, maximum and the 50th, 95th and 99th percentiles, per period and for the whole range.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
startTime (query, string, required): Start of the range (ISO 8601, UTC).
-
endTime (query, string, required): End of the range (ISO 8601, UTC).
-
environmentSid (query, string, required): The environment.
-
bucketSid (query, string): Only this bucket.
-
resolution (query, string): Width of each period:
1min,10min,1hr,2hr,1dor1mo. Defaults to1minfor a range of an hour or less, otherwise10min.
Response
All durations are in milliseconds.
- summary (object, required):
The whole range:
startTime,endTime,requests(count),average,minimum,maximumandpercentiles.
percentiles
-
50 (object): The median:
value, and in the summary alsominimum,maximumandmedianof the per-period values. -
95 (object): The 95th percentile, with the same fields.
-
99 (object): The 99th percentile, with the same fields.
-
periods (object[], required): One entry per period with
startTime,endTime,requests,average,minimum,maximumandpercentiles(each withvalueonly). -
approximate (boolean): Present and
truewhen the summary came from pre-aggregated metrics and the range’s edges were moved to their grid (by at most half a step). Absent when the summary covers exactly the range you asked for.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/metrics/responseTime \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'startTime=2026-10-19T00:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T00:00:00.000Z' \
--data-urlencode 'environmentSid=prd7k2' \
--data-urlencode 'resolution=1hr'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-19T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
environmentSid: 'prd7k2',
resolution: '1hr',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/metrics/responseTime?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { summary } = await response.json();
console.log(`p95 ${summary.percentiles['95'].value} ms`);
{
"summary": {
"startTime": "2026-10-19T00:00:00.000Z",
"endTime": "2026-10-20T00:00:00.000Z",
"requests": 10412,
"average": 142.6,
"minimum": 2,
"maximum": 6130,
"percentiles": {
"50": { "value": 61, "minimum": 48, "maximum": 92, "median": 60 },
"95": { "value": 410, "minimum": 220, "maximum": 3980, "median": 380 },
"99": { "value": 1240, "minimum": 610, "maximum": 5210, "median": 1100 }
}
},
"periods": [
{
"startTime": "2026-10-19T14:00:00.000Z",
"endTime": "2026-10-19T15:00:00.000Z",
"requests": 702,
"average": 388.1,
"minimum": 3,
"maximum": 6130,
"percentiles": {
"50": { "value": 92 },
"95": { "value": 3980 },
"99": { "value": 5210 }
}
}
]
}
Get traffic punchcard
GET https://api.apitraffic.io/v1/accounts/{accountSid}/metrics/trafficPunchcard
Returns request counts by day of the week and hour of the day, for a heat map of when your API is busy.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
startTime (query, string, required): Start of the range (ISO 8601, UTC).
-
endTime (query, string, required): End of the range (ISO 8601, UTC).
-
environmentSid (query, string, required): The environment.
-
bucketSid (query, string): Only this bucket.
-
timezone (query, string, default UTC): The IANA time zone days and hours are counted in, for example
America/New_York. Up to 64 characters.
Response
-
summary (object, required):
timezone(as you sent it) andrequests(the total). -
series (object[], required): Seven entries, Sunday first:
dow(0 is Sunday),label(Sunday),shortLabel(Sun) andhours, 24 entries ofhour(0 to 23) andvalue(requests). -
ranges (object[], required): Six suggested color bands for a heat map, each with
from,toandlabel. The first is always0.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/metrics/trafficPunchcard \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'startTime=2026-10-13T00:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T00:00:00.000Z' \
--data-urlencode 'environmentSid=prd7k2' \
--data-urlencode 'timezone=America/New_York'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-13T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
environmentSid: 'prd7k2',
timezone: 'America/New_York',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/metrics/trafficPunchcard?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { series } = await response.json();
{
"summary": { "timezone": "America/New_York", "requests": 72940 },
"ranges": [
{ "from": 0, "to": 0, "label": "0" },
{ "from": 1, "to": 165, "label": "1-165" },
{ "from": 166, "to": 330, "label": "166-330" },
{ "from": 331, "to": 495, "label": "331-495" },
{ "from": 496, "to": 660, "label": "496-660" },
{ "from": 661, "to": 824, "label": "661-824" }
],
"series": [
{
"dow": 0,
"label": "Sunday",
"shortLabel": "Sun",
"hours": [
{ "hour": 0, "value": 212 },
{ "hour": 1, "value": 188 }
]
}
]
}
The example shortens series to one day and two hours.
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
1000 |
A parameter is missing or invalid, for example a time without the trailing Z, or an unknown timezone. |
400 |
2007 |
criteria could not be parsed. |
502 |
5105 |
The query failed. Retry. |
503 |
5102, 5103, 5104 |
Analytics are temporarily unavailable. Retry after Retry-After seconds; for 5104, a shorter, more recent range works now. |
504 |
5101 |
The query took too long. Retry, or narrow the range. |