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.
Name | Value |
---|---|
Endpoint | https://app.graphql-hive.com/usage |
Authorization Header | Authorization: Bearer token-here |
API version Header | X-Usage-API-Version: 2 |
Method | POST |
Content-Type Header | Content-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 Code | Meaning |
---|---|
200 | Usage data was successfully accepted. |
400 | Errors while processing the sent JSON body. |
401 | Invalid X-Usage-API-Version header provided. |
429 | Rate limited due to exceeding usage reporting quota. |
500 | An 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