> For the complete documentation index, see [llms.txt](https://mobile-calendar.gitbook.io/v1/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mobile-calendar.gitbook.io/v1/overview/authentication.md).

# Authentication

## Overview

The **Mobile Calendar API** uses **OAuth 2.0 Client Credentials Flow** for secure, server-to-server authentication

Each integration receives a **client ID** and **client secret**, which are used to obtain an access token.\
Tokens are **short-lived** (valid for 3600 seconds / 1 hour) and must be generated new before expiration.

## 1. Requesting an Access Token

### Endpoint

POST **/v1/public/auth/token**\
Content-Type: **application/json**

### Request Body

```json
{
  "clientId": "user123_438ehs833s32...",
  "clientSecret": "47yd47r39y4r34ruj9384..."
}
```

### Successful Response

```json
{
    "token_type": "Bearer",
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJh...",
    "expires_in": 3600,
    "scope": [
        "reservations.read",
        "reservations.create",
        "reservations.update",
        "locks.read",
        "locks.create",
        "locks.update",
    ],
    "meta": {
        "ruid": "96ee294f-be6d-490e-adb5-bdb4c6a8b2d9"
    }
}
```

### Error Response

```json
{
    "type": "https://mobile-calendar.com...",
    "title": "Unauthorized",
    "status": 401,
    "detail": "Invalid credentials",
    "instance": "/v1/public/auth/token",
    "ruid": "7f80f1b4-a44b-4345-b383-7d0a937b4411"
}
```

## 2. Using the Token

Include the access token in every authorized request using the `Authorization` header:

```markup
Authorization: Bearer {access_token}
```

The token grants access only to the scopes specified during creation. Once expired, a new token must be generated using the same credentials.

{% hint style="warning" %}
Tip: It is recommended to refresh your token a few minutes before it expires to ensure uninterrupted API access.
{% endhint %}

## 3. Token Lifetime

* Access token validity: **3600 seconds (1 hour)**
* No refresh token is provided
* To renew, call `/v1/public/auth/token` again with your credentials
* Expired tokens will result in a **401 Unauthorized** response

## 4. Scopes

Scopes define what actions your integration can perform. When requesting an access token, your client credentials are mapped to specific scopes assigned by the administrator.

### Available Scopes

| Scope                    | Description                       |
| ------------------------ | --------------------------------- |
| **reservations.read**    | Retrieve reservation data         |
| **reservations.create**  | Create new reservations           |
| **reservations.update**  | Update existing reservations      |
| **reservations.delete**  | Delete reservations               |
| **reservations.restore** | Restore deleted reservations      |
| **locks.read**           | Read lock device data             |
| **locks.create**         | Add new lock devices              |
| **locks.update**         | Update existing locks             |
| **locks.delete**         | Remove lock devices               |
| **rooms.read**           | List and view rooms               |
| **rooms.create**         | Create rooms                      |
| **rooms.update**         | Modify room details               |
| **rooms.delete**         | Delete rooms                      |
| **roomTypes.read**       | Read room type definitions        |
| **clients.read**         | Access client information         |
| **clients.create**       | Add new clients                   |
| **clients.update**       | Update client data                |
| **clients.delete**       | Remove clients                    |
| **pricing.read**         | Retrieve pricing information      |
| **availability.read**    | Retrieve availability information |
| **rates.read**           | Retrieve rate plans and rate data |
| **sources.read**         | Retrieve reservation source data  |
| **invoices.read**        | Retrieve invoices                 |
| **invoices.create**      | Create invoices                   |
| **invoices.update**      | Modify invoices                   |
| **invoices.delete**      | Delete invoices                   |

Scopes can be combined based on your API account configuration.

## 5. IP Address Restrictions

Each API account can be **restricted to specific IP addresses**.\
Requests coming from unauthorized IPs are rejected with:

**HTTP 403 Forbidden**

Example configuration:

Allowed IPs: 203.0.113.0, 198.51.100.10

This feature enhances security and prevents misuse of stolen credentials.

## 6. Security Best Practices

{% hint style="warning" %}

* Always use **HTTPS** — unsecured connections are blocked.
* Store your **clientId** and **clientSecret** securely (never in frontend or mobile apps).
* **Rotate credentials** periodically.
* **Cache** and **reuse** the access token until it expires.
* **Renew** tokens proactively (e.g., 5 minutes before expiration).
* Use the returned **`ruid`** for request tracing.
* Restrict access to **only the necessary scopes and IPs**.
* Validate all webhook signatures to verify authenticity.
  {% endhint %}

## 7. Example Integration Flow

{% stepper %}
{% step %}

### Obtain credentials

Obtain credentials (`clientId`, `clientSecret`) from your Mobile Calendar account.
{% endstep %}

{% step %}

### Request an access token

Request an access token via `/v1/public/auth/token`.
{% endstep %}

{% step %}

### Store the access token

Store the `accessToken` temporarily (cache or memory).
{% endstep %}

{% step %}

### Use the token

Use it in all subsequent API requests:

```bash
curl -X GET https://api.mobile-calendar.com/v1/reservations \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json"
```

{% endstep %}

{% step %}

### Renew the token

Renew the token before expiration.
{% endstep %}

{% step %}

### Handle unauthorized errors

Handle 401 errors by re-authenticating automatically.
{% endstep %}

{% step %}

### Logging

Log all responses including `ruid` for audit and debugging purposes.
{% endstep %}
{% endstepper %}
