Skip to main content
Installer accounts are separate from organization API keys. They are used by field technicians to register charge points and run commissioning workflows through the Dynamo CSMS Installer App. All installer endpoints return a short-lived JWT access token that you include in subsequent requests.

Register an installer account

POST /api/v1/installer/signup Creates a new installer account immediately, without requiring email confirmation. Use signup-with-confirmation if you want to enforce email verification before the account becomes active.
email
string
required
Installer’s email address. Used as the login identifier.
password
string
required
Must be at least 10 characters, containing at least one uppercase letter, one lowercase letter, and one digit.
first_name
string
required
Installer’s given name.
last_name
string
required
Installer’s family name.
company
string
required
Name of the installer’s employer or contracting company.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "j.smith@acme-ev.com",
    "password": "Tr0ub4dor&3",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme EV Services"
  }'
Response 201 Created
{
  "installer_id": "ins_7f3a1b2c",
  "email": "j.smith@acme-ev.com",
  "first_name": "Jane",
  "last_name": "Smith",
  "company": "Acme EV Services",
  "status": "active",
  "created_at": "2024-03-10T09:00:00Z"
}

Register with email confirmation

POST /api/v1/installer/signup-with-confirmation Same as signup, but the account is created in a pending_verification state. Dynamo CSMS sends a confirmation email; the installer must click the link before they can log in. Accepts the same body as POST /api/v1/installer/signup.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/signup-with-confirmation \
  -H "Content-Type: application/json" \
  -d '{
    "email": "j.smith@acme-ev.com",
    "password": "Tr0ub4dor&3",
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "Acme EV Services"
  }'
Response 201 Created
{
  "installer_id": "ins_7f3a1b2c",
  "email": "j.smith@acme-ev.com",
  "status": "pending_verification",
  "message": "A confirmation link has been sent to j.smith@acme-ev.com."
}

Log in

POST /api/v1/installer/login Authenticates an installer and returns a JWT access token. Include this token as Authorization: Bearer <access_token> in all subsequent installer API calls.
email
string
required
The installer’s registered email address.
password
string
required
The installer’s password.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "j.smith@acme-ev.com",
    "password": "Tr0ub4dor&3"
  }'
Response 200 OK
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "installer_id": "ins_7f3a1b2c"
}
access_token
string
JWT token to use in the Authorization: Bearer header.
token_type
string
Always "Bearer".
expires_in
integer
Token lifetime in seconds (default 3600 — 1 hour).
installer_id
string
The authenticated installer’s ID.

Log out

POST /api/v1/installer/logout Invalidates the current access token server-side. After logging out, the token will be rejected on all subsequent requests.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/logout \
  -H "Authorization: Bearer INSTALLER_ACCESS_TOKEN"
Response 204 No Content

Request password reset

POST /api/v1/installer/forgot-password Sends a password reset email to the specified address if an account exists. The response is always 200 OK regardless of whether the email is registered, to prevent account enumeration.
email
string
required
The email address associated with the installer account.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email": "j.smith@acme-ev.com"}'
Response 200 OK
{
  "message": "If an account with that email exists, a reset link has been sent."
}

Reset password

POST /api/v1/installer/reset-password Completes a password reset using the token from the email link.
token
string
required
The reset token extracted from the password reset email link.
new_password
string
required
The new password. Must meet the same strength requirements as signup.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "token": "rst_4f8a2b1c9d3e7f0a",
    "new_password": "N3wS3cur3P@ss!"
  }'
Response 200 OK
{
  "message": "Password updated successfully. Please log in with your new password."
}

Get profile

GET /api/v1/installer/profile Returns the authenticated installer’s profile information.
curl https://api.dynamo-csms.com/api/v1/installer/profile \
  -H "Authorization: Bearer INSTALLER_ACCESS_TOKEN"
