Skip to main content
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. 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.

X-API-Key header

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

  1. Log in to the Dynamo CSMS Developer Portal.
  2. Navigate to Settings → API Keys.
  3. Click Create API key, choose a name, and select the scopes you need.
  4. 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.
ScopeAccess
read:charge_pointsList and query charge point status and details
write:charge_pointsRegister, update, and delete charge points
read:sessionsRead active and historical charging sessions
write:sessionsStart and stop charging sessions remotely
read:billingRead tariffs, billing rules, and revenue reports
write:billingCreate and update tariffs, promotional codes, and billing rules
read:webhooksList configured webhook endpoints
write:webhooksCreate, update, and delete webhook endpoints
read:analyticsAccess fleet analytics and usage reports
read:organisationsRead organisation and team member data
write:organisationsUpdate organisation settings and manage team members
write:api_keysCreate and revoke API keys for your organisation
read:ocpiRead OCPI roaming partner data
write:ocpiConfigure OCPI connections with partner networks
write:commandsSend 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.
TierLimit
Free1,000 requests per hour
Pro10,000 requests per hour
EnterpriseCustom — 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.