APM API
Read where request time goes, which endpoints and operations consume it, what regressed after a deploy, slow examples, dependencies and distributed traces.
These operations answer the questions on the app’s APM pages: where request time goes, which endpoints use the most of it, what got slower, and which requests belong to one distributed trace. The first four are computed from the per-request APM totals, so they stay fast at any traffic volume. The APM analytics operations go deeper: span operations and endpoints ranked on the server, trends, heatmaps, before-and-after comparisons, slow examples and dependencies. For individual operations, see also the Spans API.
Plan: needs a plan that includes APM; otherwise every operation answers 403 with code 2221. Permissions: any member, or a user or administrator API token.
All times are ISO 8601 in UTC, for example 2026-10-19T00:00:00.000Z. Durations are in milliseconds.
Time breakdown
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/breakdown
Splits request time into database, cache, outbound HTTP, queue and RPC, and application time, as a total for the range and as a time series. Application time is what remains after the instrumented operations, never below 0.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
startTime (query, string, required): Start of the range.
-
endTime (query, string, required): End of the range.
-
environmentSid (query, string): Only this environment.
-
bucketSid (query, string): Only this bucket.
-
endpoint (query, string): Only this endpoint, for example
/v1/orders/{order_id}.
Response
- summary (object, required): The whole range.
summary
-
requestCount (number): Requests.
-
errorCount (number): Requests that failed.
-
totalMs (number): Wall-clock time of the requests.
-
dbMs (number): Time in database queries.
-
cacheMs (number): Time in Redis and other caches.
-
httpOutMs (number): Time in outbound HTTP calls.
-
queueMs (number): Time in queue and RPC calls.
-
appMs (number): Remaining in-process time.
-
spanCount (number): Spans recorded.
-
p50Ms (number): Median request duration.
-
p95Ms (number): 95th percentile duration.
-
p99Ms (number): 99th percentile duration.
-
timeseries (object[], required): The same fields per period (without
p50Msandp99Ms), plusbucket: the start of the period. The period width follows the length of the range. -
rollup (boolean, required):
truewhen the answer came from pre-aggregated metrics.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/breakdown \
-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 'bucketSid=k3m9p2x'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-19T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
bucketSid: 'k3m9p2x',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/breakdown?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { summary } = await response.json();
console.log(`database share: ${Math.round((summary.dbMs / summary.totalMs) * 100)}%`);
{
"summary": {
"requestCount": 10412,
"errorCount": 538,
"totalMs": 1484700,
"dbMs": 612300,
"cacheMs": 21400,
"httpOutMs": 498100,
"queueMs": 0,
"appMs": 352900,
"spanCount": 88210,
"p50Ms": 61,
"p95Ms": 410,
"p99Ms": 1240
},
"timeseries": [
{
"bucket": "2026-10-19T14:00:00.000Z",
"requestCount": 702,
"errorCount": 61,
"totalMs": 272400,
"dbMs": 41800,
"cacheMs": 1500,
"httpOutMs": 201300,
"queueMs": 0,
"appMs": 27800,
"spanCount": 5960,
"p95Ms": 3980
}
],
"rollup": true
}
Endpoints by time consumed
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/endpoints
Ranks endpoints by the total time they consume, with the same split as Time breakdown. Total time, not average latency, shows where your capacity goes: a fast endpoint called constantly can cost more than a slow one called rarely.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
startTime (query, string, required): Start of the range.
-
endTime (query, string, required): End of the range.
-
environmentSid (query, string): Only this environment.
-
bucketSid (query, string): Only this bucket.
-
limit (query, integer, default 50): Endpoints to return, 1 to 1000.
Response
- points (object[], required):
One entry per endpoint, most time first:
endpoint,requestCount,errorCount,averageDurationMs,p95Ms,p99Ms,lastSeen, and the time splittotalMs,dbMs,cacheMs,httpOutMs,queueMs,appMsandspanCount.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/endpoints \
-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 'limit=10'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-19T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
limit: '10',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/endpoints?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"points": [
{
"endpoint": "/v1/checkout",
"requestCount": 612,
"errorCount": 9,
"averageDurationMs": 684,
"p95Ms": 1420,
"p99Ms": 2310,
"lastSeen": "2026-10-19T23:58:41.000Z",
"totalMs": 418600,
"dbMs": 96300,
"cacheMs": 2100,
"httpOutMs": 287400,
"queueMs": 0,
"appMs": 32800,
"spanCount": 9180
},
{
"endpoint": "/v1/orders/{order_id}",
"requestCount": 1830,
"errorCount": 22,
"averageDurationMs": 171,
"p95Ms": 512,
"p99Ms": 940,
"lastSeen": "2026-10-19T23:59:12.000Z",
"totalMs": 312900,
"dbMs": 261700,
"cacheMs": 4100,
"httpOutMs": 0,
"queueMs": 0,
"appMs": 47100,
"spanCount": 42090
}
]
}
Regressions
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/regressions
Finds endpoints whose latency or error rate moved against a baseline window, ranked by how much the change matters given their traffic.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
startTime (query, string, required): Start of the window to examine.
-
endTime (query, string, required): End of the window to examine.
-
environmentSid (query, string): Only this environment.
-
bucketSid (query, string): Only this bucket.
-
baseline (query, string, default previous):
previouscompares with the window just before, of the same length.weekAgocompares with the same window seven days earlier, which suits traffic with a weekly shape. -
minRequests (query, integer, default 20): Ignore endpoints with fewer requests than this in either window, 1 to 1,000,000.
-
limit (query, integer, default 20): Endpoints to return, 1 to 1000.
Response
-
baseline (string, required): The baseline used.
-
points (object[], required): One entry per endpoint, most significant first.
point
-
endpoint (string): The endpoint.
-
requestCount (number): Requests in the window.
-
baselineRequestCount (number): Requests in the baseline.
-
p95Ms (number): 95th percentile now.
-
baselineP95Ms (number): 95th percentile in the baseline.
-
p95DeltaPct (number): Change in the 95th percentile, in percent.
-
errorRate (number): Share of requests that failed now, from 0 to 1.
-
baselineErrorRate (number): The same in the baseline.
-
errorRateDelta (number): The difference.
-
totalMs (number): Time consumed now.
-
baselineTotalMs (number): Time consumed in the baseline.
-
score (number): The ranking score: latency and error movement weighted by traffic.
-
baseline (string): The baseline used.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/regressions \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'startTime=2026-10-19T14:00:00.000Z' \
--data-urlencode 'endTime=2026-10-19T14:40:00.000Z' \
--data-urlencode 'baseline=weekAgo'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-19T14:00:00.000Z',
endTime: '2026-10-19T14:40:00.000Z',
baseline: 'weekAgo',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/regressions?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"baseline": "weekAgo",
"points": [
{
"endpoint": "/v1/payments/{payment_id}/capture",
"baseline": "weekAgo",
"requestCount": 96,
"baselineRequestCount": 91,
"p95Ms": 3980,
"baselineP95Ms": 310,
"p95DeltaPct": 1183.9,
"errorRate": 0.44,
"baselineErrorRate": 0.01,
"errorRateDelta": 0.43,
"totalMs": 241200,
"baselineTotalMs": 21800,
"score": 912.4
}
]
}
Distributed trace
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/trace
Returns every captured request that belongs to one distributed trace, in time order, across buckets and services. Each request is stamped with its trace id when it is captured: from the incoming traceparent header when there is one.
Path parameters
- accountSid (path, string, required): The account identifier.
Query parameters
-
traceId (query, string, required): The trace id.
-
startTime (query, string, required): Start of the range to search.
-
endTime (query, string, required): End of the range to search.
-
environmentSid (query, string): Only this environment.
-
bucketSid (query, string): Only this bucket.
-
limit (query, integer, default 100): Requests to return, 1 to 1000.
Response
-
traceId (string, required): The trace id.
-
points (object[], required): The requests, oldest first:
dt(when it started),sid,endpoint,method,host,path,direction,bucketSid,environmentSid,statusCode,durationMsandspanCount. Usesidwith Get request for the detail.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/trace \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'traceId=4bf92f3577b34da6a3ce929d0e0e4736' \
--data-urlencode 'startTime=2026-10-19T14:00:00.000Z' \
--data-urlencode 'endTime=2026-10-19T15:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
traceId: '4bf92f3577b34da6a3ce929d0e0e4736',
startTime: '2026-10-19T14:00:00.000Z',
endTime: '2026-10-19T15:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/trace?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"points": [
{
"dt": "2026-10-19T14:21:07.412Z",
"sid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
"endpoint": "/v1/payments/{payment_id}/capture",
"method": "POST",
"host": "api.acme-store.example",
"path": "/v1/payments/pi_3f9a1c7e2b4d6a/capture",
"direction": "in",
"bucketSid": "k3m9p2x",
"environmentSid": "prd7k2",
"statusCode": 502,
"durationMs": 4012,
"spanCount": 3
},
{
"dt": "2026-10-19T14:21:07.418Z",
"sid": "req_2cV9bN1mK4jH7gF3dS6aP8oI5uY",
"endpoint": "/v1/payment_intents/{payment_intent_id}/capture",
"method": "POST",
"host": "payments.acme-pay.example",
"path": "/v1/payment_intents/pi_3f9a1c7e2b4d6a/capture",
"direction": "out",
"bucketSid": "k3m9p2x",
"environmentSid": "prd7k2",
"statusCode": 504,
"durationMs": 3995,
"spanCount": 0
}
]
}
APM analytics
The operations below power the app’s APM analytics pages. They rank span operations and endpoints on the server by total time, percentiles, calls, calls per request or regression score, chart one of them over time, compare it before and after a deploy, and return slow examples to open. Unlike the operations above, they report span-level detail and estimated call counts.
Every analytics response starts with the same fields:
-
sourceState (string, required):
ready, orabsentwhen the account has no data of this kind yet, so an empty answer is expected. -
source (string, required):
hot_raw(computed from individual spans) ormetrics(from pre-aggregated metrics). -
coverage (object, required): How much of the range was read:
status(full,partialornone),source,requestedandeffective(the range actually read),hotFrom,reason(why it is partial, for examplemetrics_lagorraw_window_capped) andfoldedShare. -
estimator (string | null, required): How percentiles were computed:
tdigest,exactorhistogram. -
unit (string, required): The unit of every duration in the answer:
us(microseconds) orms. -
window (object, required): The range answered:
from,to(rounded inward to minutes) andsnapSeconds.
Answers about operations also carry statementText (whether the account stores statement text) and dictionaryAvailable (whether fingerprint details could be read in time).
All of them take startTime and endTime (required; endTime is exclusive), and optional bucketSid and environmentSid.
Rank span operations
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/operations
Ranks span operations (a fingerprint and its algorithm version) on the server, so slow but rare operations are not cut off by limit.
Query parameters
-
startTime (query, string, required): Start of the range.
-
endTime (query, string, required): End of the range (exclusive).
-
orderBy (query, string, default total):
total,p95,p99,calls,calls_per_request(N+1 queries first),error_rateorregression. -
limit (query, integer, default 50): Operations to return, 1 to 100.
-
endpoint (query, string): Only operations run by this inbound endpoint.
-
types (query, string): Only these span types, comma-separated:
db.query,redis,cache,http.out,queue,rpc,graphql,custom. -
minCalls (query, number, default 20): For
error_rate,calls_per_requestandregressionranking, ignore operations with fewer estimated calls (per side, for regression). -
pivotAt (query, string): For
regressionranking, the deploy time that splits before from after. Defaults to the middle of the range. -
minRelativeIncrease (query, number, default 0.1): For
regressionranking, the smallest p95 increase that counts (0.1is +10%). -
fpVersion (query, integer): Only this fingerprint algorithm version.
Response
The common fields, orderBy, limit, minCalls, pivotAt, and:
- points (object[], required):
One entry per operation:
fingerprint,fpVersion,calls(estimated),rows(spans read),total,avg,p50,p95,p99,max,errors,errorRate,lastSeen,latestVersion(the latest service version seen),sampledRequests,callsPerRequest,type,system,op,target,name,db,host,regression(withregressionranking) anddictionary(fingerprint details, ornull).
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/operations \
-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 'orderBy=calls_per_request' \
--data-urlencode 'types=db.query'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
startTime: '2026-10-19T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
orderBy: 'calls_per_request',
types: 'db.query',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/operations?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"sourceState": "ready",
"coverage": { "status": "full", "source": "hot_raw", "requested": {}, "hotFrom": null },
"source": "hot_raw",
"estimator": "exact",
"unit": "us",
"window": { "from": "2026-10-19T00:00:00.000Z", "to": "2026-10-20T00:00:00.000Z", "snapSeconds": 60 },
"orderBy": "calls_per_request",
"limit": 50,
"minCalls": 20,
"pivotAt": null,
"statementText": true,
"dictionaryAvailable": true,
"points": [
{
"fingerprint": "fpr_5b8e2d7c1a9f4e3b",
"fpVersion": 1,
"calls": 21960,
"rows": 21960,
"total": 40406400,
"avg": 1840,
"p50": 1500,
"p95": 4200,
"p99": 7900,
"max": 12100,
"errors": 0,
"errorRate": 0,
"lastSeen": "2026-10-19T23:59:12.000Z",
"latestVersion": "v2026.10.19",
"sampledRequests": 1830,
"callsPerRequest": 12,
"type": "db.query",
"system": "postgresql",
"op": "SELECT",
"target": "order_items",
"name": "SELECT order_items",
"db": "acme_store",
"host": "db.acme.internal",
"dictionary": null
}
]
}
Span operation trend
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/operations/trend
Charts p50, p95, p99, calls and errors over time for one operation.
Query parameters
-
startTime (query, string, required): Start of the range.
-
endTime (query, string, required): End of the range (exclusive).
-
fingerprint (query, string, required): The operation’s fingerprint (
fpr_…). -
fpVersion (query, integer, required): Its algorithm version, 1 to 255 (from Rank span operations;
1when it has none). -
endpoint (query, string): Only spans run by this inbound endpoint.
-
maxPoints (query, integer, default 120): At most this many periods, 2 to 500.
Response
The common fields, and:
-
step (object | null, required): The period width:
stepSeconds,fromSeconds,toSeconds, and whether the first and last periods are partial. -
points (object[], required): One entry per period:
bucket(start, epoch seconds),calls,rows,errors,total,p50,p95andp99. -
operation (object | null, required): What the operation is:
type,system,db,op,target,name,host,callSite,callSiteFn,firstSeenVersion,firstSeenAt,lastSeenAt,statementandcallStack(bothnullunless statement text is on).
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/operations/trend \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'fingerprint=fpr_5b8e2d7c1a9f4e3b' \
--data-urlencode 'fpVersion=1' \
--data-urlencode 'startTime=2026-10-19T00:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T00:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
fingerprint: 'fpr_5b8e2d7c1a9f4e3b',
fpVersion: '1',
startTime: '2026-10-19T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/operations/trend?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"sourceState": "ready",
"source": "hot_raw",
"unit": "us",
"step": { "stepSeconds": 720, "fromSeconds": 1792368000, "toSeconds": 1792454400, "firstBucketPartial": false, "lastBucketPartial": false },
"points": [
{ "bucket": 1792418400, "calls": 1104, "rows": 1104, "errors": 0, "total": 2030000, "p50": 1500, "p95": 4100, "p99": 7700 }
],
"operation": { "type": "db.query", "system": "postgresql", "db": "acme_store", "op": "SELECT", "target": "order_items", "name": "SELECT order_items", "host": "db.acme.internal", "callSite": "src/repositories/orderRepository.js:48:22", "callSiteFn": "loadLineItems", "firstSeenVersion": "v2026.10.2", "firstSeenAt": "2026-10-02T10:04:51.000Z", "lastSeenAt": "2026-10-19T23:59:12.000Z", "statement": "SELECT * FROM order_items WHERE order_id = $1 AND line = $2", "callStack": null },
"statementText": true,
"dictionaryAvailable": true
}
The examples on this page leave out some of the common fields.
Span operation heatmap
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/operations/heatmap
Returns a latency heatmap for one operation: counts of spans per period and fixed latency band.
Query parameters
The same as Span operation trend; maxPoints defaults to 60.
Response
The common fields, step and operation as in Span operation trend, and:
-
bounds (number[], required): The latency band edges, in
unit. -
cells (object[], required): One entry per non-empty cell:
bucket(period start, epoch seconds),latencyBucket(the band’s index),lower,upperandcount.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/operations/heatmap \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'fingerprint=fpr_2a7e9c4b1d8f6e3a' \
--data-urlencode 'fpVersion=1' \
--data-urlencode 'startTime=2026-10-19T13:00:00.000Z' \
--data-urlencode 'endTime=2026-10-19T16:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
fingerprint: 'fpr_2a7e9c4b1d8f6e3a',
fpVersion: '1',
startTime: '2026-10-19T13:00:00.000Z',
endTime: '2026-10-19T16:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/operations/heatmap?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { cells } = await response.json();
{
"sourceState": "ready",
"unit": "us",
"bounds": [1000, 10000, 100000, 1000000, 10000000],
"cells": [
{ "bucket": 1792418400, "latencyBucket": 3, "lower": 1000000, "upper": 10000000, "count": 19 }
]
}
Span operation regression
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/operations/regression
Compares one operation before and after a deploy, split by time or by service version, with both distributions and a verdict.
Query parameters
The fingerprint parameters of Span operation trend, plus:
-
pivotAt (query, string, required): The deploy time that splits before from after, inside the range.
-
version (query, string): Split by version instead: spans from this service version are “after” whenever they ran, other versions “before”.
-
previousVersion (query, string): With
version, only this version counts as “before”. -
unlabelled (query, string, default by_time): Spans without a service version:
by_time(split bypivotAt) orexclude.
Response
The common fields, operation, and:
-
mode (string, required):
timeorversion. -
before (object | null, required):
calls,rows,errors,unlabelled,p50,p95,p99andhist(counts per band inbounds).afterhas the same fields. -
verdict (object | null, required):
regressed,score(the p95 increase times the calls after;nullwith too little data),deltaP95,ratioP95andreason(insufficient_data,below_threshold,improvedornull).
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/operations/regression \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'fingerprint=fpr_5b8e2d7c1a9f4e3b' \
--data-urlencode 'fpVersion=1' \
--data-urlencode 'pivotAt=2026-10-19T10:00:00.000Z' \
--data-urlencode 'startTime=2026-10-18T10:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T10:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
fingerprint: 'fpr_5b8e2d7c1a9f4e3b',
fpVersion: '1',
pivotAt: '2026-10-19T10:00:00.000Z',
startTime: '2026-10-18T10:00:00.000Z',
endTime: '2026-10-20T10:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/operations/regression?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { verdict } = await response.json();
{
"sourceState": "ready",
"unit": "us",
"pivotAt": "2026-10-19T10:00:00.000Z",
"mode": "time",
"bounds": [1000, 10000, 100000],
"before": { "calls": 20410, "rows": 20410, "errors": 0, "unlabelled": 0, "p50": 1400, "p95": 3900, "p99": 7100, "hist": [8100, 12200, 110, 0] },
"after": { "calls": 21960, "rows": 21960, "errors": 0, "unlabelled": 0, "p50": 1500, "p95": 4200, "p99": 7900, "hist": [8300, 13500, 160, 0] },
"verdict": { "score": 6588000, "deltaP95": 300, "ratioP95": 1.08, "regressed": false, "reason": "below_threshold" }
}
Span operation examples
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/operations/examples
Returns the slowest spans of one operation, and optionally some near a threshold such as its p95, to open in the request detail.
Query parameters
The fingerprint parameters of Span operation trend, plus:
-
limit (query, integer, default 20): Slowest examples, 1 to 100.
-
nearDuration (query, number): Also return examples at or just above this duration (in the answer’s
unit), typically the p95 from the trend. -
nearLimit (query, integer): How many of those, 1 to 50.
Response
The common fields, operation, and:
- examples (object[], required):
One entry per span:
kind(slowest or near the threshold),dt,requestDt,requestSid(open it with Get request),spanSid,traceId,duration,ok,errorClass,statusCode,endpoint,method,serviceVersionandinstanceSid.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/operations/examples \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'fingerprint=fpr_2a7e9c4b1d8f6e3a' \
--data-urlencode 'fpVersion=1' \
--data-urlencode 'limit=5' \
--data-urlencode 'startTime=2026-10-19T13:00:00.000Z' \
--data-urlencode 'endTime=2026-10-19T16:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
fingerprint: 'fpr_2a7e9c4b1d8f6e3a',
fpVersion: '1',
limit: '5',
startTime: '2026-10-19T13:00:00.000Z',
endTime: '2026-10-19T16:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/operations/examples?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { examples } = await response.json();
{
"sourceState": "ready",
"unit": "us",
"examples": [
{
"kind": "slowest",
"dt": "2026-10-19T14:21:07.418Z",
"requestDt": "2026-10-19T14:21:07.412Z",
"requestSid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
"spanSid": "spn_02",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"duration": 3995000,
"ok": false,
"errorClass": "timeout",
"statusCode": 504,
"endpoint": "/v1/payments/{payment_id}/capture",
"method": "POST",
"serviceVersion": "v2026.10.19",
"instanceSid": "ins_k8f2a1"
}
]
}
Rank endpoints
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/endpoints
Ranks endpoints (template and method) on the server. With direction=out, ranks the outbound calls your API makes.
Query parameters
-
startTime (query, string, required): Start of the range.
-
endTime (query, string, required): End of the range (exclusive).
-
orderBy (query, string, default total):
total,p95,p99,calls,error_rateorregression. -
direction (query, string, default in):
in(your API’s endpoints) orout(calls it makes). -
limit (query, integer, default 50): Endpoints to return, 1 to 100.
-
minCalls (query, number, default 20): As for Rank span operations.
-
pivotAt (query, string): As for Rank span operations.
-
minRelativeIncrease (query, number, default 0.1): As for Rank span operations.
Response
The common fields, orderBy, limit, minCalls, pivotAt, and:
- points (object[], required):
One entry per endpoint:
endpoint,method,calls,rows,total,avg,p50,p95,p99,max,errors,errorRate,clientErrors,lastSeen,latestVersionand, withregressionranking,regression.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/endpoints \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'orderBy=p95' \
--data-urlencode 'startTime=2026-10-19T00:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T00:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({ orderBy: 'p95', startTime: '2026-10-19T00:00:00.000Z', endTime: '2026-10-20T00:00:00.000Z' });
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/endpoints?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"sourceState": "ready",
"unit": "ms",
"orderBy": "p95",
"limit": 50,
"minCalls": 20,
"pivotAt": null,
"points": [
{
"endpoint": "/v1/payments/{payment_id}/capture",
"method": "POST",
"calls": 402,
"rows": 402,
"total": 246180,
"avg": 612.4,
"p50": 240,
"p95": 3980,
"p99": 4060,
"max": 4120,
"errors": 61,
"errorRate": 0.152,
"clientErrors": 0,
"lastSeen": "2026-10-19T23:57:40.000Z",
"latestVersion": "v2026.10.19"
}
]
}
Endpoint trend, heatmap, regression and examples
Four operations do for one endpoint what the operation versions above do for one span operation. Instead of fingerprint and fpVersion, they take:
-
endpoint (query, string, required): The endpoint template, for example
/v1/orders/{order_id}. -
method (query, string, required): The HTTP method.
-
direction (query, string, default in):
inorout.
Their other parameters and responses match the operation versions, without operation, statementText and dictionaryAvailable.
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/endpoints/trend
Like Span operation trend: p50, p95, p99, calls and errors over time.
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/endpoints/heatmap
Like Span operation heatmap.
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/endpoints/regression
Like Span operation regression, with pivotAt required.
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/endpoints/examples
Like Span operation examples: the slowest requests to the endpoint.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/endpoints/trend \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'endpoint=/v1/payments/{payment_id}/capture' \
--data-urlencode 'method=POST' \
--data-urlencode 'startTime=2026-10-19T13:00:00.000Z' \
--data-urlencode 'endTime=2026-10-19T16:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
endpoint: '/v1/payments/{payment_id}/capture',
method: 'POST',
startTime: '2026-10-19T13:00:00.000Z',
endTime: '2026-10-19T16:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/endpoints/trend?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"sourceState": "ready",
"unit": "ms",
"step": { "stepSeconds": 120, "fromSeconds": 1792414800, "toSeconds": 1792425600, "firstBucketPartial": false, "lastBucketPartial": false },
"points": [
{ "bucket": 1792418520, "calls": 4, "rows": 4, "errors": 3, "total": 15800, "p50": 3990, "p95": 4110, "p99": 4120 }
]
}
Rank regressions
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/regressions
Returns the operations or endpoints that got slower after a deploy time, ranked by regression score.
Query parameters
-
startTime (query, string, required): Start of the range.
-
endTime (query, string, required): End of the range (exclusive).
-
kind (query, string, default operation):
operationorendpoint. -
pivotAt (query, string): The deploy time. Defaults to the middle of the range.
-
direction (query, string, default in): With
kind=endpoint,inorout. -
endpoint (query, string): With
kind=operation, only operations run by this endpoint. -
types (query, string): With
kind=operation, only these span types (comma-separated). -
limit (query, integer, default 50): Results, 1 to 100.
-
minCalls (query, number, default 20): Ignore results with fewer estimated calls on either side.
-
minRelativeIncrease (query, number, default 0.1): The smallest p95 increase that counts.
Response
The common fields, orderBy, limit, minCalls, pivotAt, and points: entries shaped as in Rank span operations or Rank endpoints, each with regression.
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/regressions \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'kind=endpoint' \
--data-urlencode 'pivotAt=2026-10-19T10:00:00.000Z' \
--data-urlencode 'startTime=2026-10-18T10:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T10:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
kind: 'endpoint',
pivotAt: '2026-10-19T10:00:00.000Z',
startTime: '2026-10-18T10:00:00.000Z',
endTime: '2026-10-20T10:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/regressions?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"sourceState": "ready",
"unit": "ms",
"orderBy": "regression",
"limit": 50,
"minCalls": 20,
"pivotAt": "2026-10-19T10:00:00.000Z",
"points": [
{
"endpoint": "/v1/payments/{payment_id}/capture",
"method": "POST",
"calls": 402,
"p95": 3980,
"errorRate": 0.152,
"regression": {}
}
]
}
Rank dependencies
GET https://api.apitraffic.io/v1/accounts/{accountSid}/apm/analytics/dependencies
Ranks what your API depends on (databases, caches, HTTP APIs and queues) by peer or by target, with latency and the mix of error types.
Query parameters
-
startTime (query, string, required): Start of the range.
-
endTime (query, string, required): End of the range (exclusive).
-
granularity (query, string, default peer):
peer: one row per type, system, host and database.target: one row per table or outbound endpoint on it. -
orderBy (query, string, default total):
total,p95,calls,calls_per_requestorerror_rate. -
endpoint (query, string): Only dependencies of this inbound endpoint.
-
types (query, string): Only these span types (comma-separated).
-
limit (query, integer, default 50): Results, 1 to 100.
-
minCalls (query, number, default 20): For
calls_per_requestanderror_rateranking, ignore dependencies with fewer estimated calls.
Response
The common fields, and points: type, system, host, db, target, op, calls, rows, total, avg, p50, p95, p99, max, errors, errorRate, lastSeen, latestVersion, sampledRequests, callsPerRequest and errorClasses (errors by class).
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/apm/analytics/dependencies \
-H "Authorization: Bearer $APITRAFFIC_TOKEN" \
--data-urlencode 'types=http.out' \
--data-urlencode 'orderBy=error_rate' \
--data-urlencode 'startTime=2026-10-19T00:00:00.000Z' \
--data-urlencode 'endTime=2026-10-20T00:00:00.000Z'
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({
types: 'http.out',
orderBy: 'error_rate',
startTime: '2026-10-19T00:00:00.000Z',
endTime: '2026-10-20T00:00:00.000Z',
});
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/apm/analytics/dependencies?${params}`, {
headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { points } = await response.json();
{
"sourceState": "ready",
"unit": "us",
"orderBy": "error_rate",
"points": [
{
"type": "http.out",
"system": "http",
"host": "payments.acme-pay.example",
"db": "",
"target": "",
"op": "",
"calls": 1020,
"rows": 1020,
"total": 612000000,
"avg": 600000,
"p50": 210000,
"p95": 3990000,
"p99": 4010000,
"max": 4020000,
"errors": 61,
"errorRate": 0.0598,
"lastSeen": "2026-10-19T23:57:40.000Z",
"latestVersion": "v2026.10.19",
"sampledRequests": 1020,
"callsPerRequest": 1,
"errorClasses": { "timeout": 47, "5xx": 14 }
}
]
}
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
1000 |
A parameter is missing or invalid, for example limit above 1000. |
403 |
2221 |
The plan does not include APM. |
502 |
5105 |
The query failed. Retry. |
503 |
5102, 5103, 5104 |
Analytics are temporarily unavailable. Retry after Retry-After seconds. |
504 |
5101 |
The query took too long. Narrow the range and retry. |
Related
-
How APM works: What APM measures and how to read it.
-
Spans API: The operations behind the time split.