Documentation développeur
Intégrez l'estimateur tarifaire et le système de réservation vtcOS sur votre site en quelques minutes. Deux options : le widget JS (le plus simple) ou l'API REST (contrôle total).
Widget JS
Shadow DOM, 6 ko gzippé, aucune dépendance, thème personnalisable. À privilégier pour une intégration rapide.
API REST
JSON sur HTTPS, idempotence, rate limit clair. À privilégier si vous construisez votre propre UX.
Widget — Quickstart
Ajoutez un <div> cible, puis le script du widget :
<div id="vtc-widget"></div> <script src="https://vtcos.upradar.cloud/widget.js" data-api-key="vtc_pk_live_XXXXXXXXXXX" data-target="#vtc-widget"></script>
C'est tout. Le widget s'affiche, charge vos véhicules et vos tarifs, gère l'autocomplétion d'adresse Google Maps et l'estimation en temps réel.
Une clé publique live (vtc_pk_live_…) est obligatoire. Utilisez vtc_pk_test_… pour les tests (n'entame pas les crédits).
Attributs du widget
| Attribut | Défaut | Description |
|---|---|---|
data-api-key | — | Obligatoire. Clé publique vtc_pk_live_… ou vtc_pk_test_…. |
data-api-url | https://app.vtcos.upradar.cloud/api | URL de l'API (à ne changer qu'en self-hosting). |
data-target | — | Sélecteur CSS où injecter le widget (ex. #vtc-widget). |
data-theme | dark | light ou dark. |
data-primary-color | #508ff8 | Couleur principale (CTA, accents). |
data-font-family | 'Inter', sans-serif | Police à utiliser. |
data-border-radius | 16px | Rayon des angles. |
data-logo-url | — | URL du logo affiché en haut. |
data-restrict-country | fr | Code pays pour l'autocomplétion (ex. fr, be). |
data-show-breakdown | true | Afficher le détail du prix (prise en charge, km, min…). |
data-show-powered-by | true | Afficher « Propulsé par vtcOS ». |
data-enable-booking | true | Bouton « Réserver » après estimation. |
data-cta-type | none | CTA complémentaire : link, tel, webhook, none. |
data-cta-value | — | Valeur du CTA (URL, numéro, endpoint webhook). |
data-cta-label | Réserver | Libellé du bouton CTA. |
data-lang | fr | Langue de l'UI. |
Événements JS du widget
Le widget émet des événements DOM personnalisés que vous pouvez intercepter pour analytics ou automation :
const vtc = document.querySelector('vtc-calculator-widget'); vtc.addEventListener('vtc:estimate', (e) => { console.log('Estimation reçue', e.détail); // e.détail = { price, route, vehicle_id, ... } }); vtc.addEventListener('vtc:booking_submitted', (e) => { // Tracking conversion GA4 / Meta Pixel dataLayer.push({ event: 'vtc_booking', email: e.détail.email }); }); vtc.addEventListener('vtc:cta_click', (e) => { // Bouton CTA cliqué });
| Événement | Détails |
|---|---|
vtc:estimate | EstimateResult (prix, route, options, vehicle_id, is_test). |
vtc:booking_submitted | { email, name } — après envoi de la demande de réservation. |
vtc:cta_click | Dernière estimation — déclenché au clic sur le bouton CTA configuré. |
Thème & couleurs
Le widget utilise un Shadow DOM : ses styles sont isolés du reste de votre site. Vous customisez via les attributs data-* sans risque de conflit CSS.
<script src="https://vtcos.upradar.cloud/widget.js" data-api-key="vtc_pk_live_XXX" data-target="#vtc-widget" data-theme="dark" data-primary-color="#e6c364" data-font-family="'Playfair Display', serif" data-border-radius="12px" data-logo-url="https://monsite.com/logo.png"></script>
CSP & CORS
Si votre site utilise une Content Security Policy stricte, autorisez :
Content-Security-Policy: script-src 'self' https://vtcos.upradar.cloud; connect-src 'self' https://app.vtcos.upradar.cloud https://maps.googleapis.com; img-src 'self' data: https://*; font-src 'self' https://fonts.gstatic.com; style-src 'self' 'unsafe-inline';
Le CORS de l'API vtcOS est ouvert (origin *) sur les endpoints publics protégés par clé API. Les clés publiques limitent l'accès au seul domaine que vous avez déclaré dans Paramètres → Clés API → Domaines autorisés.
API REST — URL de base
https://app.vtcos.upradar.cloud/api/v1
Toutes les réponses sont en JSON, encodage UTF-8. HTTPS obligatoire.
Authentification
Deux types de clés :
- Clé publique (
vtc_pk_live_…) : utilisable depuis le navigateur, restreinte aux domaines autorisés. - Clé secrète (
vtc_sk_live_…) : uniquement côté serveur, ne jamais exposer.
Passez la clé dans l'en-tête Authorization :
Authorization: Bearer vtc_pk_live_XXXXXXXXXXXXXXX
Alternative : en-tête X-API-Key, ou paramètre ?api_key=… pour les webhooks.
POST /v1/estimate
Calcule le prix d'une course. Consomme un crédit (sauf clés _test_).
Requête
POST /v1/estimate HTTP/1.1 Host: app.vtcos.upradar.cloud/api Authorization: Bearer vtc_pk_live_XXX Content-Type: application/json { "origin": { "address": "15 Avenue des Champs-Élysées, Paris" }, "destination": { "address": "Aéroport Charles-de-Gaulle, Roissy" }, "departure_datetime": "2026-05-17T08:30:00", "vehicle_id": "uuid-du-vehicule", "options": ["child_seat"] }
Origine et destination acceptent soit address (string), soit lat/lng (nombres).
Réponse
{
"request_id": "c3f5a1e2-...",
"price": {
"amount_ht": 85.50,
"currency": "EUR",
"détails": { "baseFare": 5, "distanceCost": 36.5, "timeCost": 24, ... }
},
"route": {
"distance_km": 24.3,
"duration_min": 45,
"origin": { "lat": 48.8698, "lng": 2.3076 },
"destination": { "lat": 49.0097, "lng": 2.5479 }
},
"vehicle_id": "uuid-du-vehicule",
"departure_datetime": "2026-05-17T08:30:00",
"options": ["child_seat"],
"is_test": false
}
En-tête de réponse : X-Request-ID (identifiant unique de la requête).
GET /v1/vehicles
Liste les véhicules actifs du compte (pour affichage dans votre UI).
{
"vehicles": [
{
"id": "uuid",
"brand": "Mercedes",
"model": "Classe E",
"version": "AMG",
"color": "Noir",
"registration": "AB-123-CD",
"photoUrls": ["https://..."],
"sortOrder": 1
}
]
}
GET /v1/places/*
Proxy Google Maps — pas de clé à exposer dans votre frontend.
Autocomplete
GET /v1/places/autocomplete?query=paris&country=fr // Réponse { "predictions": [{ "description": "Paris, France", "place_id": "..." }] }
Reverse geocode
GET /v1/places/reverse-geocode?lat=48.8566&lng=2.3522 // Réponse { "address": "Rue de Rivoli, 75001 Paris, France" }
POST /v1/booking/submit
Soumet une demande de réservation (statut provisoire). Déclenche :
- Un email au VTC avec lien vers la demande.
- Un email de confirmation au client avec mention « statut provisoire ».
POST /v1/booking/submit Authorization: Bearer vtc_pk_live_XXX Content-Type: application/json { "pickupDate": "2026-05-18T10:00:00", "pickupAddress": "15 Avenue des Champs-Élysées, Paris", "dropoffAddress": "Aéroport Charles-de-Gaulle", "clientName": "Jean Dupont", "clientEmail": "jean@example.com", "clientPhone": "+33612345678", "vehicleId": "uuid-optionnel", "estimatePrice": 85.50, "message": "2 passagers + 3 bagages", "options": ["child_seat"] }
La réservation est créée en statut RECEIVED. Le VTC la valide depuis son dashboard ; le client reçoit ensuite un email de confirmation ou de refus.
GET /v1/usage
Retourne l'état des crédits et des paliers de tarification. Clé secrète requise.
{
"balanceHt": 24.30,
"monthlyEstimates": 47,
"monthlyTotalHt": 14.10,
"activeTier": "T1",
"tierPriceHt": 0.30,
"tiers": [
{ "name": "T1", "from": 0, "to": 100, "priceHt": 0.30, "active": true },
...
]
}
POST /v1/webhook/cta
Le widget peut déclencher un webhook vers votre système quand le client clique le CTA, via l'attribut data-cta-type="webhook". vtcOS relaye côté serveur pour ne pas exposer votre endpoint aux bloqueurs CORS.
POST /v1/webhook/cta Authorization: Bearer vtc_pk_live_XXX { "url": "https://votreserveur.com/réservation", "data": { // le résultat de l'estimation entier } }
Réponse : 202 Accepted immédiat. vtcOS POSTe votre URL en arrière-plan avec le corps data.
Gestion des erreurs
Les erreurs suivent un format uniforme :
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Solde epuise. Rechargez votre compte.",
"request_id": "c3f5a1e2-..."
}
}
| Code HTTP | Code | Sens |
|---|---|---|
| 400 | VALIDATION_ERROR | Données de requête invalides. |
| 401 | UNAUTHORIZED | Clé API manquante ou révoquée. |
| 402 | INSUFFICIENT_CREDITS | Solde insuffisant. Rechargez le compte. |
| 403 | FORBIDDEN_DOMAIN | Domaine non autorisé pour cette clé publique. |
| 403 | SECRET_KEY_REQUIRED | Endpoint réservé aux clés secrètes. |
| 429 | RATE_LIMIT | Trop de requêtes, ralentissez. |
| 500 | INTERNAL_ERROR | Erreur serveur, réessayer plus tard. |
Rate limits
- /v1/estimate : 60 requêtes / minute / clé.
- /v1/booking/submit : 10 demandes / heure / IP.
- /v1/places/* : 120 requêtes / minute / clé.
En cas de dépassement : HTTP 429 + en-tête Retry-After indiquant le délai en secondes.
Changelog
- 2026-04-17 — Ajout
data-enable-booking, endpoint/v1/places/reverse-geocode, flow réservation provisoire. - 2026-04-15 — Tarifs par véhicule, options configurables, majorations (nuit/dimanche/férié).
- 2026-04-10 — Premier release public du widget et de l'API v1.