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

# OAuth 2.0 Authentication for the Lumenaza REST API

> Learn how to authenticate with the Lumenaza API using OAuth 2.0 client credentials flow to obtain and use bearer tokens for secure API access.

The Lumenaza REST API uses the **OAuth 2.0 client credentials flow** for authentication. Every API request must include a valid bearer token in its `Authorization` header. This flow is designed for server-to-server communication — there is no user login involved. Your application exchanges its credentials directly for an access token, which it then presents with each request.

## Get Your Credentials

Before you can authenticate, you need a **client ID** and **client secret** issued by Lumenaza.

<Note>
  Contact [Lumenaza support](mailto:support@lumenaza.de) to request your API credentials. You will receive a `client_id` and a `client_secret` tied to your whitelabel customer account. Keep these safe — they grant full access to your API account.
</Note>

<Warning>
  Never expose your `client_secret` in client-side code, public repositories, or logs. Treat it with the same care as a password. If you believe your secret has been compromised, contact Lumenaza support immediately to have it rotated.
</Warning>

***

## Request an Access Token

<Steps>
  <Step title="Choose your environment">
    Lumenaza provides two environments, each with its own token endpoint. Use the **test** environment during development and the **production** environment for live traffic.

    | Environment | Token URL |
    | - | - |
    | Test | `https://api.test.lumenaza.de/oauth2/token/` |
    | Production | `https://api.lumenaza.de/oauth2/token/` |
  </Step>

  <Step title="POST to the token endpoint">
    Send a `POST` request with your credentials and the desired scopes in the request body using `application/x-www-form-urlencoded` encoding.

    <CodeGroup>
      ```bash Test environment theme={null}
      curl --request POST \
        --url https://api.test.lumenaza.de/oauth2/token/ \
        --header 'Content-Type: application/x-www-form-urlencoded' \
        --data 'grant_type=client_credentials' \
        --data 'client_id=YOUR_CLIENT_ID' \
        --data 'client_secret=YOUR_CLIENT_SECRET' \
        --data 'scope=read write'
      ```

      ```bash Production environment theme={null}
      curl --request POST \
        --url https://api.lumenaza.de/oauth2/token/ \
        --header 'Content-Type: application/x-www-form-urlencoded' \
        --data 'grant_type=client_credentials' \
        --data 'client_id=YOUR_CLIENT_ID' \
        --data 'client_secret=YOUR_CLIENT_SECRET' \
        --data 'scope=read write'
      ```
    </CodeGroup>

    Replace `YOUR_CLIENT_ID` and `YOUR_CLIENT_SECRET` with the credentials provided by Lumenaza.
  </Step>

  <Step title="Parse the token response">
    A successful request returns a JSON object containing your access token:

    ```json Token response theme={null}
    {
      "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
      "token_type": "bearer",
      "expires_in": 3600,
      "scope": "read write"
    }
    ```

    | Field | Description |
    | - | - |
    | `access_token` | The token to include in subsequent API requests. |
    | `token_type` | Always `bearer`. |
    | `expires_in` | Seconds until the token expires (e.g. `3600` = 1 hour). |
    | `scope` | The scopes granted to this token. |
  </Step>
</Steps>

***

## Use the Token in API Requests

Include the access token in the `Authorization` header of every API request using the `Bearer` scheme.

<CodeGroup>
  ```bash List consumers theme={null}
  curl --request GET \
    --url https://api.test.lumenaza.de/v3/consumers/ \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
  ```

  ```bash List consumers (production) theme={null}
  curl --request GET \
    --url https://api.lumenaza.de/v3/consumers/ \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
  ```
</CodeGroup>

<Note>
  The token value above is truncated for readability. Use the full `access_token` string exactly as returned by the token endpoint.
</Note>

***

## Token Expiry and Reuse

Tokens are **short-lived**. The `expires_in` field in the token response tells you how many seconds the token remains valid.

**Best practices for token management:**

* **Cache and reuse** your token for its entire lifetime rather than requesting a new one per API call. This reduces latency and avoids rate-limiting on the token endpoint.
* **Track expiry** by recording the time you received the token and subtracting a small buffer (e.g. 30 seconds) to account for clock skew. Refresh before that deadline.
* **Request a new token** when the current one expires. The client credentials flow makes this straightforward — simply repeat the `POST` to the token endpoint.

<Warning>
  Requests made with an expired token will receive a `401 Unauthorized` response. Your application should handle this error gracefully by fetching a fresh token and retrying the original request.
</Warning>

***

## Scopes

Scopes control what actions your token is permitted to perform. Request only the scopes your integration actually needs.

| Scope | Permitted HTTP Methods | Typical Use |
| - | - | - |
| `read` | `GET` | Retrieving consumers, contracts, meter readings, and other resources. |
| `write` | `POST`, `PUT`, `PATCH`, `DELETE` | Creating or modifying consumers, contracts, and related data. |

You can request both scopes in a single token (`scope=read write`) or restrict a token to `read` only for integrations that never need to mutate data.

***

## Common Authentication Errors

<AccordionGroup>
  <Accordion title="401 Unauthorized — Invalid or expired token">
    **Cause:** The `Authorization` header is missing, the token value is malformed, or the token has expired.

    **Resolution:**

    * Confirm the header is formatted as `Authorization: Bearer <token>` with no extra whitespace.
    * Check whether the token has passed its `expires_in` lifetime and request a new one if so.
    * Verify you are using the correct token for the environment (test tokens cannot be used against the production API and vice versa).

    ```json Example error response theme={null}
    {
      "detail": "Authentication credentials were not provided."
    }
    ```
  </Accordion>

  <Accordion title="403 Forbidden — Insufficient scope">
    **Cause:** Your token was issued with a scope that does not cover the action you are attempting. For example, using a `read`-only token to `POST` a new consumer.

    **Resolution:**

    * Request a new token that includes the `write` scope.
    * Review your integration to ensure you are requesting the appropriate scopes at token creation time.

    ```json Example error response theme={null}
    {
      "detail": "You do not have permission to perform this action."
    }
    ```
  </Accordion>

  <Accordion title="400 Bad Request — Invalid token request">
    **Cause:** The token request body is malformed — common causes include a missing `grant_type`, incorrect `Content-Type` header, or invalid `client_id`/`client_secret` values.

    **Resolution:**

    * Ensure `Content-Type: application/x-www-form-urlencoded` is set on the token request.
    * Double-check that `grant_type=client_credentials` is included in the body.
    * Confirm your `client_id` and `client_secret` are correct and have not been rotated.

    ```json Example error response theme={null}
    {
      "error": "invalid_client",
      "error_description": "Invalid client credentials."
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Test vs. Production Environments

Lumenaza maintains fully isolated environments to keep development activity separate from live data.

| | Test | Production |
| - | - | - |
| **Token URL** | `https://api.test.lumenaza.de/oauth2/token/` | `https://api.lumenaza.de/oauth2/token/` |
| **API Base URL** | `https://api.test.lumenaza.de/v3/` | `https://api.lumenaza.de/v3/` |
| **Credentials** | Separate test `client_id` / `client_secret` | Live `client_id` / `client_secret` |
| **Data** | Sandboxed — no real consumers or contracts | Live customer data |

<Note>
  Credentials issued for the test environment will not work against the production token endpoint, and vice versa. Make sure your application reads the correct credentials and base URL from environment-specific configuration (e.g. environment variables) rather than hardcoding either set.
</Note>


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