> ## 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.

# Promotional Codes API — Discounts and User Types

> Create and manage promotional discount codes. Apply codes to charging sessions, track usage, and manage driver user types for targeted pricing.

The promotional codes API lets you create discount codes that drivers can apply to their charging sessions. Codes support both percentage-based and fixed-amount discounts, with optional usage limits and expiry dates. This section also covers the user types API, which lets you segment drivers into groups for use with billing rules.

## Create a promotional code

`POST /api/v1/billing/promotional-codes`

<ParamField body="code" type="string" required>
  The code string drivers will enter (e.g. `SUMMER25`). Must be unique within your organisation. Uppercase letters and numbers only, 4–20 characters.
</ParamField>

<ParamField body="discount_type" type="string" required>
  How the discount is calculated. Accepted values: `percent` (percentage off the total), `fixed` (fixed amount off the total).
</ParamField>

<ParamField body="discount_value" type="number" required>
  The discount amount. For `percent`, this is the percentage (e.g. `25` for 25% off). For `fixed`, this is the amount in your default currency.
</ParamField>

<ParamField body="currency" type="string">
  ISO 4217 currency code. Required when `discount_type` is `fixed`.
</ParamField>

<ParamField body="max_uses" type="number">
  Maximum number of times this code can be redeemed across all users. Leave unset for unlimited uses.
</ParamField>

<ParamField body="max_uses_per_user" type="number">
  Maximum number of times a single user can redeem this code. Leave unset for unlimited.
</ParamField>

<ParamField body="expires_at" type="string">
  ISO 8601 date/time after which the code can no longer be applied. Leave unset for no expiry.
</ParamField>

<ParamField body="description" type="string">
  Internal description for the code — not shown to drivers.
</ParamField>

```bash theme={null}
curl -X POST "https://api.dynamo-csms.com/api/v1/billing/promotional-codes" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "SUMMER25",
    "discount_type": "percent",
    "discount_value": 25,
    "max_uses": 500,
    "max_uses_per_user": 1,
    "expires_at": "2024-08-31T23:59:59Z",
    "description": "Summer 2024 promotion — 25% off one session"
  }'
```

```json theme={null}
{
  "code_id": "promo_7XNBQ",
  "code": "SUMMER25",
  "discount_type": "percent",
  "discount_value": 25,
  "currency": null,
  "max_uses": 500,
  "max_uses_per_user": 1,
  "uses_count": 0,
  "expires_at": "2024-08-31T23:59:59Z",
  "description": "Summer 2024 promotion — 25% off one session",
  "active": true,
  "created_at": "2024-06-01T10:00:00Z"
}
```

<ResponseField name="code_id" type="string">
  Unique identifier for the promotional code.
</ResponseField>

<ResponseField name="code" type="string">
  The code string.
</ResponseField>

<ResponseField name="uses_count" type="number">
  Number of times this code has been successfully redeemed.
</ResponseField>

<ResponseField name="active" type="boolean">
  Whether the code is currently redeemable. Set to `false` automatically when `max_uses` is reached or `expires_at` passes.
</ResponseField>

***

## List promotional codes

`GET /api/v1/billing/promotional-codes`

Returns all promotional codes in your organisation.

<ParamField query="active" type="boolean">
  Filter by active status.
</ParamField>

<ParamField query="discount_type" type="string">
  Filter by discount type: `percent` or `fixed`.
</ParamField>

<ParamField query="limit" type="number" default="50">
  Maximum number of codes to return.
</ParamField>

<ParamField query="offset" type="number" default="0">
  Pagination offset.
</ParamField>

```bash theme={null}
curl "https://api.dynamo-csms.com/api/v1/billing/promotional-codes?active=true" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "codes": [
    {
      "code_id": "promo_7XNBQ",
      "code": "SUMMER25",
      "discount_type": "percent",
      "discount_value": 25,
      "uses_count": 47,
      "max_uses": 500,
      "expires_at": "2024-08-31T23:59:59Z",
      "active": true
    }
  ],
  "total": 1
}
```

***

## Get a promotional code

`GET /api/v1/billing/promotional-codes/{code_id}`

<ParamField path="code_id" type="string" required>
  The unique identifier of the promotional code.
</ParamField>

```bash theme={null}
curl "https://api.dynamo-csms.com/api/v1/billing/promotional-codes/promo_7XNBQ" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "code_id": "promo_7XNBQ",
  "code": "SUMMER25",
  "discount_type": "percent",
  "discount_value": 25,
  "currency": null,
  "max_uses": 500,
  "max_uses_per_user": 1,
  "uses_count": 47,
  "expires_at": "2024-08-31T23:59:59Z",
  "description": "Summer 2024 promotion — 25% off one session",
  "active": true,
  "created_at": "2024-06-01T10:00:00Z"
}
```

***

## Apply a promotional code to a session

`POST /api/v1/billing/promotional-codes/sessions/{session_id}/apply-code`

Applies a promotional code to a completed session. The discount is calculated and recorded against the session. This endpoint can be called by a driver application or by an operator on behalf of a driver.

