Référence API
API publique Couverty
Accédez à vos données et intégrez Couverty dans vos applications.
Démarrage rapide
Créez une clé API et commencez à utiliser l'API en 3 étapes.
- 1
Créer une clé API
Accédez à vos paramètres d'intégration. Cliquez sur "Créer une clé API" et sélectionnez les permissions requises (restaurant:read, menu:read, etc). - 2
Copier la clé
Copiez la clé API générée. Assurez-vous de la stocker en sécurité. Vous ne pourrez plus la voir après avoir fermé le dialog. - 3
Faire des requêtes
Utilisez la clé dans le headerX-API-Keypour authentifier vos requêtes.
Authentification
Trois méthodes pour authentifier vos requêtes.
Méthode 1 : Header X-API-Key (Recommandé)
La méthode la plus simple et la plus sécurisée.
curl -H "X-API-Key: qr_your_api_key_here" \ https://api.couverty.ch/api/public/v1/restaurant
Méthode 2 : Authorization Bearer
Alternative utilisant le header Authorization standard.
curl -H "Authorization: Bearer qr_your_api_key_here" \ https://api.couverty.ch/api/public/v1/restaurant
Méthode 3 : Paramètre de requête (3CX uniquement)
Uniquement pour les intégrations 3CX qui ne peuvent pas utiliser les headers.
curl https://api.couverty.ch/api/integrations/3cx/lookup?apikey=qr_your_api_key_here&phone=%2B41...
Sécurité
Permissions
restaurant:read, menu:read, etc. Les requêtes échoueront si votre clé n'a pas la permission requise.Endpoints API v1
Accédez aux données de votre restaurant avec authentification par clé API.
GET /api/public/v1/restaurant
Récupère les informations du restaurant (nom, contact, horaires, branding).
/api/public/v1/restaurantExemple de réponse
{
"success": true,
"data": {
"name": "Le Restaurant",
"slug": "le-restaurant",
"contact": {
"email": "contact@example.com",
"telephone": "+41 22 123 45 67",
"address": {
"rue": "10 Rue de la Paix",
"npaVille": "1200 Genève",
"pays": "Suisse"
}
},
"hours": {
"midi": {
"enabled": true,
"ouverture": "11:30",
"fermeture": "14:30",
"jours": [1, 2, 3, 4, 5]
},
"soir": {
"enabled": true,
"ouverture": "18:30",
"fermeture": "23:00",
"jours": [0, 1, 2, 3, 4, 5, 6]
}
},
"social": {
"website": "https://example.com",
"facebook": "https://facebook.com/restaurant",
"instagram": "https://instagram.com/restaurant",
"tiktok": null,
"googleReview": null,
"tripadvisor": null
},
"branding": {
"primaryColor": "#B91C1C",
"secondaryColor": "#D4AF37",
"logoUrl": "https://example.com/logo.png",
"coverImageUrl": "https://example.com/cover.png"
}
},
"meta": {
"tenantId": "tenant_123",
"fetchedAt": "2026-03-13T10:30:00Z"
}
}GET /api/public/v1/menu
Récupère le menu complet (plats et boissons) avec catégories et menu de la semaine.
/api/public/v1/menutype: all | plats | boissons (défaut: all)includeHidden: true | false (défaut: false)
Exemple de réponse
{
"success": true,
"data": {
"plats": {
"categories": [
{
"id": "cat_123",
"nom": "Entrées",
"description": null,
"plats": [
{
"id": "plat_456",
"nom": "Salade César",
"description": "Salade fraîche avec croutons",
"prix": 18.50,
"imageUrl": "https://example.com/salade.jpg",
"allergenes": ["gluten", "oeuf"],
"vegetarien": true,
"vegan": false,
"sansGluten": false
}
]
}
],
"totalPlats": 45,
"totalCategories": 5
},
"boissons": {
"categories": [
{
"id": "cat_789",
"nom": "Vins rouges",
"description": "Sélection de vins rouges",
"boissons": [
{
"id": "boi_321",
"nom": "Côtes du Rhône",
"description": "AOC 2020",
"prix": 35.00,
"volume": "75cl",
"region": "Rhône",
"annee": 2020
}
]
}
],
"totalBoissons": 30,
"totalCategories": 4
},
"menuSemaine": {
"config": { ... },
"menus": [ ... ]
}
},
"meta": {
"tenantId": "tenant_123",
"fetchedAt": "2026-03-13T10:30:00Z"
}
}Endpoints publics par slug
Accédez à la disponibilité, configuration et menu sans authentification. Utilisés par le widget.
Disponibilité générale
https://restaurant.qr-menu.ch/book/[slug]Configuration & Paramètres
/api/public/[slug]/configConfiguration restaurant pour le widget (horaires, créneaux, capacités). Cache : 5 min CDN, 1 min navigateur.
Champs retournés
horairesActifs, serviceMidiActif, serviceSoirActif
creneauxMidiConfig, creneauxSoirConfig
modeCapacite, capaciteMidi, capaciteSoir
joursOuvertsMidi, joursOuvertsSoir
Et 40+ autres champs (voir réponse complète)
/api/public/[slug]/settingsParamètres publics du restaurant (nom, contact, couleurs, réseaux sociaux). Cache : 5 min CDN, 1 min navigateur.
Disponibilité
/api/public/[slug]/availabilityVérifie si une date/service/heure est disponible. Cache : 2 min.
date: YYYY-MM-DD (requis)service: midi | soir (requis)heure: HH:mm (optionnel)personnes: nombre (défaut: 2)
/api/public/[slug]/creneauxListe les créneaux horaires disponibles avec info de capacité. Cache : 1 min.
date: YYYY-MM-DD (requis)service: midi | soir (requis)personnesounombrePersonnes: nombre (défaut: 2)
Menu & Boissons
/api/public/[slug]/menuMenu complet avec catégories et plats visibles. Cache : 10 min.
/api/public/[slug]/boissonsCarte des boissons avec catégories. Cache : 10 min.
/api/public/[slug]/fermeturesJours de fermeture à venir (vacances, événements privés). Cache : 10 min.
Réservations
/api/public/[slug]/reservationsCrée une nouvelle réservation. Rate limit : 20 req/min par IP.
prenom: string (requis)nom: string (requis)email: string (requis)telephone: string (requis)dateReservation: YYYY-MM-DD (requis)service: midi | soir (requis)nombrePersonnes: number (requis)heureReservation: HH:mm (optionnel)commentaires: string (optionnel)
Exemple de réponse
{
"success": true,
"data": {
"id": "res_123abc",
"prenom": "Jean",
"nom": "Dupont",
"email": "jean@example.com",
"telephone": "+41 79 123 45 67",
"dateReservation": "2026-03-20",
"service": "soir",
"nombrePersonnes": 4,
"heureReservation": "19:30",
"statut": "PENDING",
"createdAt": "2026-03-13T10:30:00Z"
}
}Intégration 3CX
Récupérez les données client et rapportez les appels.
Configuration requise
3cx:lookup et3cx:report./api/integrations/3cx/lookupRecherche un client par numéro de téléphone. Retourne les informations et enrichissement (visites, no-shows).
phone: string au format E.164 (requis) ex: +41791234567
/api/integrations/3cx/report-callRapporte un appel (entrant, sortant, manqué). Crée une notification si appel manqué.
phoneNumber: string E.164 (requis)callType: Inbound | Outbound | Missed | Notanswered (requis)durationSeconds: number (optionnel)callDateTime: ISO 8601 (optionnel)agent: string (optionnel)
Format des réponses
Toutes les réponses API suivent un format standardisé.
Réponse réussie (2xx)
{
"success": true,
"data": {
// Les données demandées
},
"meta": {
"tenantId": "tenant_123",
"fetchedAt": "2026-03-13T10:30:00Z"
}
}Réponse d'erreur
{
"success": false,
"error": "Message d'erreur descriptif"
}Erreurs & Limites
Codes d'erreur, rate limits et troubleshooting.
Codes d'erreur HTTP
| Code | Signification | Exemple |
|---|---|---|
| 200 | OK - Requête réussie | Données retournées |
| 400 | Bad Request - Paramètres invalides | Date manquante |
| 401 | Unauthorized - Clé API manquante/invalide | API key expiré |
| 403 | Forbidden - Permission insuffisante | menu:read manquant |
| 404 | Not Found - Ressource inexistante | Restaurant introuvable |
| 429 | Too Many Requests - Rate limit atteint | Trop de requêtes/min |
| 500 | Internal Server Error | Erreur serveur |
Rate limits
API v1
1000 requêtes par heure par clé API
Endpoints publics
Pas de limite stricte, utilise le cache CDN (5-10 min)
POST Réservations
20 requêtes par minute par adresse IP
3CX
1000 requêtes par heure par clé API
En-têtes de cache
Les endpoints publics incluent les en-têtes Cache-Control pour optimiser la performance :
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=60 - max-age: Cache navigateur (en secondes) - s-maxage: Cache CDN (en secondes) - stale-while-revalidate: Servir ancien contenu pendant revalidation
Troubleshooting
401 Unauthorized - API key is required
Assurez-vous que :
- Vous avez créé une clé API dans vos paramètres
- Vous envoyez la clé dans le header
X-API-Key - La clé n'a pas expiré ou été révoquée
403 Forbidden - Missing required permission
La clé API n'a pas les permissions requises :
- Régénérez la clé avec les bonnes permissions in vos paramètres
- Vérifiez que l'endpoint ne nécessite pas d'authentification
429 Too Many Requests
Vous avez atteint le rate limit :
- Attendez quelques secondes avant de réessayer
- Implémentez un backoff exponentiel dans votre code
- Utilisez le cache pour réduire le nombre de requêtes
CORS errors
Les endpoints publics ([slug]) supportent CORS pour le widget. Si vous avez des erreurs CORS :
- Utilisez ces endpoints uniquement depuis le navigateur, pas depuis un serveur privé
- Pour les appels serveur-à-serveur, utilisez les endpoints v1 avec clé API
Exemples de code
Exemples complets dans plusieurs langages pour commencer rapidement.
Récupérer les infos du restaurant
const API_KEY = process.env.COUVERTY_API_KEY;
const API_BASE = 'https://api.couverty.ch';
async function getRestaurantInfo() {
try {
const response = await fetch(`${API_BASE}/api/public/v1/restaurant`, {
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (!result.success) {
throw new Error(result.error);
}
console.log('Restaurant:', result.data);
return result.data;
} catch (error) {
console.error('Erreur:', error.message);
throw error;
}
}
async function getMenu() {
try {
const response = await fetch(
`${API_BASE}/api/public/v1/menu?type=plats&includeHidden=false`,
{
headers: { 'X-API-Key': API_KEY },
}
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
return result.data;
} catch (error) {
console.error('Erreur:', error.message);
throw error;
}
}
// Utilisation
(async () => {
const restaurant = await getRestaurantInfo();
const menu = await getMenu();
})();