How much the deployment was used since a time
const url = 'https://example.com/v1/license/usage?since=2026-04-15T12%3A00%3A00Z';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://example.com/v1/license/usage?since=2026-04-15T12%3A00%3A00Z' \ --header 'Authorization: Bearer <token>'What a free license key’s renewal carries (kindgi license renew --runtime): the runs started since since (not dry runs, replays, test runs or child runs), the distinct people who started runs or decided approvals (counted in each tenant and summed, so a person in two tenants counts twice), the projects in production when the runtime can put projects in production (PUT /v1/projects/{projectId}/production), and the runtime’s version. Counts only: no content, names or ids. Only the deployment’s own token (KINDGI_API_TOKEN), or a system key holding system:license, reads it; anyone else is refused (license-operator-only), and the refusal recorded, before since is read. A deployment that doesn’t report it answers 404.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”The period’s start (ISO 8601, with a zone): kindgi license renew sends when the current key was issued. Up to five minutes ahead of the runtime’s clock is taken as now, since clocks differ; further ahead is refused.
Responses
Section titled “Responses”The counts.
object
The period’s start, as asked.
When they were counted.
The runtime’s version.
Runs started in the period: not dry runs, replays, test runs or child runs.
Distinct people who started runs or decided approvals in the period, counted in each tenant and summed.
Projects in production at until; absent when the runtime has no such setting.
Examplegenerated
{ "since": "2026-04-15T12:00:00Z", "until": "2026-04-15T12:00:00Z", "runtimeVersion": "example", "runs": 1, "people": 1, "projectsInProduction": 1}since is missing, not a time with a zone, or more than five minutes ahead of the runtime’s clock (bad-input).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Missing / malformed / expired / revoked bearer token.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Not the deployment’s own token or a system key holding system:license (license-operator-only). On a runtime serving one tenant, a system key holding anything but system:license (system-key-scope-not-served).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}The database was too busy to answer in time (database-busy); Retry-After (whole seconds) says when to try again.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}