> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Onboarding HIPAA : du BAA au prêt-à-l'audit

> Séquence pour amener un workspace santé de la signature du BAA au prêt-à-l'audit PHI — activer le mode HIPAA, restreindre rôles et scopes API, configurer la rétention, lire le journal d'accès PHI et exporter le binder de preuves.

# Onboarding HIPAA : du BAA au prêt-à-l'audit

La référence [contrôles HIPAA](/compliance/hipaa) explique ce que fait chaque contrôle. Ce guide les met en ordre — la séquence qui mène un workspace santé de « nous gérons du PHI » à « nous pouvons montrer un audit trail » sans buter sur le send gate `422 HIPAA_BAA_REQUIRED` — l'un des [send gates](/compliance/send-gates) qui vérifient la compliance de l'expéditeur avant qu'un message ou un appel ne soit envoyé.

L'ordre compte. Le mode HIPAA ne peut être activé avant que le BAA soit exécuté, les envois de PHI sont rejetés tant qu'il ne l'est pas, et la rétention ne protège les données qu'une fois configurée. Suivez les étapes de haut en bas.

Chaque étape ci-dessous s'exécute contre `https://api.orbit.devotel.io/api/v1` avec un en-tête `X-API-Key` sur une clé de **propriétaire ou administrateur**. Exportez-la avant de commencer :

```bash theme={null}
export ORBIT_KEY="dv_live_sk_…"   # live — ou dv_test_sk_… contre le sandbox
```

Deux conventions valent pour chaque réponse sur cette page :

* **Préfixes de clé.** Les clés sandbox sont `dv_test_sk_…` ; les clés live sont `dv_live_sk_…`. Chaque appel ci-dessous fonctionne sur les deux — le sandbox renvoie les mêmes enveloppes sans toucher à l'état de compliance live.
* **Enveloppe partagée.** Chaque body de succès est `{ "data": { … }, "meta": { "request_id", "timestamp" } }`. Les erreurs sont `{ "error": { code, message, status }, "meta": … }`.

## 1. Exécuter le BAA

Rien d'autre ne se débloque tant que la Business Associate Agreement (BAA) n'est pas exécutée. Deux gates lisent le statut du BAA directement :

* **Activer le mode HIPAA** renvoie `403 Forbidden` tant que le statut du BAA n'est pas `executed`.
* **Tout envoi de PHI** est rejeté avec `422 HIPAA_BAA_REQUIRED`.

Exécutez-la via le panneau **Compliance → BAA** dans le dashboard, ou pilotez les mêmes trois appels via l'API. Utilisez une clé propriétaire pour `/execute` (elle lie l'accord légal) ; une clé propriétaire-ou-administrateur suffit pour `/require` et `GET /compliance/baa`.

### 1a. Attester que le PHI est dans le périmètre

Faites passer l'organisation de `not_required` à `pending`, ce qui ouvre le flux d'exécution :

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.orbit.devotel.io/api/v1/compliance/baa/require \
    -H "X-API-Key: $ORBIT_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "reason": "Clinic messaging will carry PHI" }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/compliance/baa/require",
    {
      method: "POST",
      headers: {
        "X-API-Key": process.env.ORBIT_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ reason: "Clinic messaging will carry PHI" }),
    },
  );
  console.log((await res.json()).data.baa_status); // "pending"
  ```
</CodeGroup>

```json theme={null}
{
  "data": {
    "baa_status": "pending",
    "baa_executed_at": null,
    "baa_template_version": null,
    "baa_signer_name": null,
    "baa_signer_email": null,
    "baa_pdf_gcs_url": null,
    "hipaa_required": true,
    "expires_at": null,
    "days_until_expiry": null
  },
  "meta": { "request_id": "…", "timestamp": "…" }
}
```

`reason` est un texte libre optionnel enregistré sur la ligne d'audit, jamais dans une colonne.

### 1b. Exécuter avec une signature électronique de taper-le-nom

Enregistrez l'attestation. `typed_attestation` doit correspondre exactement à `signer_name` — c'est la défense contre une signature accidentelle ou de formulaire vierge :

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.orbit.devotel.io/api/v1/compliance/baa/execute \
    -H "X-API-Key: $ORBIT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "signer_name": "Ada Lovelace",
      "signer_email": "ada@clinic.example",
      "typed_attestation": "Ada Lovelace"
    }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/compliance/baa/execute",
    {
      method: "POST",
      headers: {
        "X-API-Key": process.env.ORBIT_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        signer_name: "Ada Lovelace",
        signer_email: "ada@clinic.example",
        typed_attestation: "Ada Lovelace",
      }),
    },
  );
  console.log((await res.json()).data.baa_status); // "executed"
  ```
