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

# API de création d'application : apps programmatiques

> Créez une application Didit par client, marque ou environnement avec POST /organizations/me/{org_id}/applications/. Renvoie client_id et api_key.



Prompt de création d'application
        Copier le prompt dans le presse-papiers



      
      

\<pre>

\`Create a new Didit application inside one of your organizations — each application has its own client_id and api_key, isolating sessions, webhooks, branding, and billing from sibling applications.

Endpoint:
POST https://apx.didit.me/auth/v2/organizations/me/{org_id}/applications/

Authentication:
Authorization: Bearer <access_token>
The access token must belong to an OWNER or ADMIN of the target organization. Get one via POST /programmatic/login/ or POST /programmatic/verify-email/.

Path parameter:
\- org_id (UUID, required) — Organization that will own the new application. Discover yours via GET /organizations/me/.

Request body (ALL fields optional — omit the body to get a default-named app):
\- name (string, optional) — Display name. Defaults to "<organization name> App".
\- website_url (string, URL, optional) — Public homepage shown in the verification flow.
\- redirect_uris (array of strings, optional) — Allowlisted OAuth-style redirect URIs.
\- terms_url (string, URL, optional) — Terms-of-service link shown in the verification UI.
\- privacy_url (string, URL, optional) — Privacy policy link shown in the verification UI.
\- description (string, optional) — Internal note. Not shown to end users.
\- data_location (string, optional) — Where the application's verification data is stored and processed: "eu" (European Union, Ireland), the default. "au" (Australia, Sydney) and "mx" (Mexico) are coming soon and answer 400 today. Chosen once: it can't be changed after the application is created.

When to call:
\- Resellers — one application per end customer to fully isolate credentials, branding, webhooks, and billing.
\- Multi-brand / multi-product — one application per brand, product, region, or environment (dev / staging / prod).
\- Use-case separation — e.g. one application for ID + selfie KYC, another for AML screening only.

curl example:
curl -X POST "https://apx.didit.me/auth/v2/organizations/me/<ORG_ID>/applications/" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Customer App",
"website_url": "https://acme.example",
"redirect_uris": ["https://acme.example/callback"],
"terms_url": "https://acme.example/terms",
"privacy_url": "https://acme.example/privacy",
"data_location": "eu"
}'

Response (201 Created):
\{
"uuid": "b2c3d4e5-6789-...",
"name": "Acme Customer App",
"client_id": "S9LIYGSoWNuGMLHsvEt9dQ",
"api_key": "sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"website_url": "https://acme.example",
"redirect_uris": ["https://acme.example/callback"],
"terms_url": "https://acme.example/terms",
"privacy_url": "https://acme.example/privacy",
"description": null,
"created_at": "2025-06-01T10:00:00Z",
"data_location": "eu",
"products": [
\{ "product": "identity", "status": "enabled", "modules": { "user_verification": true, "business_verification": true, "case_management": true } },
\{ "product": "transactions", "status": "disabled", "modules": { "travel_rule": true, "case_management": true } },
\{ "product": "authentication", "status": "disabled", "modules": {} }
]
}

What to do with the response:
\- PERSIST api_key SECURELY — use it as the x-api-key header on every https://verification.didit.me/v3/... call (sessions, workflows, billing).
\- Persist uuid (app_id) — required for /organizations/me/{org_id}/applications/{app_id}/ reads and updates.
\- If you lose the api_key, recover it later via GET /organizations/me/{org_id}/applications/{app_id}/ — see /auth-api/get-credentials.
\- products is read-only and always lists identity, transactions and authentication in that order. A new application has identity enabled with every module on, and transactions and authentication disabled. A products key in the request body is ignored.

Failure modes:
\- 400 — { "<field>": ["Enter a valid URL."] } for malformed website_url / redirect_uris / terms_url / privacy_url.
\- 400 — { "data_location": ["This data location is not available yet."] } for "au" or "mx", and { "data_location": ["\\"us\\" is not a valid choice."] } for a location that does not exist. Nothing is created.
\- 401: { "detail": "Invalid access token" } or { "detail": "Expired access token" } when the token is malformed or expired.
\- 403: { "detail": "Only organization owners and admins can manage applications." } when you are a member of the organization but not an owner or admin.
\- 403: { "detail": "Your access to this organization is suspended." } when your membership in the organization is suspended.
\- 403: { "detail": "You do not have permission to perform this action." } when the request has no Authorization header.
\- 404: { "detail": "Organization not found." } when the organization does not exist or you are not a member of it.

Next steps:
\- Configure a workflow inside the new application via POST /v3/workflows/ — see /management-api/workflows/create.
\- Update application metadata later via PATCH /organizations/me/{org_id}/applications/{app_id}/ — see /auth-api/update-application.

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.`

