Aller au contenu principal
Vos cookies, votre choix. Nous utilisons uniquement des cookies essentiels (session, sécurité). Les cookies analytiques restent désactivés sauf accord. Conforme CNDP / Loi 09-08.
Jivox
Accueil
TrouverSymptômesTarifsÀ proposContact
Commencer
  1. Accueil/
  2. API Jivox
Documentation officielle · v1

API Jivox
Intégrez la santé numérique

Endpoints REST · OAuth 2.0 · Webhooks signés HMAC SHA-256 · CNDP-conforme. Hébergée à Rabat, accessible sur api.jivox.ma.

Demander un accès Démarrage rapide
29
Endpoints
3
Langages SDK
15
Événements webhook
6k / min
Rate limit max
99,9 %
Uptime SLA
CNDP
Conformité
Sommaire
  • Démarrage rapide
  • OAuth 2.0 client credentials
  • Endpoints
  • ↳ Authentification
  • ↳ Public
  • ↳ Rendez-vous
  • ↳ Ordonnances
  • ↳ Commandes pharmacie
  • ↳ Leads
  • ↳ Notifications
  • ↳ Génération PDF
  • ↳ Vidéo (LiveKit)
  • ↳ Health checks
  • ↳ Cron jobs
  • ↳ Webhooks internes
  • Codes d'erreur
  • Pagination
  • Rate limits
  • Webhooks
  • JavaScript · Python · PHP
  • Code samples
  • Sandbox
  • Tous les services opérationnels
  • Forfaits API
Démarrage rapide

Trois étapes pour intégrer.

01

Récupérez votre clé

Demandez un accès via /demo?source=api. Vous recevez votre client_id et client_secret en moins de 24 h ouvrées.

02

Authentifiez-vous

Échangez vos identifiants contre un access_token via /auth/token. Renouvelable toutes les heures.

03

Premier appel

Listez les médecins de votre wilaya, créez votre premier rendez-vous, écoutez vos premiers webhooks.

curl -X POST https://api.jivox.ma/api/appointments \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "doctorId": "usr_8f3a92",
    "patientId": "usr_4c7b91",
    "startTime": "2026-05-12T10:30:00+01:00",
    "endTime":   "2026-05-12T11:00:00+01:00"
  }'
Authentification

OAuth 2.0 client credentials

Jivox utilise OAuth 2.0 avec le grant client_credentials pour les intégrations serveur-à-serveur. Les tokens sont valides 1 heure et peuvent être renouvelés via un refresh_token de 30 jours. Chaque token est limité à un ensemble de scopes.

POST /api/auth/token

{
  "grant_type": "client_credentials",
  "client_id": "ck_live_…",
  "client_secret": "cs_live_…",
  "scope": "appointments:read appointments:write webhooks:manage"
}

Tous les appels suivants doivent inclure l'en-tête Authorization: Bearer <access_token>. En cas de token expiré l'API renvoie 401 avec le code token_expired.

Scopes disponibles

users:read
Lire le profil utilisateur courant et les utilisateurs du tenant.
doctors:read
Lire l'annuaire interne des médecins (incluant champs privés).
appointments:read
Lire les rendez-vous accessibles.
appointments:write
Créer / mettre à jour / annuler des rendez-vous.
prescriptions:read
Lire les ordonnances accessibles.
prescriptions:write
Émettre des ordonnances (DOCTOR/DENTIST uniquement).
orders:read
Lire les commandes pharmacie accessibles.
orders:write
Créer et mettre à jour des commandes pharmacie.
notifications:write
Envoyer des notifications transactionnelles.
pdf:generate
Générer des PDFs (ordonnances, factures, certificats).
video:join
Émettre un token vidéo pour rejoindre une room LiveKit.
webhooks:manage
Inscrire et gérer des webhooks sortants.
Référence

Endpoints

12 groupes, 35 endpoints. Toutes les requêtes sont JSON UTF-8 ; les dates en ISO 8601 ; les montants en centimes MAD entiers. Cliquez sur un endpoint pour voir l'exemple.

Authentification

Sign-in, sign-out, refresh, profil — basé NextAuth + JWT.