</CodeGroup>

```json theme={null}
{
  "data": {
    "baa_status": "executed",
    "baa_executed_at": "2026-09-23T14:02:11.482Z",
    "baa_template_version": "v1",
    "baa_signer_name": "Ada Lovelace",
    "baa_signer_email": "ada@clinic.example",
    "baa_pdf_gcs_url": "gs://…/baa/org_…/baa_….pdf",
    "hipaa_required": true,
    "expires_at": "2027-09-23T14:02:11.482Z",
    "days_until_expiry": 365,
    "baa_id": "baa_…"
  },
  "meta": { "request_id": "…", "timestamp": "…" }
}
```

### 1c. Confirmer que le BAA est exécuté

Relisez le cycle de vie et notez `days_until_expiry` — un BAA exécuté expire après son terme d'un an et doit être ré-exécuté :

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.orbit.devotel.io/api/v1/compliance/baa \
    -H "X-API-Key: $ORBIT_KEY"
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/compliance/baa",
    { headers: { "X-API-Key": process.env.ORBIT_KEY! } },
  );
  console.log((await res.json()).data.days_until_expiry); // par ex. 365
  ```
</CodeGroup>

```json theme={null}
{
  "data": {
    "baa_status": "executed",
    "baa_executed_at": "2026-09-23T14:02:11.482Z",
    "baa_template_version": "v1",
    "baa_signer_name": "Ada Lovelace",
    "baa_signer_email": "ada@clinic.example",
    "baa_pdf_gcs_url": "gs://…/baa/org_…/baa_….pdf",
    "hipaa_required": true,
    "expires_at": "2027-09-23T14:02:11.482Z",
    "days_until_expiry": 365
  },
  "meta": { "request_id": "…", "timestamp": "…" }
}
```

Le cycle de vie du BAA, la mise en garde du miroir legacy et les formes de requête complètes sont documentés sous [BAA](/compliance/hipaa#5-business-associate-agreement-baa). Pour la console de l'exécution, de la ré-exécution anuelle et des contrôles de déclin/retour — plus les consoles sœurs DPA et consentement d'enregistrement — voir [Exécuter le DPA et le BAA, puis gérer le consentement d'enregistrement par appel](/guides/compliance-dpa-baa-recording-consent).

## 2. Activer le mode HIPAA

Avec le BAA exécuté, activez le drapeau HIPAA par organisation. Le mode HIPAA est un feature flag par organisation qui active cinq contrôles à la fois — chiffrement au repos, contrôles d'accès, journalisation audit PHI, rétention forcée et suivi BAA. C'est un appel propriétaire uniquement.

* **Dashboard :** **Paramètres → Compliance → HIPAA Mode Toggle**.
* **API :**

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT https://api.orbit.devotel.io/api/v1/settings/hipaa \
    -H "X-API-Key: $ORBIT_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "enabled": true }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/settings/hipaa",
    {
      method: "PUT",
      headers: {
        "X-API-Key": process.env.ORBIT_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ enabled: true }),
    },
  );
  console.log((await res.json()).data.enabled); // true
  ```
</CodeGroup>

```json theme={null}
{
  "data": {
    "enabled": true,
    "enabled_at": "2026-09-23T14:05:40.118Z",
    "last_enabled_at": "2026-09-23T14:05:40.118Z",
    "disabled_at": null,
    "enable_history": [
      { "enabledAt": "2026-09-23T14:05:40.118Z" }
    ],
    "baa_status": "executed",
    "hipaa_required": true,
    "baa": {
      "signed": true,
      "signedAt": "2026-09-23T14:02:11.482Z",
      "documentPresent": true,
      "history": []
    },
    "data_retention": { "enabled": true, "days": 365 },
    "encryption_algorithm": "AES-256-GCM",
    "phi_access_log_count": 0
  },
  "meta": { "request_id": "…", "timestamp": "…" }
}
```