<Warning>
  Codes can only be applied to sessions with status `completed`. Active sessions cannot have a code applied until the session ends.
</Warning>

<ParamField path="session_id" type="string" required>
  The billing session to apply the code to.
</ParamField>

<ParamField body="code" type="string" required>
  The promotional code string to apply.
</ParamField>

```bash theme={null}
curl -X POST "https://api.dynamo-csms.com/api/v1/billing/promotional-codes/sessions/sess_7MNBPX/apply-code" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code": "SUMMER25"}'
```

```json theme={null}
{
  "session_id": "sess_7MNBPX",
  "code": "SUMMER25",
  "code_id": "promo_7XNBQ",
  "discount_type": "percent",
  "discount_value": 25,
  "original_cost": 5.52,
  "discount_amount": 1.38,
  "final_cost": 4.14,
  "currency": "GBP",
  "applied_at": "2024-06-05T09:45:00Z"
}
```

<ResponseField name="original_cost" type="number">
  Session total before the code was applied.
</ResponseField>

<ResponseField name="discount_amount" type="number">
  Amount discounted from the session.
</ResponseField>

<ResponseField name="final_cost" type="number">
  Session total after the discount.
</ResponseField>

***

## Get promotional code usage stats

`GET /api/v1/billing/promotional-codes/{code_id}/usage`

Returns detailed usage statistics for a promotional code, including a breakdown of redemptions over time.

<ParamField path="code_id" type="string" required>
  The unique identifier of the promotional code.
</ParamField>

<ParamField query="from" type="string">
  ISO 8601 start date/time to filter usage from.
</ParamField>

<ParamField query="to" type="string">
  ISO 8601 end date/time to filter usage to.
</ParamField>

```bash theme={null}
curl "https://api.dynamo-csms.com/api/v1/billing/promotional-codes/promo_7XNBQ/usage" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "code_id": "promo_7XNBQ",
  "code": "SUMMER25",
  "total_redemptions": 47,
  "unique_users": 47,
  "total_discount_given": 64.86,
  "currency": "GBP",
  "redemptions_by_day": [
    { "date": "2024-06-01", "count": 5, "discount_total": 6.90 },
    { "date": "2024-06-02", "count": 8, "discount_total": 11.04 },
    { "date": "2024-06-03", "count": 12, "discount_total": 16.56 }
  ]
}
```

<ResponseField name="total_redemptions" type="number">
  Total number of times the code has been applied.
</ResponseField>

<ResponseField name="unique_users" type="number">
  Number of distinct users who redeemed the code.
</ResponseField>

<ResponseField name="total_discount_given" type="number">
  Total value discounted across all redemptions.
</ResponseField>

<ResponseField name="redemptions_by_day" type="object[]">
  Daily redemption counts and discount totals for the requested period.
</ResponseField>

***

## User types

User types let you segment drivers into groups so billing rules can target them specifically. For example, you might create types like `staff`, `fleet`, and `public` and then write rules that grant free sessions to `staff` drivers.

### Create a user type

`POST /api/v1/billing/user-types`

<ParamField body="name" type="string" required>
  Unique name for the user type (e.g. `staff`, `fleet-customer`, `vip`).
</ParamField>

<ParamField body="description" type="string">
  Optional description of who belongs to this type.
</ParamField>

```bash theme={null}
curl -X POST "https://api.dynamo-csms.com/api/v1/billing/user-types" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "staff",
    "description": "Company employees eligible for free charging"
  }'
```

```json theme={null}
{
  "user_type_id": "utype_3KLMX",
  "name": "staff",
  "description": "Company employees eligible for free charging",
  "created_at": "2024-06-01T09:00:00Z"
}
```

***

### List user types

`GET /api/v1/billing/user-types`

Returns all user types in your organisation.

```bash theme={null}
curl "https://api.dynamo-csms.com/api/v1/billing/user-types" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "user_types": [
    {
      "user_type_id": "utype_3KLMX",
      "name": "staff",
      "description": "Company employees eligible for free charging",
      "user_count": 18,
      "created_at": "2024-06-01T09:00:00Z"
    },
    {
      "user_type_id": "utype_9XVBQ",
      "name": "fleet",
      "description": "Fleet account drivers",
      "user_count": 64,
      "created_at": "2024-05-15T10:30:00Z"
    }
  ]
}
```

***

### Assign a user type to a driver

`PUT /api/v1/billing/user-types/users/{user_id}/user-type`

Sets the user type for a specific driver. Replaces any previously assigned type.

<ParamField path="user_id" type="string" required>
  The user to assign the type to.
</ParamField>

<ParamField body="user_type_id" type="string" required>
  The user type to assign.
</ParamField>

```bash theme={null}
curl -X PUT "https://api.dynamo-csms.com/api/v1/billing/user-types/users/usr_9PLKJ/user-type" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_type_id": "utype_3KLMX"}'
```

```json theme={null}
{
  "user_id": "usr_9PLKJ",
  "user_type_id": "utype_3KLMX",
  "user_type_name": "staff",
  "assigned_at": "2024-06-15T11:00:00Z"
}
```
