API REST v1 — JSON

Construisez avec RiLoProxy

Catalogue produits, commerçants, recherche transverse et gestion vendeur (produits, stock, commandes, vidanges, promotions, réservations…). Auth Bearer, quotas clairs, documentation transparente.

01 Présentation

L'API publique d'RiLoProxy est une API REST en JSON. Elle expose deux périmètres :

Consultation publique

Catalogue, fiches produits, boutiques, catégories, recherche. Idéal pour intégrer l'offre locale dans un site, une app, une borne…

Espace vendeur

Gestion produits, stock, commandes, vidanges, promotions, réservations, employés. Strictement scopée à vos magasins.

URL de base : https://enghien.riloweb.be/api/v1

02 Démarrage rapide

  1. Créez un compte sur /inscription et connectez-vous.
  2. Générez une clé depuis /compte/api (client) ou /pro/api (vendeur). Le token est affiché une seule fois — stockez-le immédiatement.
  3. Faites un premier appel :
    curl -H "Authorization: Bearer ep_live_VOTRE_TOKEN" \
         https://enghien.riloweb.be/api/v1/products?limit=5
  4. Vérifiez vos quotas sur GET /me.

03 Authentification

Toutes les routes (sauf POST /auth/login) exigent un Bearer token :

Authorization: Bearer ep_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

En dépannage uniquement, le token peut passer en query : ?api_key=ep_live_… (déconseillé en production).

POST /auth/login

Connexion utilisateur en JSON. Limite stricte : 3 tentatives par email/IP toutes les 15 minutes. Au-delà → 429 too_many_attempts avec Retry-After.

curl -X POST https://enghien.riloweb.be/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"client@example.com","password":"secret"}'

Réponse :

{
  "ok": true,
  "token_type": "Bearer",
  "access_token": "ep_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "api_key_prefix": "ep_live_abcd",
  "user": {
    "id": 1,
    "email": "client@example.com",
    "first_name": "Client",
    "last_name": "Demo",
    "role": "customer"
  }
}

Headers de quota

Chaque réponse renvoie les compteurs courants :

X-RateLimit-Quota: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Per-Minute: 5

04 Format des réponses

Toutes les réponses sont en JSON UTF-8 et incluent toujours ok: true|false.

Succès — liste paginée

{
  "ok": true,
  "items": [...],
  "total": 42,
  "limit": 50,
  "offset": 0
}

Erreur

{
  "ok": false,
  "error": "invalid_token",
  "message": "Jeton API invalide ou révoqué.",
  "details": { ... }
}

05 Codes d'erreur

StatutCodeCause
400invalid_queryParamètre manquant ou malformé.
400empty_payloadAucun champ fourni pour une mise à jour.
401unauthorizedToken manquant.
401invalid_tokenToken invalide ou révoqué.
403monthly_quota_exceededQuota mensuel atteint — passez à la formule supérieure.
403shop_not_ownedVous n'êtes pas propriétaire de ce magasin.
404*_not_foundRessource introuvable ou non publiée.
422validation_failedDonnées invalides (details contient les erreurs par champ).
429rate_limit_exceededDébit dépassé — attendez Retry-After secondes.
429too_many_attemptsTrop d'échecs sur /auth/login.

06 Endpoints publics

Consultation du catalogue et de la recherche. Disponibles avec n'importe quelle clé valide.

POST /auth/login Authentification utilisateur (email + mot de passe). Aucun token requis.
GET /me Informations sur votre clé et votre quota courant.
GET /products Liste paginée des produits publiés. Filtres : q, category, limit, offset.
GET /products/{slug} Fiche produit complète (description, stock, boutique, réservation).
GET /categories Catégories actives avec product_count pré-calculé.
GET /shops Liste des commerçants actifs. Filtres : city, limit, offset.
GET /shops/{slug} Fiche commerçant + jusqu'à 100 produits publiés.
GET /search?q=… Recherche transverse (produits + boutiques + catégories).

Paramètres de GET /products

ParamètreTypeDéfautDescription
qstringRecherche nom / description.
categorystringSlug d'une catégorie.
limitint50Maximum 100.
offsetint0Pagination.

07 Endpoints vendeur

Ces endpoints sont strictement scopés : la clé doit appartenir à un propriétaire ou employé actif du magasin {slug}. Tout accès à un magasin tiers renvoie 403 shop_not_owned. Les employés sont limités par leurs permissions (products.manage, orders.manage, reservations.manage, promotions.manage, ads.manage, employees.manage).