L'activation est un appel unique — il durcit la posture du workspace, donc aucun défi de ré-authentification n'est requis. La désactivation est destructive et en nécessite une ; ce flux est documenté sous [Désactiver le mode HIPAA](/compliance/hipaa#6-disabling-hipaa-mode). Si le statut du BAA n'est pas `executed`, l'appel renvoie `403 Forbidden`.

## 3. Restreindre les rôles et scopes API au minimum nécessaire

Le standard *minimum necessary* de HIPAA est **votre** responsabilité — il est du côté client du [tableau de responsabilité partagée](/compliance/hipaa#shared-responsibility). Les contrôles d'Orbit sont aujourd'hui grossiers, donc provisionnez pour cela honnêtement :

* Utilisez le **rôle `billing`** pour le personnel qui n'a besoin que des surfaces financières. Les membres billing sont confinés à la facturation, la tarification et l'usage — ils reçoivent `403` sur les endpoints de contenu de message.
* Gardez en tête le besoin de lecture de tous les autres : `owner`, `admin`, `developer` et `viewer` peuvent tous lire le contenu des messages aujourd'hui, et chaque lecture atterrit dans le journal d'accès PHI.
* Émettez des clés API avec seulement les scopes dont l'intégration a besoin, et n'accordez `messages:read` qu'aux services qui lisent vraiment du contenu de message porteur de PHI.

> **Limitation connue :** Orbit ne restreint actuellement pas les lectures de contenu de message à un ensemble de rôles plus étroit au-delà du confinement billing, et les endpoints de lecture de message (`GET /messages`, `GET /messages/{id}`) ne requièrent pas de code de raison fourni par l'opérateur. Respectez le standard minimum-necessary en provisionnant l'appartenance du workspace et les scopes de clés API de sorte que seul le personnel qui a besoin de PHI puisse atteindre ces endpoints. Si votre programme exige une restriction de lecture par rôle sur le contenu des messages, contactez [compliance@devotel.io](mailto:compliance@devotel.io) avant de vous y fier.

## 4. Configurer la rétention des données

Configurez la fenêtre de rétention avant que le PHI ne s'accumule au-delà. `data_retention_days` accepte 30–3 650 ; le défaut est 365.

* **Dashboard :** **Paramètres → Compliance → HIPAA → Rétention des données**.
* **API** (propriétaire uniquement, même endpoint que le toggle) :

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT https://api.orbit.devotel.io/api/v1/settings/hipaa \
    -H "X-API-Key: $ORBIT_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "enabled": true, "data_retention_days": 90 }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/settings/hipaa",
    {
      method: "PUT",
      headers: {
        "X-API-Key": process.env.ORBIT_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ enabled: true, data_retention_days: 90 }),
    },
  );
  console.log((await res.json()).data.data_retention.days); // 90
  ```
</CodeGroup>

La réponse renvoie l'objet statut complet (même forme que l'appel d'activation ci-dessus) ; vérifiez `data.data_retention.days`.

Un job en arrière-plan scanne les contenus de message enregistrés appels et les pièces jointes media expirés et les supprime. Les logs d'audit et les logs d'accès PHI sont conservés indépendamment de cette politique — l'horloge de suppression n'efface pas votre piste de preuve.

Si vous enregistrez des appels, épinglez la région vocale pour correspondre à vos obligations de résidence au même moment — voir [Résidence des données vocales et rétention](/compliance/voice-data-residency) pour le bouton de résidence qui maintient enregistrements, messagerie vocale et média live dans une région.

## 5. Vérifier la configuration

Confirmez que le drapeau et la rétention ont atterri comme vous le vouliez (propriétaire ou administrateur) :

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.orbit.devotel.io/api/v1/settings/hipaa \
    -H "X-API-Key: $ORBIT_KEY"
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/settings/hipaa",
    { headers: { "X-API-Key": process.env.ORBIT_KEY! } },
  );
  const { data } = await res.json();
  console.log(data.enabled, data.data_retention.days);
  ```
</CodeGroup>

```json theme={null}
{
  "data": {
    "enabled": true,
    "enabled_at": "2026-09-23T14:05:40.118Z",
    "last_enabled_at": "2026-09-23T14:05:40.118Z",
    "disabled_at": null,
    "enable_history": [ { "enabledAt": "2026-09-23T14:05:40.118Z" } ],
    "baa_status": "executed",
    "hipaa_required": true,
    "baa": { "signed": true, "signedAt": "2026-09-23T14:02:11.482Z", "documentPresent": true, "history": [] },
    "data_retention": { "enabled": true, "days": 90 },
    "encryption_algorithm": "AES-256-GCM",
    "phi_access_log_count": 12
  },
  "meta": { "request_id": "…", "timestamp": "…" }
}
```

Vérifiez `enabled` et `data_retention.days` dans la réponse.