3 endpoints
  • POST/api/auth/[...nextauth]Endpoint NextAuth dispatcher (signin, signout, callback, csrf, providers, session).▾
    Scopes :public
    Requête
    POST /api/auth/callback/credentials
    Content-Type: application/x-www-form-urlencoded
    
    email=jane%40clinic.ma&password=…&csrfToken=…
    Réponse (2xx)
    {
      "url": "https://app.jivox.ma/dashboard"
    }
    Erreur (4xx)
    {
      "error": "CredentialsSignin"
    }
  • POST/api/auth/registerCrée un nouveau compte patient, médecin ou pharmacien (email + password).▾
    Scopes :public
    Requête
    {
      "email": "[email protected]",
      "password": "S3cret!Passw0rd",
      "name": "Dr. Jane",
      "role": "DOCTOR"
    }
    Réponse (2xx)
    {
      "ok": true,
      "user": { "id": "usr_…", "email": "[email protected]", "role": "DOCTOR" }
    }
    Erreur (4xx)
    {
      "error": { "code": "CONFLICT", "message": "Email already registered" }
    }
  • GET/api/users/meRenvoie le profil de l'utilisateur authentifié (id, email, role, tenantId).▾
    Scopes :users:read
    Réponse (2xx)
    {
      "id": "usr_8f3a92",
      "email": "[email protected]",
      "name": "Dr. Jane",
      "role": "DOCTOR",
      "tenantId": "ten_…"
    }
    Erreur (4xx)
    {
      "error": { "code": "UNAUTHORIZED", "message": "Authentication required" }
    }

Public

Annuaire public, sans authentification, mis en cache.

2 endpoints
  • GET/api/public/doctorsListe paginée des médecins publics (filtres: city, specialty, languages, isTele).▾
    Scopes :public
    Réponse (2xx)
    {
      "doctors": [{
        "id": "usr_…", "slug": "dr-elhassani",
        "name": "Dr. Younes El Hassani",
        "specialty": "Cardiologie",
        "city": "Casablanca",
        "rating": 4.8,
        "isTele": true
      }],
      "pagination": { "page": 1, "pageSize": 20, "total": 142, "totalPages": 8 }
    }

Rendez-vous

Création, listing, mise à jour, annulation. Conflits détectés serveur.

5 endpoints
  • GET/api/appointmentsListe les rendez-vous (PATIENT voit les siens, DOCTOR ses créneaux, ADMIN tout).▾
    Scopes :appointments:read
    Réponse (2xx)
    {
      "appointments": [{
        "id": "apt_…",
        "startTime": "2026-05-12T10:30:00.000Z",
        "endTime":   "2026-05-12T11:00:00.000Z",
        "status": "SCHEDULED",
        "videoRoomId": "room_…",
        "patient": { "id": "usr_…", "name": "Patient X" },
        "doctor":  { "id": "usr_…", "name": "Dr. Jane" }
      }],
      "pagination": { "page": 1, "pageSize": 20, "total": 5, "totalPages": 1 }
    }

Ordonnances

Émission et listing d'ordonnances numériques signées.

2 endpoints
  • GET/api/prescriptionsListe les ordonnances visibles selon le rôle (patient/doctor/admin).▾
    Scopes :prescriptions:read
    Réponse (2xx)
    {
      "prescriptions": [{
        "id": "rx_…",
        "medication": "Metformine 500 mg",
        "dosage": "1 cp x 2/j",
        "doctor": { "id": "usr_…", "name": "Dr. Jane" },
        "patient": { "id": "usr_…", "name": "Patient X" },
        "issuedAt": "2026-05-02T08:00:00.000Z"
      }]
    }
    Erreur (4xx)

Commandes pharmacie

Création, statuts, dispensation des commandes pharmaceutiques.

4 endpoints
  • GET/api/ordersListe les commandes (patient/pharmacy/admin scope).▾
    Scopes :orders:read
    Réponse (2xx)
    {
      "orders": [{
        "id": "ord_…",
        "status": "READY",
        "deliveryRequested": true,
        "prescription": { "id": "rx_…", "medication": "…" },
        "pharmacy": { "id": "usr_…", "name": "Pharmacie Centrale" }
      }]
    }
    Erreur (4xx)

Leads

Capture des prospects depuis le site marketing (formulaires, démo).

