
# Mettre à jour une adhésion

`PATCH /v1/organizations/{org_id}/memberships/{membership_id}` · autorisation `organizations:write`

Modifie les `role_ids` de l'adhésion (l'ensemble complet des rôles attribués manuellement) ou `expires_at` à l'aide d'un JSON merge patch (`Content-Type: application/merge-patch+json`). Les deux champs peuvent changer dans la même requête ; ils sont appliqués dans une seule transaction, de sorte que soit les deux sont écrits, soit aucun ne l'est, et un enregistrement d'audit `organization_membership.updated` est écrit. `expires_at` doit être dans le futur et au plus 365 jours après la création de l'adhésion ; `null` supprime la date de fin. `role_ids: null` n'a aucun effet. Les règles relatives aux rôles sont celles de `PUT …/roles`. Un champ égal à sa valeur actuelle n'est pas écrit. L'écriture est auditée sous le nom `organization_membership.updated`.

## Requête

| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| `org_id` | chemin | oui | Identifiant de l'organisation (`org_…`). |
| `membership_id` | chemin | oui | Identifiant de l'adhésion (`mem_…`). |
| `If-Match` | en-tête | non | `ETag` actuel ; s'il est fourni, il doit correspondre (`412`) et verrouille l'écriture sur cette version. |
| `role_ids` | string[] | non | Ensemble complet des identifiants de rôles attribués manuellement (`rol_…`), 50 au maximum. |
| `expires_at` | string \| null | non | Fin de l'adhésion (RFC 3339) ; `null` la supprime. |

## Réponse

`200 OK` avec l'adhésion mise à jour et son `ETag`.

```json
{
  "id": "mem_01j9xn5p9s0t4v6w8x0y2z4a6c",
  "organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
  "user_id": "usr_01j9xh2k6p7q1r3s5t7v9w1x3y",
  "status": "active",
  "source": "admin_api",
  "reason": null,
  "roles": [
    {
      "role_id": "rol_01j9xr7s1t2w6x8y0z2a4b6c8e",
      "source": "admin_api",
      "assigned_at": "2026-10-12T09:31:00.123456Z"
    }
  ],
  "expires_at": "2027-01-01T00:00:00Z",
  "created_at": "2026-10-12T09:31:00.123456Z",
  "activated_at": "2026-10-12T09:31:00.123456Z",
  "suspended_at": null,
  "removed_at": null,
  "updated_at": "2026-10-12T10:00:00Z",
  "version": 2
}
```

## Erreurs

| HTTP | code | Quand |
|---|---|---|
| 404 | `not_found` | L'adhésion n'existe pas dans cette organisation. |
| 403 | `role_not_assignable` | Un rôle n'est ni un rôle de l'environnement ni un rôle de cette organisation. |
| 409 | `last_org_admin` | La modification laisserait l'organisation sans administrateur actif. |
| 412 | `precondition_failed` | `If-Match` ne correspond pas à la version actuelle. |
| 415 | `unsupported_media_type` | Le corps n'est pas de type `application/merge-patch+json`. |
| 422 | `validation_failed` | `expires_at` est hors plage ou l'adhésion est supprimée (`invalid_state`), ou une valeur est invalide. |
| 401 | `unauthenticated` | L'identifiant d'authentification est absent, invalide ou révoqué. |
| 403 | `insufficient_permissions` | L'identifiant d'authentification ne dispose pas de l'autorisation requise. Attribuer un rôle privilégié (`is_privileged`) requiert aussi `roles:write` ; sans cette autorisation, rien n'est écrit et `required_permissions` liste les deux autorisations. |
| 429 | `rate_limited` | La limite de débit a été dépassée ; réessayez après la durée indiquée par `Retry-After`. |
| 503 | `service_unavailable` | Une dépendance est temporairement indisponible ; réessayez après la durée indiquée par `Retry-After`. |

## Exemple

```bash
curl -i -X PATCH "https://api.eu.keenauth.com/v1/organizations/org_01j9xk3m7q8r2s4t6v8w0y2z4a/memberships/mem_01j9xn5p9s0t4v6w8x0y2z4a6c" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{"expires_at":"2027-01-01T00:00:00Z"}'
```

## Données personnelles

Cet endpoint traite des données personnelles : adhésions et invitations à une organisation. [Données personnelles dans les API KeenAuth](/docs/policies/personal-data) décrit les données stockées, leur durée de conservation et leur mode de suppression. N'envoyez pas de catégories particulières de données personnelles (santé, données biométriques, religion, opinions politiques, orientation sexuelle) dans aucun champ.
