List the rows a query matched
The rows behind an explore query, newest first unless sort says otherwise, each with a title, the dashboard page it opens, and one value per field. Takes the same body as POST /analytics/explore; filters, when and the window apply, while measure, groupBy and bucket are ignored.
POST
/analytics/recordsAuthorization
AuthorizationBearer token · headerrequired`MEDIAN_KEY` from Settings under API, or an MCP OAuth access token. A key acts as the organization; a token acts as the person who approved it.
Request body
requiredapplication/jsonqueryobjectrequiredShow propertiesHide properties
datasetstringrequiredAllowed:
conversationsratingssignalslogsknowledgeDocsknowledgeSuggestionstoolRequeststoolRunscustomerstasksusageEventsmessagesmeasureobjectShow propertiesHide properties
opstringrequiredcount takes no field. distinct reads an id, string or enum field. percent takes no field but a `where` filter, and gives the share of matched rows passing it, 0 to 100. The rest read a number or duration field.
Allowed:
countdistinctsumavgmedianp75p90p95p99minmaxpercentfieldstring | nullThe field id the measure reads.
whereobjectpercent only: the condition to count the share of. Same shape as a filter.
Show propertiesHide properties
fieldstringrequiredopstringrequiredvalueanyfiltersobject[]Rows have to pass every filter, or any one with `match: "any"`. Enum values are their ids, booleans are true or false, durations are milliseconds. isSet and isNotSet take no value; in and notIn take a list of up to 50.
Show propertiesHide properties
Array of
objectfieldstringrequiredopstringrequiredAllowed:
isisNotgtgteltltecontainsnotContainsinnotInisSetisNotSetvaluestring | number | boolean | string | number | boolean[]Show propertiesHide properties
One of:
string
stringnumber
numberboolean
booleanstring | number | boolean[]
Array of
string | number | booleanOne of:
string
stringnumber
numberboolean
booleanmatchstringall (the default) lets a row through when it passes every filter, any when it passes one.
Allowed:
allanygroupBystring | nullA field id to split the rows into series by. Rows with nothing in the field land in `__none`.
topintegerHow many groups keep their name. The rest fold into `__other`, which takes one of the places.
min 1 · max 20 · default: 8
orderstringnatural keeps the field's own order (most rows first for free text). largest or smallest ranks the groups by the measure, and the ranking picks which keep their name.
default: "natural"
Allowed:
naturallargestsmallestotherbooleanfalse leaves the groups past `top` off instead of folding them into `__other`. The total then covers only the groups returned.
default: true
bucketstring | nullThe x axis. day, week and month cut the window up and need the range scope; hour and weekday fold every row onto one clock.
Allowed:
dayweekmonthhourweekdaywhenobjectShow propertiesHide properties
fieldstringWhich of the dataset's time fields places a row. The dataset's first by default.
scopestringrange for rows inside the window, all for every row on file. Default range.
Allowed:
rangeallcomparebooleanAlso measure the same number of days just before the window, returned as `previous`. Ignored with the all scope.
default: false
daysintegerHow far back the window reaches, counted from the UTC midnight before now. Default 30.
min 1 · max 366
fromintegerThe window's start, unix ms, in place of counting back.
limitintegerHow many rows to return.
min 1 · max 200 · default: 50
sortobjectThe order of the rows. Rows with nothing in the field go last either way.
Show propertiesHide properties
bystringrequired`time` for the moment the query placed each row at, or a field id.
directionstringdefault: "desc"
Allowed:
descascfieldsstring[]Which field ids each row reads out, in this order. All of them by default.
Responses
200The matched rows.
okbooleanfieldsstring[]rowsobject[]Show propertiesHide properties
Array of
objectidstringatnumbertitlestringhrefstring | nullvaluesany[]matchedintegerscannedintegercappedboolean400The request is malformed, and the message names the field.
errorobjectShow propertiesHide properties
codestringmessagestring401The bearer token is missing, revoked, or expired.
errorobjectShow propertiesHide properties
codestringmessagestring429Too many requests. Wait the seconds in `Retry-After`. Limits depend on the plan. See [rate limits](/api/errors-and-limits#rate-limits).
errorobjectShow propertiesHide properties
codestringmessagestringRequest
curl -X POST "https://api.median.sh/v1/analytics/records" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": {
"dataset": "conversations",
"measure": {
"op": "count",
"field": "string",
"where": {
"field": "string",
"op": "string",
"value": "string"
}
},
"filters": [
{
"field": "string",
"op": "is",
"value": "string"
}
],
"match": "all",
"groupBy": "string",
"top": 8,
"order": "natural",
"other": true,
"bucket": "day",
"when": {
"field": "string",
"scope": "range"
},
"compare": false
},
"days": 0,
"from": 0,
"limit": 50,
"sort": {
"by": "string",
"direction": "desc"
},
"fields": [
"string"
]
}'const response = await fetch("https://api.median.sh/v1/analytics/records", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
"query": {
"dataset": "conversations",
"measure": {
"op": "count",
"field": "string",
"where": {
"field": "string",
"op": "string",
"value": "string"
}
},
"filters": [
{
"field": "string",
"op": "is",
"value": "string"
}
],
"match": "all",
"groupBy": "string",
"top": 8,
"order": "natural",
"other": true,
"bucket": "day",
"when": {
"field": "string",
"scope": "range"
},
"compare": false
},
"days": 0,
"from": 0,
"limit": 50,
"sort": {
"by": "string",
"direction": "desc"
},
"fields": [
"string"
]
})
});Response
{
"ok": true,
"fields": [
"string"
],
"rows": [
{
"id": "string",
"at": 0,
"title": "string",
"href": "string",
"values": [
"string"
]
}
],
"matched": 0,
"scanned": 0,
"capped": true
}{
"error": {
"code": "string",
"message": "string"
}
}{
"error": {
"code": "string",
"message": "string"
}
}{
"error": {
"code": "string",
"message": "string"
}
}