# Accès API Xpeditis — Documentation

> **Disponible sur :** plans **Gold** et **Platinium** uniquement.
> Les plans Bronze et Silver n'ont accès qu'au frontend Xpeditis.

---

## Table des matières

1. [Vue d'ensemble](#vue-densemble)
2. [Authentification par clé API](#authentification-par-clé-api)
3. [Gestion des clés API](#gestion-des-clés-api)
   - [Générer une clé](#générer-une-clé)
   - [Lister les clés](#lister-les-clés)
   - [Révoquer une clé](#révoquer-une-clé)
4. [Utiliser l'API](#utiliser-lapi)
5. [Sécurité et bonnes pratiques](#sécurité-et-bonnes-pratiques)
6. [Limites et quotas](#limites-et-quotas)
7. [Codes d'erreur](#codes-derreur)
8. [Exemples d'intégration](#exemples-dintégration)

---

## Vue d'ensemble

L'accès API permet aux abonnés **Gold** et **Platinium** d'intégrer Xpeditis directement dans leurs systèmes (ERP, TMS, scripts d'automatisation, etc.) sans passer par l'interface web.

### Deux méthodes d'authentification coexistent

| Méthode | En-tête HTTP | Disponible pour |
|---|---|---|
| **JWT Bearer** (frontend) | `Authorization: Bearer <token>` | Tous les plans |
| **Clé API** (accès programmatique) | `X-API-Key: <clé>` | Gold + Platinium uniquement |

Les deux méthodes donnent accès aux mêmes endpoints. La clé API ne nécessite pas de session interactive.

---

## Authentification par clé API

### Format de la clé

```
xped_live_<64 caractères hexadécimaux>
```

Exemple :
```
xped_live_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
```

### Utilisation dans une requête

Ajoutez l'en-tête `X-API-Key` à chaque requête :

```http
GET /api/v1/bookings HTTP/1.1
Host: api.xpeditis.com
X-API-Key: xped_live_a1b2c3d4e5f6...
Content-Type: application/json
```

### Comportement du serveur

1. Le serveur détecte l'en-tête `X-API-Key`.
2. Il calcule le hash SHA-256 de la clé et le compare à la base de données.
3. Il vérifie que la clé est active et non expirée.
4. Il vérifie **en temps réel** que l'organisation possède toujours un abonnement Gold ou Platinium.
5. Si tout est valide, la requête est authentifiée.

> Si votre abonnement est rétrogradé sous Gold, vos clés API seront automatiquement refusées même si elles sont techniquement encore actives.

---

## Gestion des clés API

Les endpoints de gestion des clés nécessitent une **authentification JWT** (via le frontend ou un token Bearer). Ils ne sont pas accessibles avec une clé API elle-même.

**Base URL :** `http://localhost:4000` (développement) ou `https://api.xpeditis.com` (production)

---

### Générer une clé

```http
POST /api-keys
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "name": "Intégration ERP Production",
  "expiresAt": "2027-01-01T00:00:00.000Z"
}
```

**Corps de la requête :**

| Champ | Type | Requis | Description |
|---|---|---|---|
| `name` | string | ✅ | Nom identifiant la clé (max 100 caractères) |
| `expiresAt` | string (ISO 8601) | ❌ | Date d'expiration. Si absent, la clé n'expire pas. |

**Réponse `201 Created` :**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Intégration ERP Production",
  "keyPrefix": "xped_live_a1b2c3d4",
  "isActive": true,
  "lastUsedAt": null,
  "expiresAt": "2027-01-01T00:00:00.000Z",
  "createdAt": "2025-03-26T10:00:00.000Z",
  "fullKey": "xped_live_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
}
```

> ⚠️ **Le champ `fullKey` n'est retourné qu'une seule fois.** Copiez-le immédiatement et stockez-le de façon sécurisée (gestionnaire de secrets, variables d'environnement chiffrées, etc.). Il ne sera plus jamais visible.

---

### Lister les clés

```http
GET /api-keys
Authorization: Bearer <access_token>
```

**Réponse `200 OK` :**

```json
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Intégration ERP Production",
    "keyPrefix": "xped_live_a1b2c3d4",
    "isActive": true,
    "lastUsedAt": "2025-03-25T14:30:00.000Z",
    "expiresAt": "2027-01-01T00:00:00.000Z",
    "createdAt": "2025-03-26T10:00:00.000Z"
  },
  {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "name": "Script de reporting mensuel",
    "keyPrefix": "xped_live_b2c3d4e5",
    "isActive": false,
    "lastUsedAt": "2025-02-01T09:00:00.000Z",
    "expiresAt": null,
    "createdAt": "2025-01-15T08:00:00.000Z"
  }
]
```

> Les clés complètes ne sont jamais retournées dans cet endpoint. Seul le préfixe est visible.

---

### Révoquer une clé

```http
DELETE /api-keys/{id}
Authorization: Bearer <access_token>
```

**Réponse `204 No Content`** en cas de succès.

> La révocation est **immédiate et irréversible**. Toute requête utilisant cette clé sera refusée à partir de cet instant. Pour réactiver l'accès, créez une nouvelle clé.

---

## Utiliser l'API

Une fois votre clé générée, vous pouvez l'utiliser sur tous les endpoints de l'API Xpeditis.

### Exemple : Récupérer les bookings

```http
GET /bookings
X-API-Key: xped_live_a1b2c3d4e5f6...
```

### Exemple : Créer un booking

```http
POST /bookings
X-API-Key: xped_live_a1b2c3d4e5f6...
Content-Type: application/json

{
  "rateQuoteId": "...",
  ...
}
```

### Référence complète

La documentation Swagger interactive est disponible à :
```
http://localhost:4000/api/docs
```

Elle liste tous les endpoints disponibles avec leurs paramètres et schémas de réponse.

---

## Sécurité et bonnes pratiques

### Stockage des clés

- ❌ Ne stockez **jamais** une clé API en dur dans votre code source ou vos dépôts Git.
- ✅ Utilisez des **variables d'environnement** (`XPEDITIS_API_KEY=xped_live_...`).
- ✅ Utilisez un **gestionnaire de secrets** (AWS Secrets Manager, HashiCorp Vault, etc.) en production.

### Rotation des clés

Effectuez une rotation régulière de vos clés :
1. Créez une nouvelle clé (sans supprimer l'ancienne).
2. Mettez à jour votre système avec la nouvelle clé.
3. Vérifiez que tout fonctionne.
4. Révoquez l'ancienne clé.

### Rotation d'urgence

En cas de compromission suspectée :
1. Révoquez immédiatement la clé compromise via `DELETE /api-keys/{id}`.
2. Créez une nouvelle clé.
3. Auditez vos logs d'accès.

### Permissions

Une clé API agit au nom de l'utilisateur qui l'a créée, avec son rôle (MANAGER, USER, etc.) et les permissions de son organisation. Les clés héritent des restrictions d'accès de l'utilisateur créateur.

---

## Limites et quotas

| Limite | Valeur |
|---|---|
| Nombre de clés actives par organisation | 20 |
| Longueur du nom d'une clé | 100 caractères max |
| Rate limiting | Identique aux autres requêtes API |

Le rate limiting est appliqué par utilisateur (basé sur l'ID utilisateur associé à la clé).

---

## Codes d'erreur

| Code HTTP | Description | Solution |
|---|---|---|
| `401 Unauthorized` | Clé invalide, expirée ou révoquée | Vérifiez la clé ou créez-en une nouvelle |
| `401 Unauthorized` | Clé bien formée mais hash inconnu | La clé a peut-être été révoquée ou n'existe pas |
| `403 Forbidden` | Abonnement insuffisant | Passez au plan Gold ou Platinium |
| `403 Forbidden` | Abonnement rétrogradé après création de la clé | Mettez à niveau votre abonnement |
| `404 Not Found` | Clé introuvable lors d'une révocation | Vérifiez l'ID de la clé |

---

## Exemples d'intégration

### cURL

```bash
# Lister les bookings
curl -X GET https://api.xpeditis.com/bookings \
  -H "X-API-Key: xped_live_votre_cle_ici" \
  -H "Content-Type: application/json"
```

### Node.js / TypeScript

```typescript
const XPEDITIS_API_KEY = process.env.XPEDITIS_API_KEY;
const BASE_URL = 'https://api.xpeditis.com';

async function getBookings() {
  const response = await fetch(`${BASE_URL}/bookings`, {
    headers: {
      'X-API-Key': XPEDITIS_API_KEY!,
      'Content-Type': 'application/json',
    },
  });

  if (!response.ok) {
    throw new Error(`Xpeditis API error: ${response.status}`);
  }

  return response.json();
}
```

### Python

```python
import os
import requests

API_KEY = os.environ['XPEDITIS_API_KEY']
BASE_URL = 'https://api.xpeditis.com'

def get_bookings():
    response = requests.get(
        f'{BASE_URL}/bookings',
        headers={
            'X-API-Key': API_KEY,
            'Content-Type': 'application/json',
        }
    )
    response.raise_for_status()
    return response.json()
```

### PHP

```php
$apiKey = getenv('XPEDITIS_API_KEY');
$baseUrl = 'https://api.xpeditis.com';

$ch = curl_init("$baseUrl/bookings");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "X-API-Key: $apiKey",
    'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
```

---

*Documentation Xpeditis — Accès API v1.0*
*Disponible uniquement sur les plans Gold (899 €/mois) et Platinium (sur devis)*
