API Resources
Common Parameters
These parameters can be used for any of the resources, except for the search and esql endpoints.
| Parameter | Value | Description |
|---|---|---|
start_time | string (optional) | Define a start time in ISO-8601 format from which records will be queried. This applies to the created_at attribute of the record. |
end_time | string (optional) | Define an end time in ISO-8601 format up until which records will be queried. This applies to the created_at attribute of the record. |
measurement_id | string (optional) | A single measurement ID to query. Only for measurements, client_reports, network_requests, event_bundles, connection_detail_traces, and geolocation_traces resources. Note: overrides all other parameters |
client_uuid | string (optional) | Specify a client to query data from. Note: overrides any tags specified |
tags | array of string (optional) | Filter by client's tags. If multiple tags are specified, all of them must be assigned to the client. Use tags[]=foo&tags[]=bar as syntax for specifying multiple tags. Alternatively, use tags=foo,bar (comma-separated). Use separate queries for OR-like tag combinations. |
label | string (optional) | Filter by client's label. |
Time Format
Valid formats for start_time and end_time are, e.g.:
2023-05-17T12:36:13.000Z
20230517T12:36:13
2023-05-17 12:36:13 UTC
Internally, the Time.parse method parses the time strings. Any format that this method supports is valid.
Resources
Measurements
- Path:
/measurements - Method:
GET - Format: JSON
Gets a list of all measurements.
Return Value
An array of all measurements, where each measurement is an object, with optional nested objects. The schema for the data is available in our reference.
Parameters
| Parameter | Value | Description |
|---|---|---|
type | VideoMeasurement, WebMeasurement, NetworkMeasurement, SpeedtestMeasurement (optional) | Define a type of measurement to query. |
subject | array of string (optional) | Filter measurements by their subject as defined in the public config. |
study_id | array of string (optional) | Filter measurements by their study ID as defined in the public config. |
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/measurements?start_time=2024-01-01T00:00:00Z&type=VideoMeasurement"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/measurements?start_time=2024-01-01T00:00:00Z&type=VideoMeasurement",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const measurements = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/measurements",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"start_time": "2024-01-01T00:00:00Z",
"type": "VideoMeasurement",
},
)
measurements = response.json()
Client Reports
- Path:
/client_reports - Method:
GET - Format: JSON
Gets a list of all Client Reports.
Return Value
An array of all Client Reports, where each Client Report is an object, with optional nested objects. The schema for the data is available in our reference.
Parameters
| Parameter | Value | Description |
|---|---|---|
type | string (optional) | Define a type of Client Report to query. See the reference for a list of available types. Example: IcmpPingClientReport |
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/client_reports?type=IcmpPingClientReport&start_time=2024-01-01T00:00:00Z"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/client_reports?type=IcmpPingClientReport&start_time=2024-01-01T00:00:00Z",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const clientReports = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/client_reports",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"type": "IcmpPingClientReport",
"start_time": "2024-01-01T00:00:00Z",
},
)
client_reports = response.json()
Event Bundles
- Path:
/event_bundles - Method:
GET - Format: JSON
Gets a list of all event bundles.
Return Value
An array of all event bundles, where each event bundle is an object, with optional nested objects. The schema for the data is available in our reference.
Note that the type of the event bundle must be passed as a parameter.
Parameters
| Parameter | Value | Description |
|---|---|---|
type | VideoEventBundle, WebEventBundle | Define a type of event bundle to query. |
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/event_bundles?type=VideoEventBundle&start_time=2024-01-01T00:00:00Z"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/event_bundles?type=VideoEventBundle&start_time=2024-01-01T00:00:00Z",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const eventBundles = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/event_bundles",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"type": "VideoEventBundle",
"start_time": "2024-01-01T00:00:00Z",
},
)
event_bundles = response.json()
Network Requests
- Path:
/network_requests - Method:
GET - Format: JSON
Gets a list of all network requests.
Return Value
An array of all network requests, where each network request is an object. The schema for the data is:
| Property | Value | Description |
|---|---|---|
client_time | string (ISO 8601) | The time the request was made, as reported by the client |
client_time_skewed | string (ISO 8601) | The time the request was made, adjusted for any time skew |
data | object | The actual request data, structure depends on the request type, see requestWillBeSent. Fields available: requestId, loaderId, documentURL, timestamp, wallTime, type, frameId, request.url, request.method, request.headers |
network_response | object | The network response |
Note that request data is pruned to save space. In particular, the following properties are not included:
request.mixedContentTyperequest.initialPriorityrequest.referrerPolicyrequest.isSameSiteinitiatorredirectHasExtraInfohasUserGesture
Each network response corresponds to the following schema:
| Property | Value | Description |
|---|---|---|
client_time | string (ISO 8601) | The time the response was received by the client |
client_time_skewed | string (ISO 8601) | The time the response was received by the client, adjusted for any time skew |
data | object | The actual response data, structure depends on the request type, see responseReceived. Fields available: requestId, loaderId, timestamp, type, frameId, and all from response except securityState, securityDetails, alternateProtocolUsage. |
Again, note that response data is pruned to save space. We remove the following properties:
response.securityStateresponse.securityDetailsresponse.alternateProtocolUsagehasExtraInfo
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/network_requests?measurement_id=12345"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/network_requests?measurement_id=12345",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const networkRequests = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/network_requests",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"measurement_id": "12345",
},
)
network_requests = response.json()
Connection Detail Traces
- Path:
/connection_detail_traces - Method:
GET - Format: JSON
Gets a list of connection detail traces, where each trace bundles the connectivity samples (Wi-Fi, mobile network, signal strength, etc.) that the client recorded around a measurement.
A trace can be shared by more than one measurement when the same connectivity snapshot was reused. Filter with measurement_id to fetch only the trace(s) attached to a specific measurement.
Return Value
An array of connection detail traces. Each trace has the following schema:
| Property | Value | Description |
|---|---|---|
id | number | The trace ID. |
client_uuid | string | The UUID of the client that recorded the trace. |
created_at | string (ISO 8601) | When the trace was stored on the server. |
updated_at | string (ISO 8601) | When the trace was last updated. |
measurement_ids | array of number | The IDs of the measurements that reference this trace, restricted to your data owner and the current filter. |
connection_details | array of object | The individual connection detail samples that make up the trace. |
Each entry in connection_details corresponds to one connectivity sample and contains common fields such as type, client_time, client_time_skewed, mobile_network_type, ssid, rssi, signal_strength, plus a wide set of optional cellular fields (mcc, mnc, tac, pci, rsrp, rsrq, …).
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/connection_detail_traces?measurement_id=12345"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/connection_detail_traces?measurement_id=12345",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const connectionDetailTraces = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/connection_detail_traces",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"measurement_id": "12345",
},
)
connection_detail_traces = response.json()
Geolocation Traces
- Path:
/geolocation_traces - Method:
GET - Format: JSON
Gets a list of geolocation traces, where each trace bundles the geolocation samples (latitude/longitude with reverse-geocoded address fields) that the client recorded around a measurement.
A trace can be shared by more than one measurement. Filter with measurement_id to fetch only the trace(s) attached to a specific measurement.
Return Value
An array of geolocation traces. Each trace has the following schema:
| Property | Value | Description |
|---|---|---|
id | number | The trace ID. |
client_uuid | string | The UUID of the client that recorded the trace. |
created_at | string (ISO 8601) | When the trace was stored on the server. |
updated_at | string (ISO 8601) | When the trace was last updated. |
measurement_ids | array of number | The IDs of the measurements that reference this trace, restricted to your data owner and the current filter. |
geolocations | array of object | The individual geolocation samples that make up the trace. |
Each entry in geolocations contains latitude, longitude, accuracy, speed, client_time, client_time_skewed, and type. When the server has reverse-geocoded the sample, address fields (city, zip, region, country) are also returned.
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/geolocation_traces?measurement_id=12345"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/geolocation_traces?measurement_id=12345",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const geolocationTraces = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/geolocation_traces",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"measurement_id": "12345",
},
)
geolocation_traces = response.json()
Clients
- Path:
/clients - Method:
GET - Format: JSON
Gets a list of all clients.
Return Value
An array of all clients, where each client is an object, with optional nested objects. The schema for the data is:
| Property | Value | Description |
|---|---|---|
uuid | string | The client's UUID |
type | string | The client's type |
label | string | A label for the client (optional) |
created_at | string | The date when the client was created |
updated_at | string | The date when the client was updated |
disabled_at | string | The date when the client was disabled (optional) |
disabled_reason | string | The reason why the client was disabled (optional) |
tags | array of string | The tags assigned to the client (optional) |
extra_label | string | An extra label for the client (optional) |
registration_key | Registration Key | The registration key for the client |
Registration Key
| Property | Value | Description |
|---|---|---|
registration_key | string | The registration key for the client |
num_registrations_left | number | The number of registrations left for the key. -1 means unlimited uses |
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/clients?tags=production"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/clients?tags=production",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const clients = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/clients",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"tags": "production",
},
)
clients = response.json()
User Feedbacks
- Path:
/user_feedbacks - Method:
GET - Format: JSON
Gets a list of all user feedbacks.
Return Value
An array of all user feedbacks, where each user feedback is an object. The schema for the data is:
| Property | Value | Description |
|---|---|---|
id | number | The unique identifier for the user feedback |
client | object | The client associated with this feedback, with the object containing its uuid |
type | string | The type of user feedback |
data_type | string | The type of data stored in the feedback (typically "object") |
data | object | The actual feedback data, structure depends on the feedback type |
client_time | string (ISO 8601) | The time the feedback was submitted, as reported by the client |
client_time_skewed | string (ISO 8601) | The adjusted client time, accounting for any time skew |
created_at | string (ISO 8601) | The time the feedback was created in the database |
updated_at | string (ISO 8601) | The time the feedback was last updated in the database |
Note: The exact structure of the data object may vary depending on the specific type of user feedback.
Parameters
| Parameter | Value | Description |
|---|---|---|
type | string (optional) | Define a type of User Feedback to query. Available types depend on your specific application. |
Example
- curl
- Node.js
- Python
curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/user_feedbacks?start_time=2024-01-01T00:00:00Z"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/user_feedbacks?start_time=2024-01-01T00:00:00Z",
{
method: "GET",
headers: {
Accept: "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
}
);
const userFeedbacks = await response.json();
import requests
response = requests.get(
"https://surfmeter-server.<host>/export_api/v1/user_feedbacks",
headers={
"Accept": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={
"start_time": "2024-01-01T00:00:00Z",
},
)
user_feedbacks = response.json()
Search
- Path:
/search - Methods:
GET,POST - Format: JSON or NDJSON (for streaming responses)
Provides direct search capabilities against the analytics data using Elasticsearch queries. For more details, see the Elasticsearch documentation.
Parameters
The following parameters are supported by our own API in addition to the ones supported by Elasticsearch:
| Parameter | Value | Description |
|---|---|---|
body | object or string (required) | The Elasticsearch query body. Can be provided as a JSON-formatted string or object when sent as a POST request with Content-Type: application/json. For details about the Query DSL, see the introduction or the Query DSL Reference. |
scroll | string (optional) | Enable scrolling search with specified scroll timeout (e.g. "1m"). Returns results as streaming NDJSON. This corresponds to the scroll parameter in the Elasticsearch API. |
source_only | boolean (optional) | If true, returns only the source documents without Elasticsearch metadata. |
If you want to pass other parameters to the Elasticsearch API, you can do so by adding them to the object next to the body parameter, or as HTTP GET query parameters.
Return Value
The response format depends on the parameters:
- Default: Returns the complete Elasticsearch response including metadata as JSON
- With
source_only=true: Returns an array of source documents only, skipping the Elasticsearch metadata - With
scrollparameter: Streams results as NDJSON (one JSON document per line) withContent-Type: application/x-ndjson
Examples
Basic Search
A regular search query returning a single client's data. Note that for exact matches on text-based fields, you should use the .keyword suffix.
- curl
- Node.js
- Python
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"body": {
"query": {
"term": {
"client.label.keyword": "my-custom-label"
}
}
}
}' \
"https://surfmeter-server.<host>/export_api/v1/search"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/search",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
body: JSON.stringify({
body: {
query: {
term: {
"client.label.keyword": "my-custom-label",
},
},
},
}),
}
);
const results = await response.json();
import requests
response = requests.post(
"https://surfmeter-server.<host>/export_api/v1/search",
headers={
"Accept": "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
json={
"body": {
"query": {
"term": {
"client.label.keyword": "my-custom-label"
}
}
}
},
)
results = response.json()
Aggregation Query
Aggregate statistic_values.initial_loading_delay by hour for the last 30 days, for video measurements only:
- curl
- Node.js
- Python
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"body": {
"size": 0,
"query": {
"bool": {
"must": [
{ "range": { "created_at": { "gte": "now-30d/d", "lte": "now/d" } } },
{ "term": { "type.keyword": "VideoMeasurement" } }
]
}
},
"aggs": {
"loading_delay_over_time": {
"date_histogram": { "field": "created_at", "calendar_interval": "hour" },
"aggs": {
"avg_loading_delay": { "avg": { "field": "statistic_values.initial_loading_delay" } }
}
}
}
}
}' \
"https://surfmeter-server.<host>/export_api/v1/search"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/search",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
body: JSON.stringify({
body: {
size: 0,
query: {
bool: {
must: [
{ range: { created_at: { gte: "now-30d/d", lte: "now/d" } } },
{ term: { "type.keyword": "VideoMeasurement" } },
],
},
},
aggs: {
loading_delay_over_time: {
date_histogram: { field: "created_at", calendar_interval: "hour" },
aggs: {
avg_loading_delay: {
avg: { field: "statistic_values.initial_loading_delay" },
},
},
},
},
},
}),
}
);
const results = await response.json();
import requests
response = requests.post(
"https://surfmeter-server.<host>/export_api/v1/search",
headers={
"Accept": "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
json={
"body": {
"size": 0,
"query": {
"bool": {
"must": [
{"range": {"created_at": {"gte": "now-30d/d", "lte": "now/d"}}},
{"term": {"type.keyword": "VideoMeasurement"}},
]
}
},
"aggs": {
"loading_delay_over_time": {
"date_histogram": {"field": "created_at", "calendar_interval": "hour"},
"aggs": {
"avg_loading_delay": {
"avg": {"field": "statistic_values.initial_loading_delay"}
}
},
}
},
}
},
)
results = response.json()
Scrolling Search (Streaming)
Perform a scrolling search for all data. The scroll parameter is required and gives the scroll timeframe:
- curl
- Node.js
- Python
curl -X POST \
-H "Accept: application/x-ndjson" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{ "body": { "query": { "match_all": {} } } }' \
"https://surfmeter-server.<host>/export_api/v1/search?scroll=1m"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/search?scroll=1m",
{
method: "POST",
headers: {
Accept: "application/x-ndjson",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
body: JSON.stringify({
body: { query: { match_all: {} } },
}),
}
);
// Process NDJSON stream
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop();
for (const line of lines) {
if (line) console.log(JSON.parse(line));
}
}
import requests
import json
response = requests.post(
"https://surfmeter-server.<host>/export_api/v1/search?scroll=1m",
headers={
"Accept": "application/x-ndjson",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
json={"body": {"query": {"match_all": {}}}},
stream=True,
)
# Process NDJSON stream
for line in response.iter_lines():
if line:
doc = json.loads(line)
print(doc)
Lucene Query
Search with a simple Lucene query. The size parameter limits the number of results returned:
- curl
- Node.js
- Python
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{ "body": { "size": 1 } }' \
"https://surfmeter-server.<host>/export_api/v1/search?q=id:123"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/search?q=id:123",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
body: JSON.stringify({ body: { size: 1 } }),
}
);
const results = await response.json();
import requests
response = requests.post(
"https://surfmeter-server.<host>/export_api/v1/search",
headers={
"Accept": "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
params={"q": "id:123"},
json={"body": {"size": 1}},
)
results = response.json()
Player Errors
Player SDK sessions have an error_summary in the video measurement documents:
count: number of errorsfatal_count: number of fatal errors. A session that recovered from a fatal error still counts it.error_types,error_codes: error categories and raw error codes of the playersvta_codes: standardized SVTA2070 codes
To find sessions with a fatal error, use a range query on error_summary.fatal_count:
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{ "body": { "size": 10, "query": { "range": { "error_summary.fatal_count": { "gt": 0 } } } } }' \
"https://surfmeter-server.<host>/export_api/v1/search"
The errors themselves are in the error_events indices, one document per error. Read them with ES|QL, because the /search endpoint does not cover these indices. A document has measurement_id, client_uuid, media_time and these fields below error:
message,error_type: the error's message and categoryerror_code: the raw code of the playersvta_code: the SVTA2070 code as an integer, absent if the error is out of scope for the spec, such as a configuration error in the appfatal: whether the error is fatal. An error without this field is non-fatal.http_status: the HTTP status, only for HTTP failures. It is also part of the SVTA code: a 404 has the code 3404.
ESQL
- Path:
/esql - Methods:
GET,POST - Format: JSON
Provides direct query capabilities against the analytics data using Elasticsearch's ES|QL query language. For more details, see the ES|QL documentation.
Parameters
| Parameter | Value | Description |
|---|---|---|
query | string (required) | The query string. Must include a valid FROM clause that references your index or indices. |
Return Value
Returns an array of documents matching the query criteria.
Security Constraints
- The
FROMclause in your query must reference indices that start with your index patterns, typically:analytics-production-<customer>*where<customer>is your customer's name - If using
LOOKUP JOIN, the referenced indices must also be within your data owner's scope and must be known lookup indices ENRICHclauses are allowed but currently not supported
Examples
Filtering Records
Filter records by a specific field:
- curl
- Node.js
- Python
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"query": "FROM analytics-production-<customer>* | WHERE type = \"VideoMeasurement\" | LIMIT 10"
}' \
"https://surfmeter-server.<host>/export_api/v1/esql"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/esql",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
body: JSON.stringify({
query:
'FROM analytics-production-<customer>* | WHERE type = "VideoMeasurement" | LIMIT 10',
}),
}
);
const results = await response.json();
import requests
response = requests.post(
"https://surfmeter-server.<host>/export_api/v1/esql",
headers={
"Accept": "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
json={
"query": 'FROM analytics-production-<customer>* | WHERE type = "VideoMeasurement" | LIMIT 10'
},
)
results = response.json()
Aggregation with Grouping
Calculate average values with grouping:
- curl
- Node.js
- Python
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"query": "FROM analytics-production-<customer>* | WHERE type = \"VideoMeasurement\" | STATS avg_ild = avg(TO_DOUBLE(statistic_values.initial_loading_delay)) BY client_label | SORT client_label"
}' \
"https://surfmeter-server.<host>/export_api/v1/esql"
const response = await fetch(
"https://surfmeter-server.<host>/export_api/v1/esql",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
body: JSON.stringify({
query:
'FROM analytics-production-<customer>* | WHERE type = "VideoMeasurement" | STATS avg_ild = avg(TO_DOUBLE(statistic_values.initial_loading_delay)) BY client_label | SORT client_label',
}),
}
);
const results = await response.json();
import requests
response = requests.post(
"https://surfmeter-server.<host>/export_api/v1/esql",
headers={
"Accept": "application/json",
"Content-Type": "application/json",
"X-API-KEY": "YOUR_API_KEY",
},
json={
"query": 'FROM analytics-production-<customer>* | WHERE type = "VideoMeasurement" | STATS avg_ild = avg(TO_DOUBLE(statistic_values.initial_loading_delay)) BY client_label | SORT client_label'
},
)
results = response.json()
Fatal Player Errors
List fatal player errors of Player SDK sessions, with their raw and SVTA codes. See Player Errors for the fields.
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
-d '{
"query": "FROM analytics-production-<customer>-error_events-* | WHERE error.fatal == true | LIMIT 10 | KEEP measurement_id.keyword, error.error_code.keyword, error.svta_code, error.http_status"
}' \
"https://surfmeter-server.<host>/export_api/v1/esql"