GroundScore
Sign in
API Docs

GROUNDSCORE API · V1

Build with GroundScore

Pull AI visibility data into your dashboards. Subscribe to events. Automate your agency workflow.

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.

Treat a key like a password. It carries the full access of its scopes on your account. Keep it server-side, never in browser code or a public repository, and revoke it the moment you suspect it leaked.

Sample request

bash
curl -H "Authorization: Bearer gs_live_yourkeyhere" \
     https://app.groundscore.ai/api/v1/sites

Scopes

Scopes are stored as a comma-separated list on the key. Pick the narrowest set that covers your integration.

ScopeGrants
read:sitesList + read site metadata and latest-scan summary.
read:scansList scans for a site and read a single scan's full detail.
read:ai-monitorRead the latest completed AI Monitor run for a site (composite score + per-engine breakdown).
read:webhooksList active webhook subscriptions.
write:webhooksCreate 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

json
{
  "data": {
    "sites": [ /* … */ ]
  }
}

Error

json
{
  "error": {
    "code": "insufficient_scope",
    "message": "Required scope: read:scans"
  }
}

Error codes

CodeStatusWhen it happens
unauthorized401Missing or malformed Authorization header.
invalid_key401Key is unknown, revoked, or no longer active.
insufficient_scope403Key is valid but doesn't include the required scope for this endpoint.
not_found404Resource doesn't exist or isn't visible to this key's owner.
rate_limited429Too 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.

Most agency integrations stay well under the limit by pulling on a schedule (e.g. nightly) rather than polling. If your integration needs more headroom than that, get in touch and tell us the shape of the traffic.

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:

  1. Create a key in Settings with the scopes you need (start with read:sites and read:scans).
  2. Hit GET /api/v1/sites to list the sites tied to your account.
  3. For each site, hit GET /api/v1/sites/{siteId}/scans to pull the score history, or subscribe to scan.completed via the Webhooks API for push delivery.