Skip to content

Authentication

C.O.S. API v1

All C.O.S. API requests (except /v1/health and /v1/version) require a valid API key passed as a Bearer token.


Request format

Authorization: Bearer cos_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678901234567

The header name is Authorization. The scheme is Bearer. The value is your full API key including the cos_live_ prefix.


Key format

Field Value
Production prefix cos_live_
Test prefix cos_test_
Total length 57 characters including prefix (9-char prefix + 48-char random suffix)
Format cos_live_ (9 chars) + 48 random alphanumeric characters

Both cos_live_ and cos_test_ keys are registered with GitHub secret scanning. If either prefix is committed to a public repository, the exposure is detected automatically and you will be notified.


Key scope

Standard key. A key issued for a regular organisation can only access that organisation's own resources:

  • GET /v1/organisations/{org_id} — own org only
  • PUT/PATCH /v1/organisations/{org_id} — own org only
  • GET /v1/organisations/{org_id}/members — own org only
  • GET/POST/DELETE /v1/organisations/{org_id}/api-keys/... — own org only
  • GET /v1/organisations — returns 403 Forbidden (platform key required)
  • POST /v1/organisations — returns 403 Forbidden (platform key required)

Platform key. A key issued for a platform organisation (is_system: true) grants cross-tenant admin access to all of the above. Platform keys are used by C.O.S. operators only and are not issued to tenants.


Getting a key

During Phase 59, API keys are issued by the C.O.S. FOUNDER/administrator. Self-service key issuance opens in a future release.

When a key is issued via POST /v1/organisations/{org_id}/api-keys, the response includes the full raw key in the key field:

{
  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "key": "cos_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678901234567",
  "key_prefix": "cos_live_aBcD",
  "label": "Production integration",
  "is_active": true,
  ...
}

The raw key is shown once only. It cannot be retrieved after the issuance response. Store it immediately in a secrets manager (e.g. HashiCorp Vault, AWS Secrets Manager, or an equivalent).

Only the key_prefix (first 12 characters) is stored by C.O.S. and returned in subsequent list and get responses. Use it to identify a key without exposing the secret.


Quick test

# Replace with your actual key and org UUID
curl -s \
  -H "Authorization: Bearer cos_live_your_key_here" \
  https://cosprotocol.io/v1/organisations/your-org-uuid

A valid key returns 200 with your organisation profile.
A missing or malformed key returns 401:

{
  "error": "UNAUTHORIZED",
  "message": "Missing or invalid API key",
  "details": []
}

A valid key used against a different organisation (or an admin-only endpoint) returns 403:

{
  "error": "FORBIDDEN",
  "message": "This operation requires a platform-org API key",
  "details": []
}

Revoking a key

Revoke a key permanently with:

curl -s -X DELETE \
  -H "Authorization: Bearer $COS_API_KEY" \
  https://cosprotocol.io/v1/organisations/$ORG_ID/api-keys/$KEY_ID

Returns 204 No Content on success. Revocation is permanent — the key is immediately rejected at authentication and the record is retained for audit.

A governance event (api_key_revoked) is written to the C.O.S. audit log on every revocation.


Key lifecycle summary

Issue  →  Active  →  Revoked  (permanent)
                 ↘  Expired   (if expires_at set)

Revoked and expired keys return 401 Unauthorized on any authenticated request. Revocation status is visible in the is_active field of the key record.