1 endpoint
  • POST/api/leadsEnregistre un lead. Source typique: /demo, /pricing, /contact.▾
    Scopes :public
    Requête
    {
      "name": "Dr. Karim",
      "email": "[email protected]",
      "phone": "+212600000000",
      "source": "DEMO_FORM",
      "metadata": { "specialty": "Cardiologie", "city": "Rabat" }
    }
    Réponse (2xx)
    { "ok": true, "leadId": "lead_…" }

Notifications

Envoi de SMS/WhatsApp/Email transactionnels via les providers ChannelProvider.

1 endpoint
  • POST/api/notifications/sendEnvoie un message transactionnel sur le canal préféré du destinataire.▾
    Scopes :notifications:write
    Requête
    {
      "recipientUserId": "usr_…",
      "channel": "WHATSAPP",
      "templateCode": "appointment_reminder",
      "variables": { "doctorName": "Dr. Jane", "datetime": "12 mai à 10h30" }
    }
    Réponse (2xx)

Génération PDF

Rendu serveur d'ordonnances, certificats, factures, attestations.

1 endpoint
  • POST/api/pdf/generateGénère un PDF signé à partir d'un template. Renvoie un URL temporaire.▾
    Scopes :pdf:generate
    Requête
    {
      "templateId": "rx_default",
      "data": { "prescriptionId": "rx_…" }
    }
    Réponse (2xx)
    {
      "ok": true,
      "url": "https://cdn.jivox.ma/pdf/rx_…?sig=…",
      "expiresAt": "2026-05-02T11:30:00.000Z"
    }

Vidéo (LiveKit)

Délivre un access token JWT pour rejoindre une room LiveKit.

1 endpoint
  • POST/api/video/tokenÉmet un access token court (15 min) pour le videoRoomId d'un rendez-vous.▾
    Scopes :video:join
    Requête
    {
      "appointmentId": "apt_…",
      "identity": "usr_…"
    }
    Réponse (2xx)
    {
      "ok": true,
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
      "url": "wss://livekit.jivox.ma",
      "roomId": "room_…",
      "expiresAt": "2026-05-12T10:45:00.000Z"
    }

Health checks

Sondes de disponibilité — utilisées par le load balancer et le statut public.

4 endpoints
  • GET/api/healthSonde liveness simple — répond 200 dès que le process tourne.▾
    Scopes :public
    Réponse (2xx)
    {
      "ok": true,
      "timestamp": "2026-05-02T10:30:00.000Z"
    }
    Erreur (4xx)
    { "ok": false, "error": "service_unavailable" }

Cron jobs

Workers planifiés. Auth via en-tête X-Cron-Secret. Idempotents.

6 endpoints
  • POST/api/cron/remindersEnvoie les rappels J-1 et H-2 pour les rendez-vous (cadence: toutes les 15 min).▾
    Scopes :cron:run
    Réponse (2xx)
    { "ok": true, "processed": 42, "succeeded": 41, "failed": 1 }
    Erreur (4xx)
    { "error": "forbidden" }

Webhooks internes

Inter-app événements signés. Auth via X-Internal-Token.

5 endpoints
  • POST/api/internal/appointment-confirmedÉmis par doctor-portal quand un médecin confirme un rendez-vous.▾
    Scopes :internal
    Requête
    { "appointmentId": "apt_…" }
    Réponse (2xx)
    {
      "ok": true,
      "timestamp": "2026-05-02T10:30:00.000Z"
    }
    Erreur (4xx)
Erreurs

Codes d'erreur

Toutes les erreurs renvoient une enveloppe normalisée avec un code, un message lisible et des détails optionnels. Les codes 4xx ne sont jamais retentés automatiquement, les 5xx oui (backoff exponentiel).

Enveloppe d'erreur standard

{
  "error": {
    "code": "UNPROCESSABLE",
    "message": "Validation failed",
    "details": [
      { "path": ["startTime"], "message": "Invalid datetime" }
    ]
  }
}
CodeLibelléDescriptionRetry
200OKRequête réussie.Non
201CreatedRessource créée.Non
204No ContentSuccès sans corps de réponse.Non
400Bad RequestCorps JSON invalide ou paramètre manquant.Non
401UnauthorizedToken absent ou expiré (token_expired).Non
403ForbiddenToken valide mais scope/role insuffisant.Non
404Not FoundRessource ou route inexistante.Non
409ConflictConflit métier (chevauchement, état incompatible).Non
422Unprocessable EntityValidation Zod échouée — voir details[].Non
429Too Many RequestsQuota dépassé — voir Retry-After.Oui
500Internal Server ErrorErreur serveur inattendue.Oui
502Bad GatewayProvider en aval indisponible.Oui
503Service UnavailableMaintenance ou dégradation; voir /health.Oui

