Skip to main content

API Resources

Common Parameters​

These parameters can be used for any of the resources, except for the search and esql endpoints.

ParameterValueDescription
start_timestring (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_timestring (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_idstring (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_uuidstring (optional)Specify a client to query data from. Note: overrides any tags specified
tagsarray 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.
labelstring (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​

ParameterValueDescription
typeVideoMeasurement, WebMeasurement, NetworkMeasurement, SpeedtestMeasurement (optional)Define a type of measurement to query.
subjectarray of string (optional)Filter measurements by their subject as defined in the public config.
study_idarray of string (optional)Filter measurements by their study ID as defined in the public config.

Example​

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"

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​

ParameterValueDescription
typestring (optional)Define a type of Client Report to query. See the reference for a list of available types. Example: IcmpPingClientReport

Example​

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"

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​

ParameterValueDescription
typeVideoEventBundle, WebEventBundleDefine a type of event bundle to query.

Example​

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"

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:

PropertyValueDescription
client_timestring (ISO 8601)The time the request was made, as reported by the client
client_time_skewedstring (ISO 8601)The time the request was made, adjusted for any time skew
dataobjectThe 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_responseobjectThe network response

Note that request data is pruned to save space. In particular, the following properties are not included:

  • request.mixedContentType
  • request.initialPriority
  • request.referrerPolicy
  • request.isSameSite
  • initiator
  • redirectHasExtraInfo
  • hasUserGesture

Each network response corresponds to the following schema:

PropertyValueDescription
client_timestring (ISO 8601)The time the response was received by the client
client_time_skewedstring (ISO 8601)The time the response was received by the client, adjusted for any time skew
dataobjectThe 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.securityState
  • response.securityDetails
  • response.alternateProtocolUsage
  • hasExtraInfo

Example​

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"

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:

PropertyValueDescription
idnumberThe trace ID.
client_uuidstringThe UUID of the client that recorded the trace.
created_atstring (ISO 8601)When the trace was stored on the server.
updated_atstring (ISO 8601)When the trace was last updated.
measurement_idsarray of numberThe IDs of the measurements that reference this trace, restricted to your data owner and the current filter.
connection_detailsarray of objectThe 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 -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"

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:

PropertyValueDescription
idnumberThe trace ID.
client_uuidstringThe UUID of the client that recorded the trace.
created_atstring (ISO 8601)When the trace was stored on the server.
updated_atstring (ISO 8601)When the trace was last updated.
measurement_idsarray of numberThe IDs of the measurements that reference this trace, restricted to your data owner and the current filter.
geolocationsarray of objectThe 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 -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"

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:

PropertyValueDescription
uuidstringThe client's UUID
typestringThe client's type
labelstringA label for the client (optional)
created_atstringThe date when the client was created
updated_atstringThe date when the client was updated
disabled_atstringThe date when the client was disabled (optional)
disabled_reasonstringThe reason why the client was disabled (optional)
tagsarray of stringThe tags assigned to the client (optional)
extra_labelstringAn extra label for the client (optional)
registration_keyRegistration KeyThe registration key for the client
Registration Key​
PropertyValueDescription
registration_keystringThe registration key for the client
num_registrations_leftnumberThe number of registrations left for the key. -1 means unlimited uses

Example​

curl -X GET \
-H "Accept: application/json" \
-H "X-API-KEY: YOUR_API_KEY" \
"https://surfmeter-server.<host>/export_api/v1/clients?tags=production"

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:

PropertyValueDescription
idnumberThe unique identifier for the user feedback
clientobjectThe client associated with this feedback, with the object containing its uuid
typestringThe type of user feedback
data_typestringThe type of data stored in the feedback (typically "object")
dataobjectThe actual feedback data, structure depends on the feedback type
client_timestring (ISO 8601)The time the feedback was submitted, as reported by the client
client_time_skewedstring (ISO 8601)The adjusted client time, accounting for any time skew
created_atstring (ISO 8601)The time the feedback was created in the database
updated_atstring (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​

ParameterValueDescription
typestring (optional)Define a type of User Feedback to query. Available types depend on your specific application.

Example​

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"
  • 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:

ParameterValueDescription
bodyobject 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.
scrollstring (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_onlyboolean (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 scroll parameter: Streams results as NDJSON (one JSON document per line) with Content-Type: application/x-ndjson

Examples​

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 -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"
Aggregation Query​

Aggregate statistic_values.initial_loading_delay by hour for the last 30 days, for video measurements only:

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"
Scrolling Search (Streaming)​

Perform a scrolling search for all data. The scroll parameter is required and gives the scroll timeframe:

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"
Lucene Query​

Search with a simple Lucene query. The size parameter limits the number of results returned:

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"

Player Errors​

Player SDK sessions have an error_summary in the video measurement documents:

  • count: number of errors
  • fatal_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 player
  • svta_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 category
  • error_code: the raw code of the player
  • svta_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 app
  • fatal: 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​

ParameterValueDescription
querystring (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 FROM clause 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
  • ENRICH clauses are allowed but currently not supported

Examples​

Filtering Records​

Filter records by a specific field:

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"
Aggregation with Grouping​

Calculate average values with grouping:

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"
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"