Response 200 OK
{
  "installer_id": "ins_7f3a1b2c",
  "email": "j.smith@acme-ev.com",
  "first_name": "Jane",
  "last_name": "Smith",
  "company": "Acme EV Services",
  "phone": "+1-555-0100",
  "status": "active",
  "identity_verified": true,
  "terms_accepted_at": "2024-03-10T09:05:00Z",
  "created_at": "2024-03-10T09:00:00Z"
}

Update profile

PUT /api/v1/installer/profile Updates the authenticated installer’s profile. All fields are optional — only include the ones you want to change.
first_name
string
Updated given name.
last_name
string
Updated family name.
company
string
Updated company name.
phone
string
Contact phone number in E.164 format (e.g. "+1-555-0100").
curl -X PUT https://api.dynamo-csms.com/api/v1/installer/profile \
  -H "Authorization: Bearer INSTALLER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+1-555-0199",
    "company": "Acme EV Services Ltd."
  }'
Response 200 OK — returns the full updated profile object (same schema as GET profile).

Get verification status

GET /api/v1/installer/verification-status Returns the current identity verification state for the installer account.
curl https://api.dynamo-csms.com/api/v1/installer/verification-status \
  -H "Authorization: Bearer INSTALLER_ACCESS_TOKEN"
Response 200 OK
{
  "installer_id": "ins_7f3a1b2c",
  "identity_verified": false,
  "verification_submitted_at": "2024-03-11T10:00:00Z",
  "verification_status": "under_review",
  "rejection_reason": null
}
identity_verified
boolean
true when identity verification has been approved.
verification_status
string
One of not_submitted, under_review, approved, rejected.
rejection_reason
string | null
Human-readable reason if status is rejected, otherwise null.

Submit identity verification

POST /api/v1/installer/verify-identity Submits identity documents for review. Verification is required before an installer can commission charge points in production.
document_type
string
required
Type of identity document. One of: passport, drivers_license, national_id.
document_number
string
required
The document’s identification number.
document_expiry
string
required
Document expiry date in YYYY-MM-DD format.
selfie_url
string
required
URL of an uploaded selfie image for liveness check. Upload the image to your storage first and provide the URL.
document_front_url
string
required
URL of the front-of-document image.
document_back_url
string
URL of the back-of-document image. Required for drivers_license and national_id.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/verify-identity \
  -H "Authorization: Bearer INSTALLER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "drivers_license",
    "document_number": "D123-4567-8901",
    "document_expiry": "2028-06-30",
    "selfie_url": "https://storage.example.com/selfie_jsmith.jpg",
    "document_front_url": "https://storage.example.com/dl_front_jsmith.jpg",
    "document_back_url": "https://storage.example.com/dl_back_jsmith.jpg"
  }'
Response 202 Accepted
{
  "message": "Identity verification submitted. Review typically takes 1–2 business days.",
  "verification_status": "under_review",
  "submitted_at": "2024-03-11T10:00:00Z"
}

Accept terms of service

POST /api/v1/installer/accept-terms Records that the installer has accepted the current Dynamo CSMS Terms of Service. This must be called before the installer can register charge points.
terms_version
string
required
The version string of the terms being accepted (e.g. "2024-01"). You can find the current version in your Dynamo CSMS dashboard.
curl -X POST https://api.dynamo-csms.com/api/v1/installer/accept-terms \
  -H "Authorization: Bearer INSTALLER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"terms_version": "2024-01"}'
Response 200 OK
{
  "message": "Terms of service accepted.",
  "terms_version": "2024-01",
  "accepted_at": "2024-03-10T09:05:00Z"
}

Error responses

StatusCodeMeaning
400validation_errorOne or more required fields are missing or invalid
401invalid_credentialsEmail or password is incorrect
401token_expiredThe access token has expired — log in again
403account_pendingAccount not yet email-confirmed
403identity_requiredIdentity verification needed before this action
403terms_requiredTerms of service must be accepted first
409email_takenAn account with this email already exists
422weak_passwordPassword does not meet strength requirements