Pour les codes 429, 5xx et timeouts réseau : retentez avec un backoff exponentiel (250 ms × 2ⁿ, max 5 tentatives). Respectez l'en-tête Retry-After quand il est présent.

Pagination

Pagination

Les listes utilisent un schéma page + pageSize (max 100). La réponse contient un objet pagination avec total et totalPages.

Requête
GET /api/appointments?status=SCHEDULED&page=2&pageSize=50
Authorization: Bearer YOUR_ACCESS_TOKEN
Réponse
{
  "appointments": [ /* … 50 rows … */ ],
  "pagination": {
    "page": 2,
    "pageSize": 50,
    "total": 327,
    "totalPages": 7
  }
}
Quotas

Rate limits

Chaque token reçoit ses quotas selon le forfait de l'organisation. Les en-têtes X-RateLimit-Limit et X-RateLimit-Remaining sont renvoyés à chaque appel ; Retry-After est renvoyé en cas de 429.

ForfaitRequêtes / minuteBucket / jourBurst autorisé
Starter60 / minute5 000 / jour1.5x pendant 10 s
Pro600 / minute100 000 / jour3x pendant 30 s
Enterprise6 000 / minuteIllimitéSur mesure
Webhooks

15 événements signés HMAC SHA-256

Chaque webhook contient un en-tête X-MC-Signature calculé avec votre webhook_secret en HMAC SHA-256 sur le corps brut. Les requêtes échouées sont retentées 3 fois (1 min, 10 min, 1 h).

Vérification de signature

Politique de retry : 3 tentatives avec backoff exponentiel (1 min, 10 min, 1 h). Au-delà, la livraison est marquée failed et l'événement reste consultable dans le tableau de bord.

import crypto from "node:crypto";

export function verify(rawBody: string, header: string, secret: string) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody, "utf8")
    .digest("hex");
  // Constant-time comparison to defeat timing attacks.
  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(header, "hex");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
