Every request to the Dynamo CSMS API must include a valid credential. This page explains the two supported authentication methods, how to obtain and manage API keys, what permission scopes control, and how to handle authentication and rate-limit errors.
Authentication methods
Dynamo CSMS accepts credentials in two header formats. Both are equally valid — choose whichever fits your HTTP client or framework better.
Bearer token (recommended)
Pass your API key as a Bearer token in the Authorization header:
curl -X GET https://api.dynamo-csms.com/api/v1/cpo/fleet/summary \
-H "Authorization: Bearer dyn_live_abc123xyz789..."
This is the standard OAuth 2.0 Bearer format and is supported by virtually every HTTP client library.
Alternatively, pass your API key in the X-API-Key header:
curl -X GET https://api.dynamo-csms.com/api/v1/cpo/fleet/summary \
-H "X-API-Key: dyn_live_abc123xyz789..."
Do not pass credentials in the URL query string (for example, ?api_key=...). Query parameters appear in server logs and browser history. Use headers instead.
Code examples
import requests
headers = {"Authorization": "Bearer dyn_live_abc123xyz789..."}
response = requests.get(
"https://api.dynamo-csms.com/api/v1/cpo/fleet/summary",
headers=headers
)
Obtaining an API key
Via the Developer Portal
- Log in to the Dynamo CSMS Developer Portal.
- Navigate to Settings → API Keys.
- Click Create API key, choose a name, and select the scopes you need.
- Copy the key immediately — it is only displayed once.
Via the API
If you already have a valid key with the write:api_keys scope, you can create additional keys programmatically:
curl -X POST https://api.dynamo-csms.com/api/v1/org/api-keys \
-H "Authorization: Bearer YOUR_EXISTING_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "webhook-service",
"scopes": ["read:charge_points", "read:sessions"]
}'
{
"id": "key_01hx2b3c4d5e6f7g8h9j",
"name": "webhook-service",
"key": "dyn_live_abc123xyz789...",
"scopes": ["read:charge_points", "read:sessions"],
"created_at": "2026-05-01T09:00:00Z"
}
The key field is only returned on creation. If you lose the key value, you must revoke it and create a new one. The API never returns the full key value again after the creation response.
Permission scopes
Scopes restrict what an API key can do. Assign only the scopes an application actually needs — this limits the blast radius if a key is ever leaked.
| Scope | Access |
|---|
read:charge_points | List and query charge point status and details |
write:charge_points | Register, update, and delete charge points |
read:sessions | Read active and historical charging sessions |
write:sessions | Start and stop charging sessions remotely |
read:billing | Read tariffs, billing rules, and revenue reports |
write:billing | Create and update tariffs, promotional codes, and billing rules |
read:webhooks | List configured webhook endpoints |
write:webhooks | Create, update, and delete webhook endpoints |
read:analytics | Access fleet analytics and usage reports |
read:organisations | Read organisation and team member data |
write:organisations | Update organisation settings and manage team members |
write:api_keys | Create and revoke API keys for your organisation |
read:ocpi | Read OCPI roaming partner data |
write:ocpi | Configure OCPI connections with partner networks |
write:commands | Send remote commands to charge points (reboot, unlock, etc.) |
For read-only integrations such as monitoring dashboards or analytics pipelines, use only read:* scopes. Reserve write:* scopes for services that actively control hardware.
Installer authentication
Installers in the field use a separate token-based flow rather than long-lived API keys. This is because installer credentials are personal and time-limited — they are not associated with an organisation’s API key quota.
To authenticate as an installer:
curl -X POST https://api.dynamo-csms.com/api/v1/installer/login \
-H "Content-Type: application/json" \
-d '{
"email": "installer@example.com",
"password": "your-password"
}'
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"installer_id": "ins_01hx9k2m3n4p"
}
Use the access_token value as a Bearer token in the same way as an API key. Installer tokens expire after 60 minutes. See the Installer quickstart for the full workflow.
Rate limits
Dynamo CSMS enforces rate limits per API key to ensure fair use and platform stability.
| Tier | Limit |
|---|
| Free | 1,000 requests per hour |
| Pro | 10,000 requests per hour |
| Enterprise | Custom — contact support@dynamo-csms.com |
Every response includes rate-limit headers so you can track your consumption:
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9847
X-RateLimit-Reset: 1746090000
The X-RateLimit-Reset value is a Unix timestamp indicating when your hourly quota resets.
Error responses
401 Unauthorized
A 401 response means the request was not authenticated or the credential is invalid.
{
"error": "unauthorized",
"message": "Invalid or missing API key.",
"request_id": "req_01hxzz9aa1b2"
}
Common causes:
- The
Authorization or X-API-Key header is missing entirely.
- The API key has been revoked or expired.
- The key belongs to a different organisation than the resource being accessed.
- The
Bearer prefix is missing from the Authorization header value.
403 Forbidden
A 403 response means the credential is valid but the key does not have the required scope for the requested operation.
{
"error": "forbidden",
"message": "The API key does not have the required scope: write:charge_points",
"required_scope": "write:charge_points",
"request_id": "req_01hxzz9aa1b3"
}
Add the missing scope to the API key in the Developer Portal, or create a new key with the correct scopes.
429 Too Many Requests
A 429 response means you have exceeded your hourly rate limit.
{
"error": "rate_limit_exceeded",
"message": "You have exceeded the rate limit of 1000 requests per hour.",
"retry_after": 847,
"request_id": "req_01hxzz9aa1b4"
}
The retry_after field tells you how many seconds to wait before retrying. Implement exponential backoff in your application rather than retrying immediately.
import time
import requests
def call_with_backoff(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
retry_after = response.json().get("retry_after", 60)
time.sleep(retry_after)
continue
return response
raise Exception("Rate limit retries exhausted")
Revoking an API key
To revoke a key that is no longer needed or may have been compromised, delete it via the API or from Settings → API Keys in the Developer Portal.
curl -X DELETE https://api.dynamo-csms.com/api/v1/org/api-keys/key_01hx2b3c4d5e6f7g8h9j \
-H "Authorization: Bearer YOUR_ADMIN_KEY"
Revocation takes effect immediately. Any in-flight requests using the revoked key that have already been authenticated will complete, but new requests will return 401.
Security best practices
- Rotate keys regularly. Create a new key, update your application, then revoke the old one.
- Use environment variables. Never hard-code API keys in source files.
- Apply least-privilege scopes. Give each key only the scopes it needs.
- Monitor usage. Review
X-RateLimit-Remaining in responses and alert on unexpected spikes.
- Separate keys per environment. Use distinct keys for development, staging, and production.