Authentication and scopes
Every request to the External API is authenticated with an API key sent in the
X-API-Key header.
curl -sS https://api.claytonpower.com/api/v1/external/systems \ -H "X-API-Key: cp_live_Ab3xK9pQ2vNmR7sT4uW1yZ0cD6eF8gH5jL3nP7qS9tU"There is no other scheme. An Authorization: Bearer token from one of the Clayton
Power apps is not accepted on /api/v1/external/* and is answered with 401.
Key format
Section titled “Key format”cp_live_Ab3xK9pQ2vNmR7sT4uW1yZ0cD6eF8gH5jL3nP7qS9tU└──┬───┘└─────────────────────┬────────────────────┘ prefix 43 characters, base64urlA key is the literal prefix cp_live_ followed by 43 base64url characters encoding
32 cryptographically random bytes. Treat the whole string as opaque and compare it
byte for byte; do not trim, lowercase or re-encode it.
The first 12 characters (for example cp_live_Ab3x) are stored and shown in the key
list so you can tell your keys apart. The rest is stored only as a SHA-256 hash.
A key is displayed exactly once, at creation. There is no endpoint and no support procedure that can reveal it again.
Scopes
Section titled “Scopes”A key carries one or more scopes, chosen when it is created. A scope is a permission
to call a group of endpoints; a key without the right scope gets 403, even for its
own company’s data.
| Scope | Grants |
|---|---|
systems:read |
List systems and read a single system |
telemetry:read |
Latest snapshot, energy series, state-of-charge series, health |
alerts:read |
List and read alerts, read a system’s alert settings |
alerts:manage |
Change a system’s alert settings |
webhooks:manage |
Create, read, update and delete webhook subscriptions, rotate a secret, send a test event, read deliveries |
Per endpoint:
| Endpoint | Scope |
|---|---|
GET /systems |
systems:read |
GET /systems/{serialNumber} |
systems:read |
GET /systems/{serialNumber}/telemetry/latest |
telemetry:read |
GET /systems/{serialNumber}/telemetry/energy |
telemetry:read |
GET /systems/{serialNumber}/telemetry/soc |
telemetry:read |
GET /systems/{serialNumber}/health |
telemetry:read |
GET /alerts, GET /alerts/{id} |
alerts:read |
GET /systems/{serialNumber}/alert-settings |
alerts:read |
PUT /systems/{serialNumber}/alert-settings |
alerts:manage |
| `GET | POST |
Grant the narrowest set that does the job. A read-only reporting integration wants
systems:read and telemetry:read and nothing else.
Scopes are fixed for the life of a key. To change them, create a new key with the scopes you want and revoke the old one.
Company reach
Section titled “Company reach”A key belongs to one company and sees only that company’s systems. There is no cross-company or distributor key in v1.
A serial number that belongs to another company is answered with 404, exactly as an
invented serial number is. This is deliberate: a 403 would confirm that the serial
exists, which would let anyone with a key enumerate the fleet.
Expiry, revocation and rotation
Section titled “Expiry, revocation and rotation”Expiry is optional and set at creation. After the expiry moment the key is
rejected with 401.
Revocation is immediate. Revoke a key in fleet-manager under Settings -> API keys. Revoking an already revoked key is not an error. There is no undo - a revoked key can never be reactivated.
Rotation is create-then-revoke; there is no in-place rotation of an API key in v1. The order that avoids downtime:
- Create a new key with the same scopes.
- Deploy it to your integration.
- Confirm the integration is using it.
- Revoke the old key.
A company can hold at most 20 active keys. Revoked keys do not count towards the limit. If creation fails because the limit is reached, revoke keys you no longer use.
Each key records when it was last used, refreshed at most once every five minutes, so the timestamp tells you whether a key is still in service but is not an audit trail of individual calls.
401 and 403
Section titled “401 and 403”401 Unauthorized - the request was not authenticated:
- no
X-API-Keyheader, or an empty one - a key that does not exist, has been revoked, or has expired
- a session token from the Clayton Power apps instead of an API key
Retrying does not help. Check the key.
403 Forbidden - the key is valid but does not carry the scope the endpoint
requires. Create a key with the missing scope; the same request will keep failing
until you do.
Neither response reveals whether the resource in the path exists.
Both use the standard error shape described in Errors and rate limits.
Rate limits
Section titled “Rate limits”Limits are applied per key, not per company, so one busy integration cannot starve another. The current limit is 600 requests per 60 seconds. See Rate limits.