Skip to Content

Usage Reporting

The official JavaScript Hive Client (@graphql-hive/core) collects executed operations and sends them in batches (as a single report, when a buffer is full or every few seconds) over HTTP.

It’s recommended to send a report for more than 1 operation. The maximum payload size is 1 MB.

NameValue
Endpointhttps://app.graphql-hive.com/usage
Authorization HeaderAuthorization: Bearer token-here
API version HeaderX-Usage-API-Version: 2
MethodPOST
Content-Type HeaderContent-Type: application/json

JSON Body structure

TypeScript schema
export interface Report { size: number map: { [k: string]: OperationMapRecord } operations?: RequestOperation[] subscriptionOperations?: SubscriptionOperation[] } export interface OperationMapRecord { operation: string operationName?: string /** * @minItems 1 */ fields: [string, ...string[]] } export interface RequestOperation { timestamp: number operationMapKey: string execution: Execution metadata?: Metadata persistedDocumentHash?: string } export interface Execution { ok: boolean duration: number errorsTotal: number } export interface SubscriptionOperation { timestamp: number operationMapKey: string metadata?: Metadata } export interface Client { name: string version: string } export interface Metadata { client?: Client }
JSON Schema
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Report", "additionalProperties": false, "type": "object", "properties": { "size": { "type": "integer" }, "map": { "type": "object", "patternProperties": { "^(.*)$": { "title": "OperationMapRecord", "additionalProperties": false, "type": "object", "properties": { "operation": { "type": "string" }, "operationName": { "type": "string" }, "fields": { "minItems": 1, "type": "array", "items": { "type": "string" } } }, "required": [ "operation", "fields" ] } } }, "operations": { "type": "array", "items": { "title": "RequestOperation", "additionalProperties": false, "type": "object", "properties": { "timestamp": { "type": "integer" }, "operationMapKey": { "type": "string" }, "execution": { "title": "Execution", "additionalProperties": false, "type": "object", "properties": { "ok": { "type": "boolean" }, "duration": { "type": "integer" }, "errorsTotal": { "type": "integer" } }, "required": [ "ok", "duration", "errorsTotal" ] }, "metadata": { "title": "Metadata", "additionalProperties": false, "type": "object", "properties": { "client": { "title": "Client", "additionalProperties": false, "type": "object", "properties": { "name": { "type": "string" }, "version": { "type": "string" } }, "required": [ "name", "version" ] } } }, "persistedDocumentHash": { "type": "string", "title": "PersistedDocumentHash", "pattern": "^[a-zA-Z0-9_-]{1,64}~[a-zA-Z0-9._-]{1,64}~([A-Za-z]|[0-9]|_){1,128}$" } }, "required": [ "timestamp", "operationMapKey", "execution" ] } }, "subscriptionOperations": { "type": "array", "items": { "title": "SubscriptionOperation", "additionalProperties": false, "type": "object", "properties": { "timestamp": { "type": "integer" }, "operationMapKey": { "type": "string" }, "metadata": { "title": "Metadata", "additionalProperties": false, "type": "object", "properties": { "client": { "title": "Client", "additionalProperties": false, "type": "object", "properties": { "name": { "type": "string" }, "version": { "type": "string" } }, "required": [ "name", "version" ] } } } }, "required": [ "timestamp", "operationMapKey" ] } } }, "required": [ "size", "map" ] }

Raw JSON Example Payload

{ "size": 3, "map": { "c3b6d9b0": { "operationName": "me", "operation": "query me { me { id name } }", "fields": ["Query", "Query.me", "User", "User.id", "User.name"] }, "762a45e3": { "operationName": "users", "operation": "query users { users { id } }", "fields": ["Query", "Query.users", "User", "User.id"] }, "12f3712a": { "operationName": "liveCoordinates", "operation": "subscription liveCoordinates { location { x y } }", "fields": [ "Subscription", "Subscription.location", "User", "Location", "Location.x", "Location.y" ] } }, "operations": [ { "operationMapKey": "c3b6d9b0", // points to the 'me' query "timestamp": 1663158676535, // must be within retention period of use plan (free/Pro/enterprise) "execution": { "ok": true, "duration": 150000000, // 150ms in nanoseconds "errorsTotal": 0 }, "metadata": { "client": { "name": "demo", "version": "0.0.1" } } }, { "operationMapKey": "c3b6d9b0", // points to the 'me' query "timestamp": 1663158676589, "execution": { "ok": false, // failed operation "duration": 150000000, // 150ms in nanoseconds "errorsTotal": 1 // 1 GraphQL error }, "metadata": { "client": { "name": "demo", "version": "0.0.1" } } }, { "operationMapKey": "762a45e3", // points to the 'users' query "timestamp": 1663158676589, "execution": { "ok": true, "duration": 150000000, // 150ms in nanoseconds "errorsTotal": 0 }, "metadata": { "client": { "name": "demo", "version": "0.0.1" } } } ], "subscriptionOperations": [ { "operationMapKey": "12f3712a", // points to the 'users' query "timestamp": 1663158676589, "metadata": { "client": { "name": "demo", "version": "0.0.1" } } } ] }

curl example request

curl -X POST \ https://app.graphql-hive.com/usage \ -H 'Authorization: Bearer token-here' \ -H 'X-Usage-API-Version: 2' \ -H 'content-type: application/json' \ -d '{ "size": 1, "map": { "aaa": { "operationName": "me", "operation": "query me { me { id } }", "fields": ["Query", "Query.me", "User", "User.id"] } }, "operations": [{ "operationMapKey" : "c3b6d9b0", "timestamp" : 1663158676535, "execution" : { "ok" : true, "duration" : 150000000, "errorsTotal" : 0 }, "metadata" : { "client" : { "name" : "demo" , "version" : "0.0.1" } } } ] }'

Response

Status CodeMeaning
200Usage data was successfully accepted.
400Errors while processing the sent JSON body.
401Invalid X-Usage-API-Version header provided.
429Rate limited due to exceeding usage reporting quota.
500An unexpected error occured.

The endpoint will return a JSON body response body for 200 and 400 status codes.

200 Status Body

Response 200
{ "id": "c6ba1f9c-44c0-40a1-8089-65f7e4de5de5", "operations": { "accepted": 20, "rejected": 0 } }

400 Status Body

A response with status 400 indicates that the report sent within the request body is not valid. The response body will contain a JSON Schema validation errors that can be used to debug the faulty request body.

Response 400
{ "errors": [ { "message": "Expected union value", "path": "/operations", "errors": [ { "message": "Expected valid unix timestamp in milliseconds", "path": "/operations/0/timestamp" }, { "message": "Expected integer to be greater or equal to 0", "path": "/operations/0/execution/duration" }, { "message": "Expected null", "path": "/operations" } ] } ] }
Last updated on