> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ridergy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Obtain an access token

> Exchange client credentials for a short-lived Bearer token (3600s).

Accepts credentials via:
- `Authorization: Basic base64(client_id:client_secret)` with
  `grant_type=client_credentials` in the request body (RFC 6749)
- JSON body with `client_id`, `client_secret`, and `grant_type`




## OpenAPI

````yaml api-reference/energy-management/openapi.en.yaml POST /oauth/token
openapi: 3.1.0
info:
  title: RiDERgy Energy Management API
  version: '1.0'
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
  description: >
    Programmatic control of charging power limits across locations, individual

    chargers, organizations, and cross-location clusters.


    ## Authentication

    Every endpoint except `GET /health` and `POST /oauth/token` requires a

    Bearer token obtained via the OAuth 2.0 client_credentials flow:


    1. Create OAuth client credentials in the RiDERgy dashboard.

    2. Exchange them for a short-lived access token via `POST /oauth/token`.

    3. Pass the token as `Authorization: Bearer <token>` on every request.


    Tokens expire after 3600 seconds. Your tenant is embedded in the token

    and cannot be spoofed. Credentials for one tenant cannot access another.


    Your tenant must have the Energy Management API feature enabled, otherwise

    requests fail with `403 FEATURE_NOT_ENABLED`. Contact RiDERgy to enable it.


    ## Scopes

    Tokens carry scopes that control which endpoints are accessible:

    `locations:read`, `locations:write`, `clusters:read`, `clusters:write`,

    `chargers:write`, `org:write`. Requests to endpoints requiring a scope

    the token does not have will fail with `403 INSUFFICIENT_SCOPE`.


    ## Priority model

    Location and charger limits are controlled via **priority-windowed
    profiles**:


    - Priorities range from **0 (lowest) to 10 (highest)**, OCPP-stack-style.

    - A target (location or charger connector) can have up to 11 profiles, one
      per priority level, each with its own `[startTime, endTime)` window.
    - At any moment, the **effective limit** is the `limitKw` of the
      highest-priority profile whose window is currently active.
    - If no profile is active, a location falls back to its `permanentLimitKw`.

    - Submitting a profile at a priority that already has one for that target
      **replaces** it.
    - Profiles are applied and reverted automatically at their
      `startTime`/`endTime`. No further API calls are needed once a profile is
      created. Profile records are never deleted, so history remains queryable.

    ## Errors

    All errors share this shape:


    ```json

    {
      "error": {
        "code": "LOCATION_NOT_FOUND",
        "message": "Location 123 was not found for the provided tenant",
        "requestId": "b1f6e6b0-..."
      }
    }

    ```
servers:
  - url: https://api.ridergy.com/v1
    description: Production
security:
  - BearerAuth: []
tags:
  - name: Auth
    description: OAuth 2.0 token endpoint for the client_credentials grant.
  - name: Health
    description: Unauthenticated service health check.
  - name: Locations
    description: Read and set location-level power limits and priority profiles.
  - name: Chargers
    description: >-
      Lock individual charger connectors to a fixed power limit for a time
      window.
  - name: Organizations
    description: Tenant-wide cap profiles (recorded only, enforcement not yet active).
  - name: Clusters
    description: Group locations under a shared kW cap and apply schedules across them.
paths:
  /oauth/token:
    post:
      tags:
        - Auth
      summary: Obtain an access token
      description: |
        Exchange client credentials for a short-lived Bearer token (3600s).

        Accepts credentials via:
        - `Authorization: Basic base64(client_id:client_secret)` with
          `grant_type=client_credentials` in the request body (RFC 6749)
        - JSON body with `client_id`, `client_secret`, and `grant_type`
      operationId: createToken
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - grant_type
              properties:
                grant_type:
                  type: string
                  enum:
                    - client_credentials
                client_id:
                  type: string
                  description: Required if not using Basic auth header.
                  example: emcl_a1b2c3d4e5f67890a1b2c3d4e5f67890
                client_secret:
                  type: string
                  description: Required if not using Basic auth header.
                  example: emcs_...
            examples:
              jsonBody:
                value:
                  grant_type: client_credentials
                  client_id: emcl_a1b2c3d4e5f67890a1b2c3d4e5f67890
                  client_secret: emcs_a1b2c3d4...
      responses:
        '200':
          description: Access token issued
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token:
                    type: string
                    description: JWT Bearer token
                    example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                  token_type:
                    type: string
                    example: Bearer
                  expires_in:
                    type: integer
                    description: Token lifetime in seconds
                    example: 3600
                  scope:
                    type: string
                    description: Space-delimited list of granted scopes
                    example: >-
                      locations:read locations:write clusters:read
                      clusters:write chargers:write org:write
        '400':
          description: Invalid request (missing grant_type or unsupported grant)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: unsupported_grant_type
                  error_description:
                    type: string
                    example: Only client_credentials grant type is supported
        '401':
          description: Invalid client credentials
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: invalid_client
                  error_description:
                    type: string
                    example: Invalid client credentials
      security: []
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >
        OAuth 2.0 access token obtained via `POST /oauth/token` with
        client_credentials grant.

        Tenant and scopes are embedded in the JWT. No additional headers needed.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.