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.

This page as Markdown

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.units is requests.

  • responseTime (object, required): Average response time. current.units is milliseconds.

  • errors (object, required): Requests that returned a status of 400 or above. current.units is requests.

  • blocked (object, required): Reserved for requests blocked by the firewall.

Note: Only current is filled in today. previous, change and the whole of blocked are returned as 0. 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.

bash
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'
js
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;
json
{
  "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, 1d or 1mo. Defaults to 1min for a range of an hour or less, otherwise 10min.

  • units (query, string, default rps): How average is expressed: rps (requests per second) or rpm (requests per minute).

Response

  • summary (object, required): The whole range: startTime, endTime, averageUnits, total and httpStatus.

summary

  • total (object): count (requests) and average (requests per averageUnits) across every status.

  • httpStatus (object): The same count and average for each status class, keyed 200, 300, 400 and 500.

  • 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): metrics when the answer came from pre-aggregated metrics, events when it was computed from the requests themselves.

bash
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'
js
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);
json
{
  "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, 1d or 1mo. Defaults to 1min for a range of an hour or less, otherwise 10min.

Response

All durations are in milliseconds.

  • summary (object, required): The whole range: startTime, endTime, requests (count), average, minimum, maximum and percentiles.

percentiles

  • 50 (object): The median: value, and in the summary also minimum, maximum and median of 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, maximum and percentiles (each with value only).

  • approximate (boolean): Present and true when 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.

bash
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'
js
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`);
json
{
  "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) and requests (the total).

  • series (object[], required): Seven entries, Sunday first: dow (0 is Sunday), label (Sunday), shortLabel (Sun) and hours, 24 entries of hour (0 to 23) and value (requests).

  • ranges (object[], required): Six suggested color bands for a heat map, each with from, to and label. The first is always 0.

bash
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'
js
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();
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.
  • Dashboard: The charts these numbers drive.

  • APM API: Where the time inside requests goes.