\</pre>



      
      

Coller dans

Utilisez cet endpoint lorsque vous devez séparer le trafic de vérification, les identifiants, l'image de marque ou les rapports au sein de la même organisation.Cela est particulièrement utile pour les **revendeurs** qui créent une application par client. Cela convient également lorsque votre entreprise dispose de plusieurs produits, marques, régions, environnements de préproduction et de production, ou cas d'usage qui ne doivent pas partager la même clé API ni les mêmes paramètres au niveau de l'application.> [!NOTE]
>
> Tous les endpoints de l'Auth API utilisent `https://apx.didit.me/auth/v2`. Utilisez la valeur `api_key` renvoyée comme `x-api-key` lors de l'appel aux endpoints `https://verification.didit.me/v3/...`, tels que les sessions et les workflows.## Localisation des donnéesChaque application stocke et traite ses données de vérification à un emplacement unique, appelé sa localisation des données, choisi lors de sa création avec `data_location`.
Aujourd'hui, la seule localisation disponible est `eu`, l'Union européenne (Irlande), qui est aussi la valeur par défaut si vous omettez ce champ.
L'Australie (Sydney, `au`) et le Mexique (`mx`) sont bientôt disponibles : une requête qui les mentionne reçoit une réponse 400 `This data location is not available yet.` et ne crée rien.
Chaque lecture de l'application renvoie sa `data_location`, qui ne peut pas être modifiée une fois l'application créée.
Voir [Localisation des données](https://docs.didit.me/fr/console/applications.md#localisation-des-données).


## OpenAPI

````yaml fr/openapi-auth.json POST /organizations/me/{org_id}/applications/
openapi: 3.0.0
info:
  version: 1.0.0
  title: Didit Auth API
  description: "API d'inscription et d'authentification programmatiques pour les développeurs et les agents IA. Inscrivez-vous en 2 appels d'API -- aucun navigateur requis. La plateforme de vérification d'identité la plus adaptée aux agents.\n\n## URL de base\n\nTous les endpoints de cette spécification sont hébergés sur `https://apx.didit.me/auth/v2`. Il s'agit d'un hôte différent de celui de l'API de vérification (`https://verification.didit.me/v3`). Distinguez-les bien\_: cet hôte d'authentification délivre vos **tokens d'accès JWT** et vous permet de lister et gérer vos **organisations** et **applications**. L'hôte de vérification est celui sur lequel vous appelez les sessions, les workflows, l'AML, etc., en vous authentifiant avec la **`api_key`** renvoyée par cette API.\n\n## Fonctionnement du flux d'authentification\n\n1. `POST /programmatic/register/` — soumettez e-mail + mot de passe.\n2. Recevez un code alphanumérique de 6 caractères par e-mail.\n3. `POST /programmatic/verify-email/` — soumettez le code. Vous recevez en retour un `access_token` JWT, un `refresh_token`, une organisation et une application par défaut avec `client_id` + `api_key`.\n4. Enregistrez la `api_key`. Utilisez-la comme `x-api-key` pour chaque appel vers `https://verification.didit.me/v3/...`.\n5. Depuis n'importe quelle machine ultérieure, `POST /programmatic/login/` échange votre e-mail + mot de passe contre un nouveau JWT, puis appelez `GET /organizations/me/` et les endpoints d'application pour récupérer ou renouveler les identifiants.\n\nLe JWT n'est requis que pour les endpoints de **Gestion de compte** de cette spécification\_; le trafic de l'API de vérification utilise la `api_key` de longue durée, pas le JWT.\n\n## Conventions\n\n- Tous les corps de requête et de réponse sont en JSON (`Content-Type: application/json`).\n- **Utilisez une véritable adresse e-mail distribuable lors du test de `POST /programmatic/register/`.** L'endpoint envoie le code de vérification de manière synchrone\_; les adresses sur des domaines de test réservés (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) sont donc refusées par le service de distribution des e-mails et la requête renvoie une erreur `500`. Remplacez l'espace réservé `you@yourdomain.com` dans les exemples par une boîte de réception que vous pouvez réellement consulter.\n- Les erreurs de validation renvoient un code HTTP `400` avec l'une des deux structures\_: `{\"field\": [\"message\", ...]}` pour les problèmes au niveau des champs, ou `{\"detail\": \"message\"}` pour les erreurs de règles métier. Quelques validateurs (force du mot de passe lors de l'inscription, expiration du code lors de la vérification de l'e-mail) répondent actuellement avec un simple tableau `[\"message\"]` au lieu du format avec des clés correspondant aux champs -- il s'agit d'une incohérence connue côté serveur\_; le code client doit donc accepter les deux formats.\n- Les erreurs d'authentification renvoient `{\"detail\": \"...\"}` avec un code HTTP `401` (token porteur non valide) ou `403` (token porteur manquant / privilèges insuffisants).\n- Les réponses de limite de débit incluent un champ `wait` indiquant le délai d'attente en secondes."
servers:
  - url: https://apx.didit.me/auth/v2
    description: Serveur d'authentification de production
security: []
tags:
  - name: Programmatic Auth
    description: >-
      Cycle de vie d'un compte avec e-mail et mot de passe : inscription,
      vérification, connexion. Renvoie le `access_token` JWT que vous utilisez
      sur les endpoints de gestion de compte, plus (lors de la vérification) le
      `client_id` et la `api_key` de votre première application.
  - name: Account Management
    description: >-
      Endpoints authentifiés (Bearer JWT) qui listent les organisations et
      créent, récupèrent ou mettent à jour des applications. Utilisez-les pour
      récupérer ou remplacer la clé `api_key` avec laquelle vous authentifiez
      les appels à l'API de vérification.
paths:
  /organizations/me/{org_id}/applications/:
    post:
      tags:
        - Account Management
      summary: Créer une application
      description: "Créez une application au sein d'une organisation, dans l'emplacement de données de votre choix (`data_location`, l'Union européenne par défaut\_; il ne peut pas être modifié ultérieurement). La réponse inclut `api_key`\_; conservez-la dès maintenant (récupérable via GET). Nécessite un JWT propriétaire/administrateur."
      operationId: create_organization_application
      parameters:
        - name: org_id
          in: path
          required: true
          description: UUID de l'organisation. Obtenez-le avec `GET /organizations/me/`.
          schema:
            type: string
            format: uuid
            example: a1b2c3d4-5678-90ab-cdef-111111111111
      requestBody:
        required: false
        description: >-
          Tous les champs sont facultatifs. Omettre le corps crée une
          application avec le nom par défaut `"<organization name> App"` et
          aucune URL publique configurée.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApplicationCreateRequest'
            examples:
              ResellerCustomer:
                summary: >-
                  Revendeur déployant une application limitée au périmètre d'un
                  client
                value:
                  name: Acme Customer App
                  website_url: https://acme.example
                  redirect_uris:
                    - https://acme.example/callback
                  terms_url: https://acme.example/terms
                  privacy_url: https://acme.example/privacy
                  data_location: eu
              Minimal:
                summary: Création minimale -- accepter toutes les valeurs par défaut
                value:
                  name: Sandbox App
              Empty:
                summary: >-
                  Aucun corps de requête : la valeur par défaut est <nom de
                  l'organisation> App
                value: {}
      responses:
        '201':
          description: >-
            Application créée. La réponse inclut la `api_key` de longue durée ;
            conservez-la dès maintenant et utilisez-la comme en-tête `x-api-key`
            sur chaque appel `https://verification.didit.me/v3/...`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Application'
              examples:
                Success:
                  value:
                    uuid: b2c3d4e5-6789-01bc-defg-222222222222
                    name: Acme Customer App
                    client_id: S9LIYGSoWNuGMLHsvEt9dQ
                    api_key: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                    website_url: https://acme.example
                    redirect_uris:
                      - https://acme.example/callback
                    terms_url: https://acme.example/terms
                    privacy_url: https://acme.example/privacy
                    description: null
                    created_at: '2025-06-01T10:00:00Z'
                    data_location: eu
                    products:
                      - product: identity
                        status: enabled
                        modules:
                          user_verification: true
                          business_verification: true
                          case_management: true
                      - product: transactions
                        status: disabled
                        modules:
                          travel_rule: true
                          case_management: true
                      - product: authentication
                        status: disabled
                        modules: {}
        '400':
          description: >-
            Erreur de validation dans le corps de la requête : par exemple un
            URI de redirection mal formé, un `data_location` qui n'est pas
            encore disponible (`au`, `mx`) ou un qui n'existe pas. Rien n'est
            créé.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
              examples:
                InvalidUrl:
                  value:
                    website_url:
                      - Enter a valid URL.
                DataLocationNotAvailable:
                  summary: Un emplacement de données prochainement disponible
                  value:
                    data_location:
                      - This data location is not available yet.
                UnknownDataLocation:
                  summary: Un emplacement de données qui n'existe pas
                  value:
                    data_location:
                      - '"us" is not a valid choice.'
        '401':
          description: >-
            Token d'accès malformé, invalide ou expiré. Obtenez-en un nouveau
            avec `POST /programmatic/login/`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthError'
              examples:
                InvalidToken:
                  value:
                    detail: Invalid access token
                ExpiredToken:
                  value:
                    detail: Expired access token
        '403':
          description: >-
            Vous ne pouvez pas créer d'applications dans cette organisation. Un
            membre de l'organisation qui n'est ni propriétaire ni administrateur
            reçoit `Only organization owners and admins can manage
            applications.` Un propriétaire ou un administrateur dont l'accès à
            l'organisation est suspendu reçoit `Your access to this organization
            is suspended.` Une requête sans en-tête `Authorization` reçoit `You
            do not have permission to perform this action.` Pendant les 72
            heures suivant la récupération de votre compte, la requête est
            refusée avec le `code` `recovery_hold` et `until`, l'heure à
            laquelle le blocage prend fin.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/AuthError'
                  - $ref: '#/components/schemas/RecoveryHoldError'
              examples:
                NotOwnerOrAdmin:
                  summary: Membre qui n'est ni propriétaire ni administrateur
                  value:
                    detail: >-
                      Only organization owners and admins can manage
                      applications.
                Suspended:
                  summary: Adhésion suspendue
                  value:
                    detail: Your access to this organization is suspended.
                MissingToken:
                  summary: Aucun en-tête Authorization
                  value:
                    detail: You do not have permission to perform this action.
                RecoveryHold:
                  summary: Compte récupéré il y a moins de 72 heures
                  value:
                    detail: This action is on hold because you recovered your account.
                    code: recovery_hold
                    until: '2026-11-04T10:15:00+00:00'
        '404':
          description: L'organisation n'existe pas ou vous n'en êtes pas membre.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthError'
              examples:
                OrganizationNotFound:
                  summary: Organisation introuvable, ou vous n'en êtes pas membre
                  value:
                    detail: Organization not found.
      security:
        - BearerAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: >-
            curl -X POST
            "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/"
            \
              -H "Authorization: Bearer $ACCESS_TOKEN" \
              -H "Content-Type: application/json" \
              -d '{
                "name": "Acme Customer App",
                "website_url": "https://acme.example",
                "redirect_uris": ["https://acme.example/callback"],
                "data_location": "eu"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Use the access token that account.login returns.
            client = Didit(account_token="YOUR_ACCESS_TOKEN")

            result = client.account.applications.create(
                "a1b2c3d4-5678-90ab-cdef-111111111111",
                name="Acme Customer App",
                website_url="https://acme.example",
                redirect_uris=["https://acme.example/callback"],
                terms_url="https://acme.example/terms",
                privacy_url="https://acme.example/privacy",
                data_location="eu",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: >-
            import Didit from "@didit-protocol/sdk-node";


            // Use the access token that account.login returns.

            const didit = new Didit({ accountToken: "YOUR_ACCESS_TOKEN" });


            const result = await
            didit.account.applications.create("a1b2c3d4-5678-90ab-cdef-111111111111",
            {
              name: "Acme Customer App",
              website_url: "https://acme.example",
              redirect_uris: ["https://acme.example/callback"],
              terms_url: "https://acme.example/terms",
              privacy_url: "https://acme.example/privacy",
              data_location: "eu",
            });

            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Use the access token that account.login returns.\nclient := didit.NewClient(option.WithAccountToken(\"YOUR_ACCESS_TOKEN\"))\n\nresult, err := client.Account.Applications.Create(ctx, \"a1b2c3d4-5678-90ab-cdef-111111111111\", didit.ApplicationCreateRequest{\n\tName:         didit.String(\"Acme Customer App\"),\n\tWebsiteURL:   didit.String(\"https://acme.example\"),\n\tRedirectURIs: didit.Some([]string{\"https://acme.example/callback\"}),\n\tTermsURL:     didit.String(\"https://acme.example/terms\"),\n\tPrivacyURL:   didit.String(\"https://acme.example/privacy\"),\n\tDataLocation: didit.Some(didit.ApplicationDataLocation(\"eu\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.util.List;

            import me.didit.Didit;

            import me.didit.types.ApplicationCreateRequest;

            import me.didit.types.ApplicationDataLocation;


            // Use the access token that account.login returns.

            Didit client =
            Didit.builder().accountToken("YOUR_ACCESS_TOKEN").build();


            var result =
            client.account().applications().create("a1b2c3d4-5678-90ab-cdef-111111111111",
            ApplicationCreateRequest.builder()
                    .name("Acme Customer App")
                    .websiteUrl("https://acme.example")
                    .redirectUris(List.of("https://acme.example/callback"))
                    .termsUrl("https://acme.example/terms")
                    .privacyUrl("https://acme.example/privacy")
                    .dataLocation(ApplicationDataLocation.of("eu"))
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: >-
            <?php


            require 'vendor/autoload.php';


            use Didit\DiditClient;


            // Use the access token that account.login returns.

            $didit = new DiditClient(accountToken: 'YOUR_ACCESS_TOKEN');


            $result =
            $didit->account->applications->create('a1b2c3d4-5678-90ab-cdef-111111111111',
            [
                'name' => 'Acme Customer App',
                'website_url' => 'https://acme.example',
                'redirect_uris' => ['https://acme.example/callback'],
                'terms_url' => 'https://acme.example/terms',
                'privacy_url' => 'https://acme.example/privacy',
                'data_location' => 'eu',
            ]);

            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Use the access token that account.login returns.
            didit = Didit::Client.new(account_token: "YOUR_ACCESS_TOKEN")

            result = didit.account.applications.create(
              "a1b2c3d4-5678-90ab-cdef-111111111111",
              name: "Acme Customer App",
              website_url: "https://acme.example",
              redirect_uris: ["https://acme.example/callback"],
              terms_url: "https://acme.example/terms",
              privacy_url: "https://acme.example/privacy",
              data_location: "eu"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Use the access token that account.login returns.

            using var client = new DiditClient(new DiditClientOptions {
            AccountToken = "YOUR_ACCESS_TOKEN" });


            var result = await
            client.Account.Applications.CreateAsync("a1b2c3d4-5678-90ab-cdef-111111111111",
            new ApplicationCreateRequest

            {
                Name = "Acme Customer App",
                WebsiteUrl = "https://acme.example",
                RedirectUris = new string[] { "https://acme.example/callback" },
                TermsUrl = "https://acme.example/terms",
                PrivacyUrl = "https://acme.example/privacy",
                DataLocation = new ApplicationDataLocation("eu"),
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    ApplicationCreateRequest:
      type: object
      description: >-
        Tous les champs sont facultatifs. Envoyer un corps vide crée une
        application avec un nom par défaut, dans l'Union européenne.
      properties:
        name:
          type: string
          description: >-
            Nom d'affichage de l'application. Vaut par défaut `"<organization
            name> App"`.
          example: Acme Customer App
        website_url:
          type: string
          description: URL du site web ou de l'application associée à cette application.
          example: https://acme.example
        redirect_uris:
          type: array
          items:
            type: string
          description: >-
            URI de redirection autorisées pour les flux de redirection de type
            OAuth et de vérification.
          example:
            - https://acme.example/callback
        terms_url:
          type: string
          description: >-
            URL des conditions d'utilisation affichée dans le flux de
            vérification.
          example: https://acme.example/terms
        privacy_url:
          type: string
          description: >-
            URL de la politique de confidentialité affichée dans le flux de
            vérification.
          example: https://acme.example/privacy
        description:
          type: string
          description: >-
            Description interne de l'application (non visible par les
            utilisateurs finaux).
        data_location:
          $ref: '#/components/schemas/ApplicationDataLocation'
    Application:
      type: object
      description: >-
        Enregistrement complet de l'application. `uuid`, `client_id` et
        `api_key` ne changent jamais après la création. `data_location` non
        plus, sauf une fois sur l'application de production créée avec votre
        organisation, avant sa première utilisation (voir la requête de mise à
        jour).
      properties:
        uuid:
          type: string
          format: uuid
          description: >-
            UUID de l'application. À utiliser comme `{app_id}` dans les appels
            ultérieurs.
          example: b2c3d4e5-6789-01bc-defg-222222222222
        name:
          type: string
          description: Nom d'affichage de l'application affiché dans la console Didit.
          example: Acme Production App
        client_id:
          type: string
          description: >-
            Identifiant client public, pouvant être intégré en toute sécurité
            dans des flux de type OAuth.
          example: S9LIYGSoWNuGMLHsvEt9dQ
        api_key:
          type: string
          description: >-
            Secret à longue durée de vie (également appelé `client_secret`). À
            utiliser comme en-tête `x-api-key` pour chaque appel à
            `https://verification.didit.me/v3/...` (sessions, workflows, AML,
            etc.). Traitez-le comme un identifiant confidentiel ; ne l'exposez
            jamais côté client. Les nouvelles clés commencent par `sk_live_`
            (application de production) ou `sk_test_` (application sandbox),
            suivies de 43 caractères compatibles avec les URL (lettres,
            chiffres, `-` et `_`). Les clés créées avant ce format n'ont aucun
            préfixe et continuent de fonctionner à l'identique. Pendant 72
            heures après la récupération de votre compte, lister, récupérer et
            mettre à jour renvoient une chaîne vide ici à la place de la clé.
          example: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        website_url:
          type: string
          nullable: true
          description: URL du site web ou de l'application associée à cette application.
          example: https://acme.example
        redirect_uris:
          type: array
          items:
            type: string
          description: >-
            URI de redirection autorisées pour les flux de redirection de type
            OAuth et de vérification.
          example:
            - https://acme.example/callback
        terms_url:
          type: string
          nullable: true
          description: >-
            URL des conditions d'utilisation affichée dans le flux de
            vérification.
          example: https://acme.example/terms
        privacy_url:
          type: string
          nullable: true
          description: >-
            URL de la politique de confidentialité affichée dans le flux de
            vérification.
          example: https://acme.example/privacy
        description:
          type: string
          nullable: true
          description: >-
            Description interne de l'application (non visible par les
            utilisateurs finaux).
        created_at:
          type: string
          format: date-time
          example: '2025-06-01T10:00:00Z'
        data_location:
          $ref: '#/components/schemas/ApplicationDataLocation'
        products:
          type: array
          readOnly: true
          description: >-
            Les produits de l'application. Toujours les trois, dans cet ordre :
            `identity`, `transactions`, `authentication`. Une nouvelle
            application a `identity` activé avec chaque module activé, et
            `transactions` ainsi que `authentication` désactivés. Lecture seule
            : une clé `products` dans un corps de création ou de mise à jour est
            ignorée.
          items:
            $ref: '#/components/schemas/ApplicationProduct'
          example:
            - product: identity
              status: enabled
              modules:
                user_verification: true
                business_verification: true
                case_management: true
            - product: transactions
              status: disabled
              modules:
                travel_rule: true
                case_management: true
            - product: authentication
              status: disabled
              modules: {}
    ValidationError:
      description: >-
        Corps de l'erreur de validation. L'enveloppe prévue est une structure
        `{field: ["message", ...]}` pour les erreurs au niveau des champs ou une
        enveloppe à clé unique `{detail: "..."}` pour les erreurs de règles
        métier. Quelques validateurs (robustesse du mot de passe lors de
        l'inscription, validité du code lors de verify-email) répondent
        actuellement avec un simple tableau `["message"]`, une incohérence
        connue côté serveur. Le schéma ci-dessous conserve cette branche avec
        tableau simple afin que le code client généré à partir de cette
        spécification désérialise les réponses actuelles, mais le nouveau code
        client devrait le traiter sous la forme indexée par champ appropriée
        (`{password: [...]}` ou `{code: [...]}`) et le contrat serveur
        convergera vers cette structure.
      oneOf:
        - type: object
          additionalProperties:
            type: array
            items:
              type: string
          example:
            email:
              - Enter a valid email address.
        - type: object
          properties:
            detail:
              type: string
          example:
            detail: An account with this email already exists.
        - type: array
          items:
            type: string
          example:
            - Invalid or expired verification code.
    AuthError:
      type: object
      description: >-
        Enveloppe d'erreur d'authentification / d'autorisation / d'élément
        introuvable.
      properties:
        detail:
          type: string
          example: Invalid access token
    RecoveryHoldError:
      type: object
      description: >-
        Renvoyé pendant 72 heures après la récupération du compte (les méthodes
        de connexion perdues ont été réinitialisées). Les actions créant des
        organisations, des applications ou des secrets sont refusées jusqu'à
        `until` ; les opérations de lecture continuent de fonctionner.
      required:
        - detail
        - code
        - until
      properties:
        detail:
          type: string
          example: This action is on hold because you recovered your account.
        code:
          type: string
          enum:
            - recovery_hold
          example: recovery_hold
        until:
          type: string
          format: date-time
          description: >-
            Date et heure de fin du blocage temporaire (ISO 8601). Réessayez la
            requête après cette date.
          example: '2026-11-04T10:15:00+00:00'
    ApplicationDataLocation:
      type: string
      enum:
        - eu
        - au
        - mx
      description: >-
        Emplacement où les données de vérification de l'application sont
        stockées et traitées, choisi lors de la création de l'application. `eu`
        correspond à l'Union européenne (Irlande), la valeur par défaut. `au`
        (Australie, Sydney) et `mx` (Mexique) seront bientôt disponibles : une
        requête les mentionnant renvoie une erreur 400 `This data location is
        not available yet.` L'application Sandbox d'une organisation se trouve
        toujours dans l'Union européenne.
      example: eu
    ApplicationProduct:
      type: object
      description: >-
        Un produit d'une application et son état. En lecture seule : les
        endpoints de l'application le renvoient et l'ignorent dans le corps de
        la requête.
      properties:
        product:
          type: string
          enum:
            - identity
            - transactions
            - authentication
          description: >-
            `identity` (Vérification d'identité), `transactions` (Surveillance
            des transactions) ou `authentication` (Authentification).
          example: identity
        status:
          type: string
          enum:
            - enabled
            - early_access
            - disabled
          description: >-
            Indique si le produit est activé pour cette application.
            `early_access` s'applique uniquement à `authentication`, que Didit
            active pour vous.
          example: enabled
        modules:
          type: object
          additionalProperties:
            type: boolean
          description: >-
            Interrupteurs de modules du produit, chacun valant `true` ou
            `false`. `identity` comporte `user_verification`,
            `business_verification` et `case_management`. `transactions`
            comporte `travel_rule` et `case_management`. `authentication` n'en a
            aucun (`{}`). `case_management` est un paramètre unique affiché à la
            fois sous `identity` et `transactions`, il a donc la même valeur sur
            les deux.
          example:
            user_verification: true
            business_verification: true
            case_management: true
      required:
        - product
        - status
        - modules
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        JWT `access_token` signé en RS256 renvoyé par `POST
        /programmatic/login/` ou `POST /programmatic/verify-email/`. À envoyer
        sous la forme `Authorization: Bearer <access_token>`. La durée de vie
        par défaut est de 86400 secondes (24h). Ce token n'est valable que pour
        les endpoints de gestion de compte sur `apx.didit.me/auth/v2`. L'API de
        vérification (`verification.didit.me/v3`) utilise plutôt la `api_key` de
        longue durée sous forme de `x-api-key`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.