# API Manifesto

Our API is more than just endpoints and data - it’s a developer experience. This document outlines the principles, conventions, and policies we follow to ensure our APIs are usable, consistent, and future-proof.

## 📐 Structure & Versioning

* All endpoints support versioning based on header
  * Default versioning is provided for backward compatibility
  * Version format: `VYYYY_MM_DD` (e.g., `V2024_01_18`, `V2024_07_01`)
  ```json
  "Monta-Version": V2024_01_18 // pass to header
  ```
* Breaking changes only occur in explicit new versions
* New features are non-breaking and additive

***

## ▶️ Pagination and Data Access

* Support for two pagination types:

  1. *Offset-based pagination:* This is used for simpler scenarios where you need to navigate through pages with a fixed number of items.

  ```json
  {
      "data": [
          // Array of items
      ],
      "meta": {
          "perPage": 10,  // Number of items per page
          "itemCount": 5, // Number of items in current response
          "total": 100,   // Total number of items available
          "page": 1       // Current page number
      }
  }

  ```

  ii. *Cursor-based pagination* : This is used for large datasets and better performance. Instead of page numbers, it uses cursor values (usually IDs) to navigate through results.
* ```json
  {
      "data": [
          // Array of items
      ],
      "meta": {
          "itemCount": 10,  // Number of items in current response
          "perPage": 50,    // Number of items per page
          "before": "1290", // ID of first item in current page (for backward navigation)
          "after": "456",   // ID of last item in current page (for forward navigation)
      }
  }
  ```

***

## 🧾 Naming Conventions

### Endpoints

* Use **plural nouns** for resources:

Example:

```text
GET /v1/charges  
POST /v1/charges  
DELETE /v1/sites/{id}
```

### Models / Fields

* Single responses are returned directly at the root level without wrapping
* Multiple responses are **always** wrapped in a `data` array (`data: []`)
* The `data` property for multiple responses will always contain an array, never an object
* Even when returning an empty result set, the structure maintains `data: []`
* Use camelCase for JSON keys:

Example:

```
{  
  "teamId": 15,  
  "chargePointId": 2839928 
}
```

### Query Parameters

* Use camelCase for URL Parameters:
* Common parameters:
  * `page`: Page number (zero-based)
  * `perPage`: Items per page
  * `search`: Search term
  * `sort`: Sorting field
  * `order`: Sort order (asc/desc)
  * `filter*`: Filter parameters
  * Temporal filters: , `from` `to`

Example:

```
/api/v1/teams?perPage=20&page=0&sort=createdAt&order=desc

```

***

## 🔐 Authentication

* Bearer token authentication required for all endpoints. *Reference*: [token](/reference/ref-authentication)
* Token format: `Authorization: Bearer <token>`
* Token expiration and refresh mechanism
* Rate limiting per token
* Scope-based access control
* Failed authentication returns 401 Unauthorized
* Invalid permissions returns 403 Forbidden

Example:

```
Authorization: Bearer YOUR_TOKEN_HERE
```

***

## ❗Error Handling

### Error Response Structure

* Consistent error response structure:

```
{
  "status": "HTTP_STATUS",
  "message": "Developer-oriented error message",
  "readableMessage": "User-friendly localized message",
  "errorCode": "SPECIFIC_ERROR_CODE",
  "context": {
    "prop1": "contextual information"
  }
}
```

### Error Codes

The API uses an enumerated set of error codes:

#### Authentication & Authorization

* Authentication failed `UNAUTHORIZED`
* Permission denied `ACCESS_FORBIDDEN`
* Invalid service credentials `INVALID_OR_MISSING_SERVICE_TOKEN`
* Invalid access token `INVALID_ACCESS_TOKEN`
* Invalid refresh token `INVALID_REFRESH_TOKEN`

#### Resource Errors

* Requested resource doesn't exist `RESOURCE_NOT_FOUND`
* Consumer not found `CONSUMER_NOT_FOUND`
* Application not found `APPLICATION_NOT_FOUND`
* Consumer account is disabled `CONSUMER_DISABLED`

#### Request Errors

* Invalid request parameters `BAD_REQUEST`
* Request validation failed `UNPROCESSABLE_ENTITY`

#### System Errors

* Internal server error `INTERNAL_SERVER_ERROR`
* Upstream service error `BAD_GATEWAY`

#### Domain-Specific Errors

* Unable to start charging `CHARGING_FAILED_TO_START`
* Chargepoint is offline `CHARGING_CHARGEPOINT_OFFLINE`
* Chargepoint unavailable `CHARGING_CHARGEPOINT_NOT_AVAILABLE`
* Restart charging failed `CHARGING_FAILED_TO_RESTART`
* Reservation not enabled `CHARGING_CHARGEPOINT_RESERVATION_NOT_ENABLED`

### HTTP Status Codes

| Status Code | Usage                                    |
| ----------- | ---------------------------------------- |
| 400         | Bad Request - Invalid input parameters   |
| 401         | Unauthorized - Authentication required   |
| 403         | Forbidden - Insufficient permissions     |
| 404         | Not Found - Resource doesn't exist       |
| 422         | Unprocessable Entity - Validation failed |
| 500         | Internal Server Error                    |
| 502         | Bad Gateway - Upstream service error     |

***

## ✅ Response Structure

* Success responses

```json
{
  "id": 42,
  // + more resource fields
}
```

* Collection responses

```json
{
  "data": [
    // Array of resources
  ],
  "meta": {
    // Pagination meta data
  }
}
```

## 📢 Deprecation Notice

### Version Lifecycle

* Versions follow VYYYY\_MM\_DD format
* Minimum 6-month support for deprecated versions
* Three phase deprecation:
  1. Announcement
  2. Deprecation period (6 months)
  3. Sunset (version support removed)

### Deprecation Notice

* Deprecation communicated via:
  * Response headers: `X-API-Deprecated: true`
  * `X-API-Sunset-Date` header
  * Documentation updates
  * Email notifications to API consumers