Après POST /auth/login, listez les magasins via GET /shop pour afficher la sélection à l'utilisateur. Si selected_shop est null, l'utilisateur doit choisir un magasin avant d'appeler /shop/{slug}/....

Magasins

GET /shop Liste des magasins accessibles à l'utilisateur.
GET /shop/{slug} Magasin sélectionné + modules autorisés.

Produits

GET /shop/{slug}/products Tous les produits (draft, published, archived).
GET /shop/{slug}/products/{id} Fiche produit complète possédée.
POST /shop/{slug}/products Crée un nouveau produit (name + price requis).
PATCH /shop/{slug}/products/{id} Mise à jour partielle.
DELETE /shop/{slug}/products/{id} Soft delete (archived).

Stock & inventaire

POST /shop/{slug}/products/{id}/stock Définit le stock courant du produit.
GET /shop/{slug}/inventory Liste des mouvements de stock.
POST /shop/{slug}/inventory Enregistre une entrée, sortie ou ajustement.

Commandes

GET /shop/{slug}/orders Liste paginée des commandes (filtre status).
GET /shop/{slug}/orders/{id} Détail d'une commande.
PATCH /shop/{slug}/orders/{id}/status Met à jour le statut de la commande.

StoreServeur

GET /shop/{slug}/storeserver Etat StoreServeur, usage stockage et liens programmes.
GET /shop/{slug}/storeserver/all Toutes les tables et donnees StoreServeur du magasin en JSON.
GET /shop/{slug}/storeserver/export Export StoreServeur en json, csv, sql ou sqlite.
GET /shop/{slug}/storeserver/daily Liste Daily filtrable par dates/heures, code raison et departement.
POST /shop/{slug}/storeserver/daily/add-to-daily Ajoute une ligne Daily d'ajustement depuis un code raison.
GET /shop/{slug}/storeserver/reasons-codes Liste des codes raison.
POST /shop/{slug}/storeserver/reasons-codes Encode ou met a jour un code raison.
DELETE /shop/{slug}/storeserver/reasons-codes/{code} Supprime un code raison.
GET/POST /shop/{slug}/storeserver/expiry-date Historique append-only des dates de peremption.
GET/POST /shop/{slug}/storeserver/rayons Table Rayon locale.
GET/POST /shop/{slug}/storeserver/storein-local Infos locales StoreIn par article.
GET/POST /shop/{slug}/storeserver/tables Tables StoreServeur dynamiques.
GET/POST /shop/{slug}/storeserver/tables/{table}/rows Lignes d'une table dynamique.

Vidanges / cautions

GET /shop/{slug}/deposits Liste des vidanges (q, status, limit, offset).
GET /shop/{slug}/deposits/orders/{id} Détail des vidanges d'une commande.
POST /shop/{slug}/deposits/{itemId}/refund Marque la vidange remboursée + email preuves.

Promotions

GET /shop/{slug}/promotions Liste des promotions du magasin.
POST /shop/{slug}/promotions Crée une promotion.
PATCH /shop/{slug}/promotions/{id} Met à jour une promotion.
DELETE /shop/{slug}/promotions/{id} Supprime une promotion.

Réservations

GET /shop/{slug}/reservations Liste des réservations.
PATCH /shop/{slug}/reservations/{id}/status Met à jour le statut.

Publicité & Sponsorisation

GET /shop/{slug}/ads Liste des publicités.
POST /shop/{slug}/ads Crée une publicité.
GET /shop/{slug}/sponsorships Liste des sponsorisations.
POST /shop/{slug}/sponsorships Crée une sponsorisation.
PATCH /shop/{slug}/sponsorships/{id}/toggle Active/désactive une sponsorisation.

Employés

GET /shop/{slug}/employees Liste des employés.
POST /shop/{slug}/employees Ajoute un employé.
PATCH /shop/{slug}/employees/{id} Met à jour permissions / rôle.
DELETE /shop/{slug}/employees/{id} Retire un employé.

Champs POST /shop/{slug}/products

