API — Gateway (Marketplace)
Le Gateway est un proxy contrôlé (style RapidAPI/Apify) qui:
- Valide une Marketplace API key (
dk_live_.../dk_test_...) - Applique scopes + rate limits + quotas
- Résout la version d’API (explicit ou default)
- Proxyfie vers l’upstream enregistré (si autorisé)
- Loggue l’usage (latence, status, credits)
Base: /gateway
Authentification
| Header | Exemple |
|---|---|
x-api-key | x-api-key: dk_live_<...> |
Authorization | Authorization: Bearer dk_live_<...> |
Le Gateway renvoie des erreurs structurées via sendError:
{ "ok": false, "code": "...", "error": "...", "requestId": "...", "details": {} }
Routes (direct proxy)
Version explicite
| Méthodes | GET POST PUT PATCH DELETE |
| Path | /gateway/:publisherSlug/:apiSlug/v/:version/* |
Exemple:
curl -X GET "https://<host>/gateway/acme/weather/v/1.0.0/forecast?city=Algiers" -H "x-api-key: dk_live_<...>"
Version par défaut
| Méthodes | GET POST PUT PATCH DELETE |
| Path | /gateway/:publisherSlug/:apiSlug/* |
Si la version n’est pas fournie, le Gateway utilise la version is_default active (sinon la première active).
Scopes (allow-list)
Les scopes sont évalués avant le proxy et s’appliquent à la route relative appelée (ex: /v1/search).
Format supporté:
*autorise toutMETHOD:PATHPATTERNoùMETHODpeut être*PATHPATTERNsupporte*(glob simple)
Exemples:
| Scope | Effet |
|---|---|
* | Tout autoriser |
*:/v1/* | Toute méthode sur /v1/... |
GET:/v1/health | Autoriser uniquement ce GET |
Erreurs:
403SCOPE_DENIED
Headers & body (forwarding)
- Le Gateway retire les hop-by-hop headers et
host/content-length. - Il retire aussi
authorizationetx-api-keyavant l’upstream. - Body: pour
GET/HEAD, aucun body n’est envoyé; sinon le body Express (JSON) est forwardé.
Execution mode
Le Gateway peut bloquer certaines formes d’exécution selon execution_mode (stocké par endpoint):
| Mode | Direct proxy | Runs |
|---|---|---|
direct | autorisé | bloqué (409 DIRECT_REQUIRED) |
run | bloqué (409 RUN_REQUIRED) | autorisé |
both | autorisé | autorisé |
Le matching endpoint supporte :param, {param} et un * final.
Rate limits & quotas
Le Gateway applique plusieurs fenêtres possibles:
- Per-second:
rate_limit - Per-minute:
rate_limit_per_minute - Per-hour:
rate_limit_per_hour - Daily quota:
daily_quota - Monthly quota:
monthly_quota(comparé àrequests_this_period)
Erreurs:
429RATE_LIMIT_EXCEEDED429QUOTA_EXCEEDED
Runs (asynchrone)
Les routes runs existent en version explicite et version default:
/gateway/:publisherSlug/:apiSlug/v/:version/runs.../gateway/:publisherSlug/:apiSlug/runs...
Créer un run
| Méthode | POST |
| Path | /gateway/:publisherSlug/:apiSlug/v/:version/runs |
| Auth | Marketplace API key |
Body
| Champ | Type | Requis | Description |
|---|---|---|---|
method | string | non | GET | POST | PUT | PATCH | DELETE (défaut POST) |
path | string | oui | Chemin relatif upstream (ex: /v1/search). Le matching scopes ignore la query-string |
headers | object | non | Headers envoyés à l’upstream (hors hop-by-hop) |
body | any | non | Body upstream |
webhookUrl | string | non | URL webhook (doit être autorisée par les règles de sécurité) |
webhookHeaders | object | non | Headers webhook |
webhookSecret | string | non | Secret (trim, max ~512) |
Réponse 201
{ "ok": true, "run": { "id": "...", "status": "queued", "created_at": "..." } }
Erreurs (sendError)
| Status | Code | Quand |
|---|---|---|
400 | VALIDATION_ERROR | method non supporté / path manquant / webhookUrl interdite |
401 | MISSING_API_KEY / INVALID_API_KEY | Auth manquante/invalide |
403 | API_KEY_DISABLED / API_KEY_EXPIRED / SUBSCRIPTION_INACTIVE / KEY_API_MISMATCH / SCOPE_DENIED | Accès refusé |
409 | DIRECT_REQUIRED | Endpoint configuré en direct uniquement |
429 | RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED | Limite/quota dépassé |
500 | REQUEST_ERROR | Erreur serveur |
Lister mes runs
| Méthode | GET |
| Path | /gateway/:publisherSlug/:apiSlug/v/:version/runs |
Query parameters
| Nom | Type | Requis | Défaut | Description |
|---|---|---|---|---|
status | string | non | - | Filtre (ex: queued, running, succeeded, failed, cancelled) |
limit | number | non | 20 | 1..100 |
offset | number | non | 0 | Pagination |
Réponse 200
{ "ok": true, "runs": [], "total": 0, "limit": 20, "offset": 0 }
Lire un run
| Méthode | GET |
| Path | /gateway/:publisherSlug/:apiSlug/v/:version/runs/:runId |
Réponse 200
{ "ok": true, "run": { "id": "...", "status": "...", "result_json": null, "error_message": null } }
Erreurs
| Status | Code | Quand |
|---|---|---|
404 | NOT_FOUND | Run introuvable (pas à cette API key) |
Annuler un run
| Méthode | POST |
| Path | /gateway/:publisherSlug/:apiSlug/v/:version/runs/:runId/cancel |
Réponse 200
{ "ok": true, "run": { "id": "...", "status": "cancelled" } }
Note: l’annulation ne s’applique qu’aux runs queued/running.
Événements (JSON)
| Méthode | GET |
| Path | /gateway/:publisherSlug/:apiSlug/v/:version/runs/:runId/events/list |
Query parameters
| Nom | Type | Requis | Défaut | Description |
|---|---|---|---|---|
afterId | number | non | 0 | Retourne les events id > afterId |
limit | number | non | 200 | 1..500 |
Réponse 200
{ "ok": true, "events": [ { "id": 1, "type": "status", "message": "queued", "data": null } ], "afterId": 0, "limit": 200 }
Événements (SSE)
| Méthode | GET |
| Path | /gateway/:publisherSlug/:apiSlug/v/:version/runs/:runId/events |
| Response | text/event-stream |
Query parameters
| Nom | Type | Requis | Description |
|---|---|---|---|
lastEventId | number | non | Reprise à partir de cet id |
Le stream envoie:
event: helloau démarrageevent: ping(heartbeat)- des events typés (
status, etc.) avecid:+data:JSON