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

# API Conventions

> Understand Minimo API structure, response formats, and common patterns

## Base URL

The Minimo API is served from two base URLs, depending on the endpoint:

| Server         | Base URL                | Endpoints                            |
| -------------- | ----------------------- | ------------------------------------ |
| **New API**    | `https://api.minimo.it` | Contacts, WhatsApp, Custom Fields    |
| **Legacy API** | `https://app.minimo.it` | Email templates, Messages, Campaigns |

**Example Endpoints**:

```
POST https://api.minimo.it/public/v1/contacts
GET  https://api.minimo.it/public/v1/templates/whatsapp
GET  https://app.minimo.it/api/templates/email
```

<Info>All requests must use HTTPS. HTTP requests will be rejected.</Info>

<Note>
  New endpoints are being progressively migrated to `api.minimo.it`. Each endpoint's documentation page specifies the
  correct base URL.
</Note>

## Request Format

### Content Type

All POST, PUT, and PATCH requests must include the `Content-Type` header:

```bash theme={null}
Content-Type: application/json
```

### Request Body

Request bodies should be valid JSON:

```json theme={null}
{
  "email": "customer@example.com",
  "firstName": "Jane",
  "customFields": {
    "company": "Acme Corp",
    "plan": "enterprise"
  }
}
```

## Response Format

### Success Response

Successful requests return appropriate HTTP status codes and JSON responses:

**Example (200 OK)**:

```json theme={null}
{
  "id": "cnt_abc123",
  "email": "customer@example.com",
  "firstName": "Jane",
  "lastName": "Doe",
  "createdAt": "2025-11-13T10:30:00Z",
  "updatedAt": "2025-11-13T10:30:00Z"
}
```

### Error Response

Errors return a consistent structure:

```json theme={null}
{
  "error": {
    "code": "validation_error",
    "message": "Invalid email address format",
    "details": {
      "field": "email",
      "value": "invalid-email"
    }
  }
}
```

**Error Object Fields**:

* `code`: Machine-readable error identifier
* `message`: Human-readable error description
* `details`: Additional context (optional)

## HTTP Status Codes

The Minimo API uses standard HTTP status codes:

| Code  | Meaning               | Description                          |
| ----- | --------------------- | ------------------------------------ |
| `200` | OK                    | Request succeeded                    |
| `201` | Created               | Resource successfully created        |
| `400` | Bad Request           | Invalid request format or parameters |
| `401` | Unauthorized          | Missing or invalid API key           |
| `403` | Forbidden             | API key lacks required permissions   |
| `404` | Not Found             | Resource doesn't exist               |
| `422` | Unprocessable Entity  | Validation error (invalid data)      |
| `429` | Too Many Requests     | Rate limit exceeded                  |
| `500` | Internal Server Error | Server error (contact support)       |
| `503` | Service Unavailable   | Temporary service disruption         |

## Common Error Codes

| Error Code              | HTTP Status | Description                            |
| ----------------------- | ----------- | -------------------------------------- |
| `unauthorized`          | 401         | Invalid or missing API key             |
| `forbidden`             | 403         | Insufficient permissions               |
| `not_found`             | 404         | Resource not found                     |
| `validation_error`      | 422         | Invalid input data                     |
| `rate_limit_exceeded`   | 429         | Too many requests                      |
| `template_not_approved` | 422         | WhatsApp template not approved by Meta |
| `invalid_phone_number`  | 422         | Phone number format invalid            |
| `duplicate_resource`    | 409         | Resource already exists                |

## Pagination

List endpoints support pagination using query parameters:

### Parameters

* `page`: Page number (default: `1`)
* `limit`: Items per page (default: `25`, max: `100`)

### Example Request

```bash theme={null}
GET /v1/contacts?page=2&limit=50
```

### Response Structure

```json theme={null}
{
  "data": [
    { "id": "cnt_1", "email": "user1@example.com" },
    { "id": "cnt_2", "email": "user2@example.com" }
  ],
  "pagination": {
    "page": 2,
    "limit": 50,
    "total": 150,
    "totalPages": 3,
    "hasNext": true,
    "hasPrevious": true
  }
}
```

**Pagination Fields**:

* `page`: Current page number
* `limit`: Items per page
* `total`: Total number of items
* `totalPages`: Total number of pages
* `hasNext`: Whether there's a next page
* `hasPrevious`: Whether there's a previous page

## Filtering & Sorting

### Filtering (Coming Soon)

Some endpoints support filtering using query parameters:

```bash theme={null}
GET /v1/contacts?tag=vip&status=active
```

### Sorting (Coming Soon)

Use the `sort` parameter to order results:

```bash theme={null}
GET /v1/contacts?sort=-createdAt
# - prefix for descending, + or no prefix for ascending
```

## Timestamps

All timestamps are returned in ISO 8601 format (UTC):

```json theme={null}
{
  "createdAt": "2025-11-13T10:30:00Z",
  "updatedAt": "2025-11-13T14:45:30Z"
}
```

## Idempotency

Some endpoints support idempotency keys to prevent duplicate operations:

```bash theme={null}
POST /v1/contacts
Idempotency-Key: unique-key-12345
```

<Tip>Use idempotency keys when retrying failed requests to avoid creating duplicates.</Tip>

## Rate Limiting

### Headers

All responses include rate limit information:

```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699889400
```

* `X-RateLimit-Limit`: Maximum requests per window
* `X-RateLimit-Remaining`: Requests remaining in current window
* `X-RateLimit-Reset`: Unix timestamp when limit resets

### Handling Rate Limits

When you exceed the rate limit, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please retry after 60 seconds.",
    "retry_after": 60
  }
}
```

**Best Practices**:

1. Monitor `X-RateLimit-Remaining` header
2. Implement exponential backoff
3. Respect the `Retry-After` header value
4. Cache responses when possible

## Versioning

The current API version is **v1**.

* **New API** (`api.minimo.it`): The version prefix `/v1/` is **required** in all paths.
* **Legacy API** (`app.minimo.it`): Paths use the `/api/` prefix without version number.

```
# New API - version prefix required
POST https://api.minimo.it/public/v1/contacts

# Legacy API - no version prefix
GET  https://app.minimo.it/api/templates/email
```

## CORS (Cross-Origin Requests)

The Minimo API supports CORS for client-side requests. However, we recommend making API calls from your server to keep API keys secure.

Allowed origins are configurable per API key in your dashboard settings.

## Webhooks (Coming Soon)

Minimo will support webhooks for real-time event notifications:

* Message delivered
* Message failed
* Contact created/updated
* Template approved/rejected

Documentation will be added when webhooks are available.

## Testing

### Test Mode (Coming Soon)

Use test mode to experiment without affecting production data:

```bash theme={null}
Authorization: Bearer mn-test-abc123-xyz789
```

Test API keys start with `mn-test-` prefix.

## Need Help?

If you encounter unexpected behavior or have questions about API conventions:

* Email: [info@minimo.it](mailto:info@minimo.it)
* Check [API Status](https://status.minimo.it) for known issues