ChampTypeNotes
name requisstringMax 200 caractères.
price requisnumberEn euros.
stockintDéfaut 0.
compare_at_pricenumberPrix barré.
short_descriptionstringMax 500 caractères.
descriptionstringTexte long, Markdown toléré.
skustringMax 80 caractères.
stock_thresholdintSeuil d'alerte stock (défaut 5).
category_idintVoir /categories.
reservation_enabledboolAutoriser réservation sans paiement.
reservation_window_hoursintFenêtre par défaut 48 h.
not_deliverableboolRetrait uniquement.
statusstringdraft (défaut), published, archived.
has_depositboolActive une vidange / caution remboursable.
deposit_pricenumberMontant de la vidange en euros.
deposit_descriptionstringDescription libre (bouteille, cintre, contenant…).

Exemple — création produit

curl -X POST https://enghien.riloweb.be/api/v1/shop/rich-lo/products \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Café arabica 250g",
    "price": 8.90,
    "stock": 30,
    "category_id": 2,
    "short_description": "Grains fraîchement torréfiés à Enghien",
    "status": "published"
  }'

Exemple — mise à jour partielle

curl -X PATCH https://enghien.riloweb.be/api/v1/shop/rich-lo/products/42 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "price": 9.50, "stock": 45 }'

Exemple — mouvement d'inventaire

{
  "product_id": 12,
  "type": "in",
  "quantity": 5,
  "reason": "Réception fournisseur",
  "reference": "BL-2026-001"
}

Exemple — remboursement de vidange

POST /shop/rich-lo/deposits/142/refund

{
  "method": "cash",
  "reference": "Rendu en boutique"
}

method accepte cash, card ou stripe. Avec stripe, l'API tente un remboursement partiel du montant de la vidange sur le paiement Stripe de la commande.

Exemple StoreServeur all

curl https://enghien.riloweb.be/api/v1/shop/rich-lo/storeserver/all \
  -H "Authorization: Bearer $TOKEN"

08 Modèle de données

Product

{
  "id": 5,
  "slug": "cafe-arabica-250g",
  "name": "Café arabica 250g",
  "short_description": "Grains fraîchement torréfiés",
  "description": "Texte long…",
  "price": 8.90,
  "compare_at_price": 10.90,
  "sku": "ARAB-250",
  "stock": 30,
  "stock_threshold": 5,
  "category_id": 2,
  "status": "published",
  "is_active": true,
  "reservation_enabled": false,
  "reservation_window_hours": 48,
  "not_deliverable": false,
  "published_at": "2026-04-23 15:00:00",
  "updated_at": "2026-04-23 15:00:00",
  "created_at": "2026-04-23 15:00:00",
  "url": "/produit/cafe-arabica-250g"
}

Order (vue vendeur)

{
  "id": 1042,
  "order_number": "EP-2026-04-01042",
  "status": "preparing",
  "payment_status": "paid",
  "payment_method": "card",
  "subtotal": 32.40,
  "delivery_fee": 4.00,
  "total": 36.40,
  "created_at": "2026-04-23 12:48:00",
  "cancelled_at": null
}

Statuts commande : pending, confirmed, preparing, shipped, delivered, cancelled.

09 Pagination & versioning

Les listes acceptent limit (max 100) et offset. La réponse contient total pour calculer le nombre de pages.

GET /api/v1/products?limit=20&offset=40

Versions

L'URL porte la version (/api/v1). En cas de changement incompatible, une /api/v2 sera introduite en parallèle. Les ajouts rétro-compatibles (nouveaux champs optionnels, nouveaux endpoints) sont déployés en v1 sans préavis.

10 Formules & quotas

Démarrez gratuitement. Passez à une formule payante quand votre produit décolle.

API Free

Gratuit

1 000 requêtes/mois, 5 req/min. Parfait pour tester.

  • 1 000 requêtes / mois
  • 5 requêtes / minute
  • Accès à tous les endpoints v1
  • Support communauté
Créer une clé gratuite

API Basic

2,99 €/ mois

10 000 req/mois, 1 000 req/min. Pour petites intégrations.

  • 10 000 requêtes / mois
  • 1 000 requêtes / minute
  • Accès à tous les endpoints v1
  • Support communauté
Souscrire

API Infinite+

10,99 €/ mois

Requêtes mensuelles illimitées, débit illimité.

  • ∞ requêtes / mois
  • ∞ requêtes / minute
  • Accès à tous les endpoints v1
  • Support communauté
Souscrire

11 Support

Équipe Enghien

Bug, question, suggestion : /support — réponse rapide, équipe basée à Enghien.

Vos clés API

Gérez et révoquez vos tokens depuis /compte/api.

Doc Markdown

La référence est aussi disponible en api.md dans le dépôt.