Authentication
Every request to /api/v1/* must include a bearer token in the Authorization header. Keys are tied to a specific user account and a set of scopes; requests outside the granted scopes return 403 insufficient_scope.
Getting an API key
Open Settings in your GroundScore account and create a key under API keys. Give it a name you will recognize later, and grant only the scopes your integration needs.
The full key is shown once, at the moment you create it. GroundScore stores only a hash of it, so it cannot be displayed again. Copy it into your secret store straight away. If you lose it, revoke the key and create another.
Live keys start with gs_live_. Settings lists the first 12 characters of each key, along with when it was created and when it was last used, so you can tell keys apart without exposing them.
Sample request
Scopes
Scopes are stored as a comma-separated list on the key. Pick the narrowest set that covers your integration.
| Scope | Grants |
|---|---|
read:sites | List + read site metadata and latest-scan summary. |
read:scans | List scans for a site and read a single scan's full detail. |
read:ai-monitor | Read the latest completed AI Monitor run for a site (composite score + per-engine breakdown). |
read:webhooks | List active webhook subscriptions. |
write:webhooks | Create and revoke webhook subscriptions. |
There is no wildcard option. Settings grants scopes explicitly, one by one, so a key never carries access its integration was not built to need.
Response envelope
Every successful response wraps its payload in data. Every handled error uses an error object with a stable machine-readable code and a human-readable message.
Success
Error
Error codes
| Code | Status | When it happens |
|---|---|---|
unauthorized | 401 | Missing or malformed Authorization header. |
invalid_key | 401 | Key is unknown, revoked, or no longer active. |
insufficient_scope | 403 | Key is valid but doesn't include the required scope for this endpoint. |
not_found | 404 | Resource doesn't exist or isn't visible to this key's owner. |
rate_limited | 429 | Too many requests. Slow down (see Rate limits below). |
An unexpected server error returns a 5xx status without the error envelope above. Treat any 5xx as retryable with backoff, and do not depend on a machine-readable code being present on those responses.
Rate limits
Each API key is limited to 60 requests per minute. Exceeding that returns 429 rate_limited with a Retry-After: 60 header indicating the seconds to wait before the next request.
Versioning
Every endpoint lives under /api/v1/. We treat the v1 contract as stable: additive changes only (new optional fields, new endpoints).
Breaking changes ship at /api/v2/. When a v2 is published, v1 remains available for 12 months afterward so integrations have time to migrate.
Getting started
Three steps to your first GroundScore-powered dashboard:
- Create a key in Settings with the scopes you need (start with
read:sitesandread:scans). - Hit
GET /api/v1/sitesto list the sites tied to your account. - For each site, hit
GET /api/v1/sites/{siteId}/scansto pull the score history, or subscribe toscan.completedvia the Webhooks API for push delivery.