AuthenticationValidate API Key

Validate API Key

Confirm credentials and inspect the caller's access scope, teams, and rate-limit state.

curl --request GET \
  --url https://api.aiclicks.io/api/v1/validate \
  --header 'Authorization: Bearer ak_live_xxx'
{
  "data": {
    "valid": true,
    "key_type": "api_key",
    "key": {
      "id": "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3",
      "name": "Production exports",
      "created_at": "2026-02-14T10:11:02.318Z"
    },
    "user_id": "f1b9e2d4-3a4b-4f1d-9b9c-12b9c0e5d2a4",
    "teams": [
      {
        "id": "1be5a7d4-0c8b-4f1d-9b9c-12b9c0e5d2a4",
        "name": "Acme",
        "developer_access": true,
        "domains_count": 3
      }
    ],
    "allowed_domains": [
      {
        "id": "21c1f9aa-9b6d-4e3a-8a31-2b0c0e1f2a3b",
        "name": "Acme Inc.",
        "website": "acme.com"
      },
      {
        "id": "32d2e8bb-aa7e-5f4b-9b42-3c1d1f2a3b4c",
        "name": "Acme Labs",
        "website": "labs.acme.com"
      }
    ],
    "rate_limit": {
      "limit_per_minute": 60,
      "remaining": 58,
      "reset_at": 1718531412
    }
  },
  "generated_at": "2026-06-16T08:00:11.218Z"
}

Use this endpoint to verify that an API key (or JWT) is live, see which teams and domains it can reach, and read the current rate-limit window in one round trip. It is intentionally cheap and never cached — call it on startup, on key rotation, or whenever a downstream 401/403 needs explanation.

For an API-key caller, the response is scoped to the key's team. For a JWT caller, it spans every team the user belongs to. Teams without Developer Access appear in the teams list (so you can surface them in UI), but their domains_count is forced to 0.

Authorizations

header
Authorizationstring
Required

Your API key formatted as Bearer ak_live_<your-key>, or a Bearer JWT from the dashboard session. Create keys in the dashboard under Settings → Developers.

header
X-Request-Idstring

Optional UUID for log correlation. If omitted, we generate one and echo it back in the response.

Query parameters

This endpoint takes no query parameters.

Response

dataobject
Required

The validation payload.

data.validboolean
Required

Always true on a 200. Authentication failures return 401 with detail instead — there is no valid: false body.

data.key_typestring
Required

One of api_key or jwt. Useful for surfacing the auth method back in dashboards or audit logs.

data.keyobject

Present only for api_key callers. null for JWT.

data.user_idstring
Required

UUID of the user that owns this key (or the JWT subject).

data.teamsarray
Required

Every team this caller is a member of (scoped to the key's team for api_key callers).

data.allowed_domainsarray

Flat list of domains the caller can access across all teams. null means unrestricted — the caller can access every domain on every developer-enabled team. An empty array means the caller has access to zero domains.

data.rate_limitobject
Required

Current rate-limit state for this caller. remaining and reset_at are null for JWT callers (rate limiting only applies to API keys).

generated_atstring
Required

ISO-8601 timestamp of when the server produced this response.

Response headers

HeaderDescription
X-CacheAlways BYPASS — this endpoint never caches.
X-Request-IdUnique request id. Echoes incoming if you set one.
X-RateLimit-LimitMax requests per minute for this key.
X-RateLimit-RemainingRequests remaining in current minute.
X-RateLimit-ResetUnix epoch seconds when the window resets.

Caching

This endpoint is never cached. Every call reads the key, the team list, and the current rate-limit bucket live — use it freely on startup and on every key rotation.

Errors

401 Unauthorizederror

Missing, malformed, or revoked API key. The response body is { "detail": "..." }; there is no valid: false envelope.

429 Too Many Requestserror

Rate limit exceeded. Inspect the Retry-After header for how long to wait, then call again.

Notes

  • A 200 with developer_access: false on every team and allowed_domains: [] means the key is structurally valid but cannot read any data. Surface this to the user as "API access not enabled — contact support@aiclicks.io" rather than as an auth failure.
  • For JWT callers, rate_limit.remaining and rate_limit.reset_at are null because rate limiting is keyed off the ak_ token, not the session.
  • allowed_domains is the union across teams post-allowlist. If you need the per-team breakdown, call GET /api/v1/domains — it returns the same domains with their team association.