> La réponse porte aussi un champ `encryption_algorithm`. Il est **pour rapport seulement** : il reflète le standard de chiffrement au repos de la plateforme (AES-256 géré par Google sur Cloud SQL), pas un chiffreur de couche application par organisation. Devotel n'effectue actuellement pas de chiffrement de couche application par organisation des corps de message, donc ne citez pas ce champ à un auditeur comme preuve que les corps de message sont individuellement chiffrés à la couche application.

## 6. Lire le journal d'accès PHI

Une fois le mode HIPAA activé, chaque accès à des données contenant du PHI est écrit dans un journal d'audit append-only. Chaque entrée enregistre l'utilisateur, la ressource, la raison (`read` est enregistré automatiquement sur les lectures de message) et le timestamp. Pagez avec `?limit=` et `?cursor=` — passez l'`id` de la dernière entrée vue comme `cursor` suivant (propriétaire ou administrateur) :

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.orbit.devotel.io/api/v1/settings/hipaa/phi-access-log?limit=50" \
    -H "X-API-Key: $ORBIT_KEY"
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/settings/hipaa/phi-access-log?limit=50",
    { headers: { "X-API-Key": process.env.ORBIT_KEY! } },
  );
  const { data } = await res.json();
  console.log(data.entries[0]?.resource, data.has_more);
  ```
</CodeGroup>

```json theme={null}
{
  "data": {
    "entries": [
      {
        "id": "phi_…",
        "userId": "user_…",
        "resource": "message:msg_…",
        "reason": "read",
        "accessedAt": "2026-09-23T14:12:07.901Z"
      },
      {
        "id": "phi_…",
        "userId": "user_…",
        "resource": "contact:con_…",
        "reason": "treatment",
        "accessedAt": "2026-09-23T13:58:44.210Z"
      }
    ],
    "has_more": true,
    "total": 12
  },
  "meta": { "request_id": "…", "timestamp": "…" }
}
```

Le journal conserve jusqu'à 10 000 entrées par organisation avec les plus anciennes rotées, est accessible aux rôles `owner` et `admin` via le dashboard ou l'API, et peut être exporté pour des audits externes. Passez-le en revue sur un calendrier tôt — c'est comme vous démontrez que l'accès suit les décisions de rôle et de scope que vous avez prises à l'étape 3. Quand `has_more` est `true`, envoyez l'`id` de la dernière entrée comme `?cursor=` pour la page suivante.

## 7. Exporter le binder de preuves HIPAA

Quand vous devez montrer la posture à un auditeur ou à l'équipe procurement d'un acheteur, générez le pack HIPAA du [binder de preuves](/compliance/evidence-binder) depuis **Paramètres → Compliance → Binder**. Le framework HIPAA assemble la journalisation d'accès PHI, la posture BAA et votre rétention configurée en un pack signé et prêt à télécharger ; chaque génération est enregistrée dans votre journal d'audit, et le lien de téléchargement expire après 24 heures.

## Bundle d'activation healthcare

Le [marketplace des plugins de compliance](/compliance/plugin-marketplace) livre un bundle d'activation **HIPAA healthcare** qui provisionne un profil de compliance en brouillon, des campagnes en brouillon, un agent AI réglé vertical et une configuration de flux opt-in en un appel. C'est un échafaudage de départ, pas un substitut de cette séquence : activer le bundle n'exécute jamais le BAA, n'active jamais le mode HIPAA et ne place jamais un envoi. Exécutez les étapes 1–6 ci-dessus d'abord, puis activez le bundle et travaillez sa checklist go-live de brouillon à production.

## Checklist d'ordre des opérations

* [ ] BAA exécuté et `baa_status` confirmé comme `executed` — *rôle propriétaire*
* [ ] Mode HIPAA activé via le toggle ou `PUT /settings/hipaa` — *rôle propriétaire*
* [ ] Appartenance taillée au minimum nécessaire ; `messages:read` scope uniquement aux clés qui en ont besoin — *administrateur*
* [ ] `data_retention_days` fixé à votre fenêtre de politique — *administrateur*
* [ ] Région vocale épinglée si vos obligations de résidence restreignent où l'audio enregistré peut vivre — *administrateur*
* [ ] `GET /settings/hipaa` vérifié, avec `encryption_algorithm` traité comme rapport-seulement — *officier de compliance*
* [ ] Journal d'accès PHI passé en revue sur calendrier — *officier de compliance*
* [ ] Binder de preuves HIPAA généré et remis via le lien de 24 heures — *officier de compliance*