appointment.createdUn nouveau rendez-vous a été créé.
{
  "event": "appointment.created",
  "id": "evt_…",
  "createdAt": "2026-05-02T10:30:00.000Z",
  "data": { "appointmentId": "apt_…", "doctorId": "usr_…", "patientId": "usr_…", "startTime": "…" }
}
appointment.updatedStatut, horaire ou notes mis à jour.
{ "event": "appointment.updated", "data": { "appointmentId": "apt_…", "changes": ["status"] } }
appointment.cancelledRendez-vous annulé (par le patient, le médecin ou l'auto-cancel).
{ "event": "appointment.cancelled", "data": { "appointmentId": "apt_…", "reason": "patient_request" } }
appointment.completedConsultation marquée terminée.
{ "event": "appointment.completed", "data": { "appointmentId": "apt_…", "durationSec": 1620 } }
prescription.createdNouvelle ordonnance émise.
{ "event": "prescription.created", "data": { "prescriptionId": "rx_…", "medication": "…" } }
prescription.signedOrdonnance signée numériquement.
{ "event": "prescription.signed", "data": { "prescriptionId": "rx_…", "signature": "sha256:…" } }
lab_order.createdCommande d'analyses soumise.
{ "event": "lab_order.created", "data": { "labOrderId": "lab_…", "tests": ["NFS","Glycémie"] } }
lab_order.status_changedStatut LabOrder mis à jour.
{ "event": "lab_order.status_changed", "data": { "labOrderId": "lab_…", "status": "RESULTS_READY" } }
lab_result.publishedRésultat publié et visible par le patient.
{ "event": "lab_result.published", "data": { "labResultId": "res_…", "url": "https://…" } }
lab_result.critical_alertValeur critique détectée — alerte haute priorité.
{ "event": "lab_result.critical_alert", "data": { "labResultId": "res_…", "param": "K+", "value": 6.2 } }
payment.succeededPaiement CMI ou cash comptabilisé.
{ "event": "payment.succeeded", "data": { "invoiceId": "inv_…", "amountMAD": 25000 } }
payment.refundedRemboursement émis.
{ "event": "payment.refunded", "data": { "invoiceId": "inv_…", "amountMAD": 25000 } }
review.createdAvis vérifié publié.
{ "event": "review.created", "data": { "reviewId": "rev_…", "rating": 5 } }
patient.createdNouveau patient enregistré.
{ "event": "patient.created", "data": { "patientId": "usr_…" } }
patient.consent_updatedLe patient a modifié son consentement CNDP.
{ "event": "patient.consent_updated", "data": { "patientId": "usr_…", "consents": ["MARKETING"] } }
SDKs officiels

JavaScript · Python · PHP

JavaScript / TypeScript

npm
npm i @medconnect/sdk

Compatible Node 20+, Next.js, Bun, Deno. Types embarqués, ESM + CJS.

Dernière version : v1.4.2

Python

PyPI
pip install medconnect

Compatible Python 3.10+. Async via httpx, synchronisé via requests.

Dernière version : v1.3.0

PHP

Composer
composer require medconnect/sdk

Compatible PHP 8.2+. Guzzle, PSR-7, autoloading PSR-4.

Dernière version : v1.2.5
Exemples

Code samples

Cinq opérations courantes en JavaScript, Python et PHP. Toutes les opérations passent par un client SDK initialisé avec votre access_token.

Lister les rendez-vous

import { Jivox } from "@medconnect/sdk";

const client = new Jivox({
  accessToken: process.env.JIVOX_TOKEN,
});

const { appointments, pagination } = await client.appointments.list({
  status: "SCHEDULED",
  page: 1,
  pageSize: 50,
});
from medconnect import Jivox

client = Jivox(access_token=os.environ["JIVOX_TOKEN"])

resp = client.appointments.list(status="SCHEDULED", page=1, page_size=50)
for appt in resp["appointments"]:
    print(appt["id"], appt["startTime"])
<?php
use Jivox\Client;

$client = new Client(['access_token' => getenv('JIVOX_TOKEN')]);
$result = $client->appointments->list(['status' => 'SCHEDULED', 'pageSize' => 50]);
foreach ($result['appointments'] as $appt) {
    echo $appt['id'] . PHP_EOL;
}

Créer un rendez-vous

const appointment = await client.appointments.create({
  doctorId: "usr_8f3a92",
  patientId: "usr_4c7b91",
  startTime: "2026-05-12T10:30:00+01:00",
  endTime:   "2026-05-12T11:00:00+01:00",
});

console.log("Réservé :", appointment.id);
appt = client.appointments.create(
    doctor_id="usr_8f3a92",
    patient_id="usr_4c7b91",
    start_time="2026-05-12T10:30:00+01:00",
    end_time="2026-05-12T11:00:00+01:00",
)
$appt = $client->appointments->create([
    'doctorId'  => 'usr_8f3a92',
    'patientId' => 'usr_4c7b91',
    'startTime' => '2026-05-12T10:30:00+01:00',
    'endTime'   => '2026-05-12T11:00:00+01:00',
]);

Lister les ordonnances

const { prescriptions } = await client.prescriptions.list({
  patientId: "usr_4c7b91",
});
rxs = client.prescriptions.list(patient_id="usr_4c7b91")["prescriptions"]
$rxs = $client->prescriptions->list(['patientId' => 'usr_4c7b91']);

Envoyer une notification

await client.notifications.send({
  recipientUserId: "usr_4c7b91",
  channel: "WHATSAPP",
  templateCode: "appointment_reminder",
  variables: { doctorName: "Dr. Jane", datetime: "12 mai à 10h30" },
});
client.notifications.send(
    recipient_user_id="usr_4c7b91",
    channel="WHATSAPP",
    template_code="appointment_reminder",
    variables={"doctorName": "Dr. Jane", "datetime": "12 mai à 10h30"},
)
$client->notifications->send([
    'recipientUserId' => 'usr_4c7b91',
    'channel'         => 'WHATSAPP',
    'templateCode'    => 'appointment_reminder',
    'variables'       => ['doctorName' => 'Dr. Jane', 'datetime' => '12 mai à 10h30'],
]);

Vérification de santé

const health = await client.health.check();
console.log(health.ok); // true
health = client.health.check()
assert health["ok"]
$health = $client->health->check();
assert($health['ok']);
Sandbox

Sandbox

L'environnement sandbox réplique l'API de production avec des données fictives. Aucune notification réelle n'est envoyée ; les paiements simulent CMI.

  • 1Demandez vos identifiants sandbox via /demo?source=api en cochant la case « Sandbox uniquement ». Réception sous 24 h.
  • 2Pointez votre client SDK sur https://api-sandbox.jivox.ma. Les comptes test sont préprovisionnés (médecins, patients, pharmacies).
  • 3Les données sandbox sont automatiquement réinitialisées chaque dimanche à 00h00 UTC. Vous pouvez forcer un reset manuel avec l'endpoint ci-dessous.
Réinitialiser les données sandbox
curl -X POST https://api-sandbox.jivox.ma/api/sandbox/reset \
  -H "Authorization: Bearer SANDBOX_TOKEN"
Statut

Tous les services opérationnels

API en ligne · SLA 99,9 %status.jivox.ma
  • API Gateway uptime 100,00 % 47 msOK
  • Auth (NextAuth) uptime 99,98 % 62 msOK
  • Webhooks uptime 99,95 % 112 msOK
  • SDK CDN uptime 100,00 % 23 msOK
  • Sandbox uptime 99,90 % 78 msOK
Tarifs

Forfaits API

Starter
0 MAD/mois

Pour explorer l'API et bâtir un prototype.

  • 60 req / min
  • 5 000 req / jour
  • Sandbox uniquement
  • Support communauté
Nous contacter
Recommandé
Pro
499 MAD/mois

Pour les éditeurs SaaS et les cabinets en production.

  • 600 req / min
  • 100 000 req / jour
  • Webhooks signés
  • SLA 99,9 %
  • Support email
Enterprise
Sur devis

Volumes illimités, isolation dédiée, contrats sur-mesure.

  • 6 000 req / min
  • Cluster dédié
  • Webhooks redondants
  • DPA + audit annuel
  • Account manager

Prêt à intégrer la santé connectée ?

Demandez votre clé API en moins de 2 minutes.

Demander un accès
Réponse en moins de 5 min

Une question ? Parlons-en sur WhatsApp

Notre équipe répond en français, en arabe ou en darija — sans créer de compte.

Discuter sur WhatsApp

Équipe basée au Maroc · Du lundi au samedi, 9h – 20h

Conforme CNDP
Données hébergées au Maroc
Agréé ANAM & ANP
Praticiens vérifiés à 100 %
Chiffrement bout-en-bout
TLS 1.3 + SHA-256 sur ordonnances
Tarifs en MAD
TVA 7 % conforme · CNOPS / CNSS / AMO
Jivox

La plateforme de télémédecine de référence au Maroc — réservation publique, téléconsultation HD, ordonnances numériques, réseau de pharmacies et laboratoires d'analyses dans tout le Royaume.

+212 5 22 00 00 00 [email protected] Casablanca, Maroc

Plateforme

Patients

Professionnels

Ressources

Entreprise

Erreur (4xx)
{
  "error": {
    "code": "UNPROCESSABLE",
    "message": "Validation failed",
    "details": [
      { "path": ["startTime"], "message": "Invalid datetime" }
    ]
  }
}
  • GET/api/doctorsListe authentifiée des médecins du tenant courant (vue admin/staff).▾
    Scopes :doctors:read
    Réponse (2xx)
    {
      "doctors": [{ "id": "usr_…", "name": "Dr. Jane", "specialty": "…" }]
    }
    Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
  • Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
  • POST/api/appointmentsCrée un rendez-vous. 409 si chevauchement avec un autre créneau du médecin.▾
    Scopes :appointments:write
    Requête
    {
      "doctorId": "usr_…",
      "patientId": "usr_…",
      "startTime": "2026-05-12T10:30:00.000Z",
      "endTime":   "2026-05-12T11:00:00.000Z",
      "notes": "Suivi diabète"
    }
    Réponse (2xx)
    {
      "appointment": { "id": "apt_…", "status": "SCHEDULED", "videoRoomId": "room_…" }
    }
    Erreur (4xx)
    {
      "error": {
        "code": "CONFLICT",
        "message": "Doctor already has an appointment in that window",
        "details": { "overlap": { "id": "apt_…" } }
      }
    }
  • GET/api/appointments/{id}Récupère un rendez-vous par identifiant.▾
    Scopes :appointments:read
    Réponse (2xx)
    {
      "appointment": { "id": "apt_…", "status": "SCHEDULED", "notes": "…" }
    }
    Erreur (4xx)
    { "error": { "code": "NOT_FOUND", "message": "Appointment not found" } }
  • PUT/api/appointments/{id}Met à jour le statut, l'heure, les notes ou annule le rendez-vous.▾
    Scopes :appointments:write
    Requête
    { "status": "CANCELLED", "notes": "Patient indisponible" }
    Réponse (2xx)
    { "appointment": { "id": "apt_…", "status": "CANCELLED" } }
    Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
  • DELETE/api/appointments/{id}Supprime définitivement un rendez-vous (admin only).▾
    Scopes :appointments:writeadmin
    Réponse (2xx)
    { "ok": true }
    Erreur (4xx)
    { "error": { "code": "FORBIDDEN", "message": "Insufficient permissions" } }
  • {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
  • POST/api/prescriptionsCrée une nouvelle ordonnance. Réservé aux DOCTOR/DENTIST.▾
    Scopes :prescriptions:write
    Requête
    {
      "patientId": "usr_…",
      "appointmentId": "apt_…",
      "medication": "Amoxicilline 1g",
      "dosage": "1 cp x 3/j pendant 7 jours",
      "instructions": "À prendre au milieu du repas."
    }
    Réponse (2xx)
    {
      "prescription": { "id": "rx_…", "medication": "Amoxicilline 1g" }
    }
    Erreur (4xx)
    {
      "error": { "code": "FORBIDDEN", "message": "Only doctors can issue prescriptions" }
    }
  • { "error": { "code": "UNPROCESSABLE", "message": "Validation failed", "details": [ { "path": ["startTime"], "message": "Invalid datetime" } ] } }
  • POST/api/ordersCrée une commande à partir d'une ordonnance et l'envoie à une pharmacie.▾
    Scopes :orders:write
    Requête
    {
      "prescriptionId": "rx_…",
      "pharmacyId": "usr_…",
      "deliveryRequested": false
    }
    Réponse (2xx)
    {
      "order": { "id": "ord_…", "status": "PENDING" }
    }
    Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
  • GET/api/orders/{id}Récupère une commande par identifiant.▾
    Scopes :orders:read
    Réponse (2xx)
    { "order": { "id": "ord_…", "status": "READY" } }
    Erreur (4xx)
    { "error": { "code": "NOT_FOUND", "message": "Order not found" } }
  • PUT/api/orders/{id}Met à jour le statut (PENDING → PREPARING → READY → DELIVERED).▾
    Scopes :orders:write
    Requête
    { "status": "READY" }
    Réponse (2xx)
    { "order": { "id": "ord_…", "status": "READY" } }
    Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
  • Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
    { "ok": true, "messageId": "msg_…", "providerMessageId": "wa_…", "status": "QUEUED" }
    Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
    Erreur (4xx)
    {
      "error": {
        "code": "UNPROCESSABLE",
        "message": "Validation failed",
        "details": [
          { "path": ["startTime"], "message": "Invalid datetime" }
        ]
      }
    }
    Erreur (4xx)
    { "error": { "code": "FORBIDDEN", "message": "User not part of this appointment" } }
    GET
    /api/health/db
    Sonde Postgres (SELECT 1, latence < 200 ms).
    ▾
    Scopes :public
    Réponse (2xx)
    { "ok": true, "service": "postgres", "latencyMs": 12 }
    Erreur (4xx)
    { "ok": false, "service": "postgres", "error": "connection_refused" }
  • GET/api/health/redisSonde Redis (PING, latence < 50 ms).▾
    Scopes :public
    Réponse (2xx)
    { "ok": true, "service": "redis", "latencyMs": 4 }
    Erreur (4xx)
    { "ok": false, "service": "redis", "error": "timeout" }
  • GET/api/health/livekitSonde LiveKit (SDK admin call, latence < 500 ms).▾
    Scopes :public
    Réponse (2xx)
    { "ok": true, "service": "livekit", "latencyMs": 87 }
    Erreur (4xx)
    { "ok": false, "service": "livekit", "error": "auth_failed" }
  • POST
    /api/cron/auto-cancel
    Annule les RDV non confirmés au-delà de 24h. Cadence: toutes les heures.
    ▾
    Scopes :cron:run
    Réponse (2xx)
    { "ok": true, "cancelled": 7 }
    Erreur (4xx)
    { "error": "forbidden" }
  • POST/api/cron/recallRappel des patients ALD inactifs depuis 90 jours. Cadence: quotidien 09:00 UTC.▾
    Scopes :cron:run
    Réponse (2xx)
    { "ok": true, "processed": 18, "succeeded": 16, "failed": 2 }
    Erreur (4xx)
    { "error": "forbidden" }
  • POST/api/cron/drip-campaignsAvance les destinataires dans leurs séquences drip activées. Cadence: 30 min.▾
    Scopes :cron:run
    Réponse (2xx)
    { "ok": true, "advanced": 124 }
    Erreur (4xx)
    { "error": "forbidden" }
  • POST/api/cron/expiry-warningsAvertit les pharmacies des médicaments arrivant en péremption (J-30, J-7).▾
    Scopes :cron:run
    Réponse (2xx)
    { "ok": true, "warnedItems": 36 }
    Erreur (4xx)
    { "error": "forbidden" }
  • POST/api/cron/apply-scheduled-pricingApplique les changements tarifaires programmés dont la date est échue.▾
    Scopes :cron:run
    Réponse (2xx)
    { "ok": true, "applied": 3 }
    Erreur (4xx)
    { "error": "forbidden" }
  • { "error": "forbidden" }
  • POST/api/internal/prescription-issuedÉmis quand une ordonnance vient d'être délivrée; pré-route vers une pharmacie si fournie.▾
    Scopes :internal
    Requête
    { "prescriptionId": "rx_…", "pharmacyId": "usr_…", "deliveryRequested": false }
    Réponse (2xx)
    { "ok": true, "prescriptionId": "rx_…", "routedOrderId": "ord_…" }
    Erreur (4xx)
    { "error": "rx_not_found" }
  • POST/api/internal/order-status-updateÉmis par pharmacy-portal à chaque transition de statut d'une commande.▾
    Scopes :internal
    Requête
    { "orderId": "ord_…", "status": "READY" }
    Réponse (2xx)
    {
      "ok": true,
      "timestamp": "2026-05-02T10:30:00.000Z"
    }
    Erreur (4xx)
    { "error": "order_not_found" }
  • POST/api/internal/lab-result-releasedÉmis par lab-portal quand un résultat est validé et publié au patient.▾
    Scopes :internal
    Requête
    { "labOrderId": "lab_…" }
    Réponse (2xx)
    {
      "ok": true,
      "timestamp": "2026-05-02T10:30:00.000Z"
    }
    Erreur (4xx)
    { "error": "lab_order_not_found" }
  • POST/api/internal/follow-up-acceptedÉmis par patient-portal quand un patient accepte une consultation de suivi.▾
    Scopes :internal
    Requête
    { "followUpId": "fu_…" }
    Réponse (2xx)
    {
      "ok": true,
      "timestamp": "2026-05-02T10:30:00.000Z"
    }
    Erreur (4xx)
    { "error": "follow_up_not_found" }
  • Jivox au Maroc · 12 wilayas

    Casablanca-SettatRabat-Salé-KénitraFès-MeknèsMarrakech-SafiTanger-Tétouan-Al HoceïmaOrientalSouss-MassaBéni Mellal-KhénifraDrâa-TafilaletGuelmim-Oued NounLaâyoune-Sakia El HamraDakhla-Oued Ed Dahab

    Suivez-nous

    WhatsApp BusinessFacebookInstagramTikTokSnapchatYouTubeLinkedInTwitter

    © 2026 Jivox. Conçu au Maroc.

    ICE 001234567000089 · TVA TVA-CAS-2024-0142 · RC Casablanca 487291 · IF 12345678

    Conforme CNDPSécuritéStatut
    Demander un accès
    Nous contacter
    Trouver
    Médecins
    Pharmacies
    Pharmacie de garde
    Laboratoires
    Tarifs
    App mobile
    Desktop
    Inscription
    Connexion
    Symptômes
    Quiz santé
    Mutuelles
    Carnet santé
    Parrainage
    Médecins
    Pharmacies
    Laboratoires
    Patients
    API
    Démo
    Webinaires
    Blog
    Études de cas
    Guide complet
    Aide
    Comparer
    Statut
    À propos
    Presse
    Carrières
    Sécurité
    Contact
    Confidentialité (CNDP)
    Conditions d'utilisation