> ## Documentation Index
> Fetch the complete documentation index at: https://dynamo-csms.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Organizations: Teams, Roles, and API Key Scoping

> Learn how organizations group users, charge points, and billing in Dynamo CSMS, including roles, API key scoping, and the member invitation flow.

An organization is the top-level container in Dynamo CSMS. Everything you manage — charge points, billing, users, and API keys — belongs to an organization. When you sign up for Dynamo CSMS, your account is automatically provisioned with an organization. Additional organizations can be created if you need to segment operations across separate business entities or customers.

## What an organization contains

Every resource in Dynamo CSMS is scoped to a single organization. This means:

* **Charge points** are registered under an organization and can only be managed by members of that organization.
* **Billing** — tariffs, invoices, and billing rules — is configured per organization.
* **Users** belong to an organization through membership, each with an assigned role.
* **API keys** are issued per organization and can only access resources within that organization.

## Members and roles

An organization has one or more members. Each member has a role that controls what actions they can perform.

| Role      | Permissions                                                                                                                   |
| --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `owner`   | Full access. Can manage billing, members, API keys, and all charge points. Cannot be removed; only one owner per org.         |
| `admin`   | Can manage charge points, sites, projects, tariffs, and members. Cannot manage billing settings or transfer ownership.        |
| `member`  | Can view charge points and sessions, and trigger OCPP commands on authorized charge points. Cannot manage members or billing. |
| `billing` | Read-only access to billing data, invoices, and session history. No access to charge point controls.                          |

<Note>
  You can have multiple admins but only one owner. To transfer ownership, the current owner must reassign the owner role from the organization settings in the dashboard or by updating a member's role via `PUT /api/v1/organizations/{org_id}/members/{user_id}/role`.
</Note>

## Creating an organization

To create a new organization, call `POST /api/v1/organizations` with a name and optional settings:

```bash theme={null}
POST /api/v1/organizations
Authorization: Bearer <your-api-key>
Content-Type: application/json

{
  "name": "Acme Fleet Services",
  "slug": "acme-fleet",
  "settings": {
    "default_currency": "USD",
    "timezone": "America/Chicago"
  }
}
```

A successful response returns the new organization object:

```json theme={null}
{
  "organization_id": "org_01HXYZ111BBB",
  "name": "Acme Fleet Services",
  "slug": "acme-fleet",
  "created_at": "2026-05-01T09:00:00Z",
  "settings": {
    "default_currency": "USD",
    "timezone": "America/Chicago"
  },
  "owner": {
    "user_id": "usr_01HXYZ999ZZZ",
    "email": "admin@acme.example.com"
  }
}
```

<Tip>
  The `slug` field appears in URLs and must be globally unique across all Dynamo CSMS organizations. If you omit it, one is auto-generated from the name.
</Tip>

## Inviting members

You invite new members by sending an invitation to their email address. They receive a link that lets them accept the invitation and join the organization.

<Steps>
  <Step title="Send the invitation">
    Call `POST /api/v1/organizations/{org_id}/invitations` with the recipient's email and desired role:

    ```bash theme={null}
    POST /api/v1/organizations/org_01HXYZ111BBB/invitations
    Authorization: Bearer <your-api-key>
    Content-Type: application/json

    {
      "email": "jane.doe@example.com",
      "role": "admin"
    }
    ```

    ```json theme={null}
    {
      "invitation_id": "inv_01HXYZ555CCC",
      "email": "jane.doe@example.com",
      "role": "admin",
      "status": "pending",
      "expires_at": "2026-05-08T09:00:00Z"
    }
    ```
  </Step>

  <Step title="Recipient accepts">
    The invitee receives an email with an acceptance link. Clicking it redirects them to the Dynamo CSMS dashboard where they create or log in to their account and join the organization.
  </Step>

  <Step title="Confirm membership">
    Once accepted, retrieve the updated member list to confirm:

    ```bash theme={null}
    GET /api/v1/organizations/org_01HXYZ111BBB/members
    ```

    ```json theme={null}
    {
      "data": [
        {
          "user_id": "usr_01HXYZ444DDD",
          "email": "jane.doe@example.com",
          "role": "admin",
          "joined_at": "2026-05-02T11:30:00Z"
        }
      ]
    }
    ```
  </Step>
</Steps>

<Warning>
  Invitations expire after 7 days. If an invitation expires before the recipient accepts it, you must send a new one. You can check the status of pending invitations with `GET /api/v1/organizations/{org_id}/invitations`.
</Warning>

## API keys

API keys in Dynamo CSMS are scoped to a single organization. A key issued for `org_01HXYZ111BBB` cannot read or write resources belonging to any other organization.

### Creating an API key

```bash theme={null}
POST /api/v1/org/api-keys
Authorization: Bearer <your-api-key>
Content-Type: application/json

{
  "name": "Production Backend",
  "scopes": ["read:charge_points", "write:charge_points", "read:billing"]
}
```

```json theme={null}
{
  "id": "key_01HXYZ222EEE",
  "name": "Production Backend",
  "key": "dynamo_sk_live_XXXXXXXXXXXXXXXXXXXX",
  "scopes": ["read:charge_points", "write:charge_points", "read:billing"],
  "created_at": "2026-05-01T09:00:00Z"
}
```

<Warning>
  The `key` value is only returned once at creation time. Store it securely — it cannot be retrieved again. If you lose it, you must rotate the key.
</Warning>

API keys are scoped by permissions rather than roles. Assign only the scopes your application actually needs.

### Rotating an API key

To rotate a key, delete the old one and create a new one:

```bash theme={null}
DELETE /api/v1/org/api-keys/{key_id}
```

<Tip>
  Create the new key before deleting the old one to ensure zero-downtime key rotation.
</Tip>

## Organization settings

You can update organization-level settings at any time:

```bash theme={null}
PUT /api/v1/organizations/org_01HXYZ111BBB
Authorization: Bearer <your-api-key>
Content-Type: application/json

{
  "settings": {
    "default_currency": "EUR",
    "timezone": "Europe/Berlin",
    "session_idle_timeout_minutes": 60
  }
}
```

<AccordionGroup>
  <Accordion title="default_currency">
    The currency used for all tariffs and invoices in this organization. Accepts ISO 4217 currency codes (e.g., `USD`, `EUR`, `GBP`). Changing this does not retroactively update existing invoice records.
  </Accordion>

  <Accordion title="timezone">
    The IANA timezone identifier used for billing period calculations and session timestamps displayed in the dashboard. Does not affect UTC timestamps returned by the API.
  </Accordion>

  <Accordion title="session_idle_timeout_minutes">
    The number of minutes after which an idle session (no energy delivered) is automatically stopped. Defaults to `0` (disabled). Useful for preventing phantom sessions on faulty chargers.
  </Accordion>
</AccordionGroup>

<CardGroup cols={2}>
  <Card title="Billing model" icon="credit-card" href="/concepts/billing-model">
    Understand tariffs, billing rules, and invoicing scoped to your organization.
  </Card>

  <Card title="Charge points" icon="charging-station" href="/concepts/charge-points">
    Learn how to register and commission charge points within your organization.
  </Card>
</CardGroup>
