> ## 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.

# Registo programático na Auth API

> Crie organizações Didit via Auth API, sem browser. Pague por chamada, sem contratos. Ideal para infraestrutura KYC de sub-contas.



Prompt de registo programático
        Copiar o prompt para a área de transferência



      
      

\<pre>

\``Programmatically create a pending Didit account — step 1 of the two-step onboarding (no browser, no console).

Endpoint:
POST https://apx.didit.me/auth/v2/programmatic/register/

Authentication:
None. This is a public endpoint. (Don't confuse the Auth API host `apx.didit.me/auth/v2` with the verification host `verification.didit.me/v3`.)

Request body:
\- email (string, required) — Any real, deliverable email (personal, work, alias). The verification code is mailed synchronously, so reserved test domains (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) get rejected by mail delivery and the call returns `500` — substitute the placeholder with an inbox you can read.
\- password (string, required) — Must satisfy ALL of: minimum 8 characters, ≥1 uppercase letter (A-Z), ≥1 lowercase letter (a-z), ≥1 digit (0-9), ≥1 special character from !@#$%^&*()_+-=[]{}|;:,.<>?. Rules are validated one at a time and the first failure short-circuits.

curl example (replace `you@yourdomain.com` with a real inbox):
curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
-H "Content-Type: application/json" \
-d '{
"email": "you@yourdomain.com",
"password": "MyStr0ng!Pass"
}'

Response (201 Created):
\- message (string) — "Registration successful. Check your email for the verification code."
\- email (string) — echoed back.

What happens server-side:
\- A pending account is created (NOT usable yet).
\- A 6-character alphanumeric code (e.g. "A3K9F2") is emailed to the supplied address.
\- The code is valid for 15 minutes. After expiry the registration must be redone.

Failure modes (all 400 unless noted):
\- Field-level: { "email": ["Enter a valid email address."] } or { "password": ["Ensure this field has at least 8 characters."] }.
\- Password-strength failures CURRENTLY return as a BARE ARRAY (no field key), one rule at a time: ["Password must contain at least one uppercase letter."] / lowercase / digit / special character. Known server-side inconsistency — treat as { "password": [...] } client-side.
\- Duplicate email: { "detail": "An account with this email already exists." }
\- 429 — { "detail": "Too many registration attempts. Please try again later.", "wait": <seconds> } when more than 5 registrations from the same IP within an hour.
\- 500 — returned (with an HTML body, not JSON) when mail delivery to the supplied address fails synchronously. Most commonly triggered by reserved test domains; use a real inbox.

Rate limits:
5 registrations per IP per hour.

Next step:
After receiving the email, call POST https://apx.didit.me/auth/v2/programmatic/verify-email/ with { "email", "code" } to get your access_token and api_key — see /auth-api/verify-email.

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

\</pre>



      
      

Colar em



## OpenAPI

````yaml pt/openapi-auth.json POST /programmatic/register/
openapi: 3.0.0
info:
  version: 1.0.0
  title: Didit Auth API
  description: >-
    API de registo e autenticação programática para programadores e agentes de
    IA. Registe-se em 2 chamadas de API -- sem necessidade de navegador. A
    plataforma de verificação de identidade mais adaptada a agentes.


    ## URL base


    Todos os endpoints nesta especificação estão alojados em
    `https://apx.didit.me/auth/v2`. Este é um anfitrião diferente da API de
    verificação (`https://verification.didit.me/v3`). Não os confunda: este
    anfitrião de autenticação emite os seus **tokens de acesso JWT** e permite
    listar e gerir as suas **organizações** e **aplicações**. O anfitrião de
    verificação é onde chama sessões, fluxos, AML, etc., utilizando a
    **`api_key`** devolvida por esta API.


    ## Como funciona o fluxo de autenticação


    1. `POST /programmatic/register/` — envie e-mail + palavra-passe.

    2. Receba um código alfanumérico de 6 carateres por e-mail.

    3. `POST /programmatic/verify-email/` — envie o código. Recebe de volta um
    `access_token` JWT, um `refresh_token`, uma organização e uma aplicação
    predefinida com `client_id` + `api_key`.

    4. Guarde a `api_key`. Utilize-a como `x-api-key` em cada chamada para
    `https://verification.didit.me/v3/...`.

    5. A partir de qualquer máquina futura, `POST /programmatic/login/` troca o
    seu e-mail + palavra-passe por um novo JWT; em seguida, chame `GET
    /organizations/me/` e os endpoints de aplicações para recuperar ou renovar
    credenciais.


    O JWT só é necessário para os endpoints de **Gestão de contas** nesta
    especificação; o tráfego da API de verificação utiliza a `api_key` de longa
    duração, não o JWT.


    ## Convenções


    - Todos os corpos de pedido e resposta são JSON (`Content-Type:
    application/json`).

    - **Utilize um endereço de e-mail real e operacional ao testar `POST
    /programmatic/register/`.** O endpoint envia o código de verificação de
    forma síncrona, pelo que endereços em domínios de teste reservados
    (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) são
    recusados pela entrega de correio e o pedido devolve um `500`. Substitua o
    marcador de posição `you@yourdomain.com` nos exemplos por uma caixa de
    entrada que possa realmente consultar.

    - Os erros de validação devolvem HTTP `400` com um de dois formatos:
    `{"field": ["message", ...]}` para problemas a nível de campo, ou
    `{"detail": "message"}` para erros de regras de negócio. Alguns validadores
    (força da palavra-passe no registo, expiração do código na verificação de
    e-mail) respondem atualmente com um array simples `["message"]` em vez do
    formato indexado por campo -- esta é uma inconsistência conhecida do lado do
    servidor, pelo que o código do cliente deve aceitar ambos os formatos.

    - Os erros de autenticação são devolvidos como `{"detail": "..."}` com HTTP
    `401` (token de portador inválido) ou `403` (token de portador em falta /
    permissões insuficientes).

    - As respostas de limite de pedidos incluem um campo `wait` com o tempo de
    espera em segundos.
servers:
  - url: https://apx.didit.me/auth/v2
    description: Servidor de autenticação de produção
security: []
tags:
  - name: Programmatic Auth
    description: >-
      Ciclo de vida de conta com e-mail e palavra-passe: registar, verificar,
      iniciar sessão. Devolve o `access_token` JWT que utiliza nos endpoints de
      Gestão de Contas, além de (na verificação) o `client_id` e a `api_key` da
      sua primeira aplicação.
  - name: Account Management
    description: >-
      Endpoints autenticados (JWT bearer) que listam organizações e criam, obtêm
      ou atualizam aplicações. Utilize-os para recuperar ou rodar a `api_key`
      com a qual autentica as chamadas à API de verificação.
paths:
  /programmatic/register/:
    post:
      tags:
        - Programmatic Auth
      summary: Registar conta
      description: >-
        Passo 1 do onboarding programático. Cria uma conta pendente e envia um
        código de 6 carateres por e-mail (TTL de 10 min). O endereço é
        verificado antes de qualquer conta ser criada: um endereço que não possa
        receber o código devolve 400 `email_undeliverable`. Limites de pedidos:
        5/IP/hora, mais um orçamento horário partilhado por rede (/24 para IPv4,
        /64 para IPv6).
      operationId: programmatic_register
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterRequest'
            examples:
              Gmail:
                summary: Registar com um Gmail pessoal
                value:
                  email: you@yourdomain.com
                  password: MyStr0ng!Pass
              Work:
                summary: Registar com um e-mail profissional
                value:
                  email: you@yourcompany.com
                  password: C0mplex#Pass1
      responses:
        '201':
          description: >-
            Registo bem-sucedido. Um código de verificação alfanumérico de 6
            carateres (ex.: `A3K9F2`) foi enviado por e-mail para o endereço
            fornecido e é válido por 10 minutos. Chame `POST
            /programmatic/verify-email/` a seguir.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterResponse'
              examples:
                Success:
                  value:
                    message: >-
                      Registration successful. Check your email for the
                      verification code.
                    email: you@yourdomain.com
        '400':
          description: >-
            Erro de validação. O envelope previsto é `{"field": ["..."]}` para
            erros ao nível do campo e `{"detail": "..."}` para erros de regras
            de negócio (por exemplo, e-mail duplicado). As regras de força da
            palavra-passe respondem atualmente com um array simples `["..."]`,
            uma regra de cada vez -- inconsistência conhecida do lado do
            servidor; trate-o como `{"password": ["..."]}` até ser corrigido.
            Quando o endereço não consegue receber o código (domínio
            descartável, reservado ou de teste, sem servidor de correio, um
            provável erro de digitação ou um endereço anteriormente rejeitado),
            o corpo é `EmailUndeliverableError` com `code:
            "email_undeliverable"`; nenhuma conta é criada ou alterada.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/EmailUndeliverableError'
              examples:
                MissingFields:
                  summary: Corpo vazio
                  value:
                    email:
                      - This field is required.
                    password:
                      - This field is required.
                InvalidEmail:
                  summary: E-mail mal formatado
                  value:
                    email:
                      - Enter a valid email address.
                PasswordTooShort:
                  summary: Palavra-passe com menos de 8 carateres
                  value:
                    password:
                      - Ensure this field has at least 8 characters.
                PasswordMissingUppercase:
                  summary: Palavra-passe sem letras maiúsculas
                  value:
                    - Password must contain at least one uppercase letter.
                PasswordMissingLowercase:
                  summary: Palavra-passe sem letras minúsculas
                  value:
                    - Password must contain at least one lowercase letter.
                PasswordMissingDigit:
                  summary: Palavra-passe sem dígitos
                  value:
                    - Password must contain at least one digit.
                PasswordMissingSpecial:
                  summary: Palavra-passe sem carateres especiais
                  value:
                    - >-
                      Password must contain at least one special character
                      (!@#$%^&*()_+-=[]{}|;:,.<>?).
                Duplicate:
                  summary: O e-mail já tem uma conta associada
                  value:
                    detail: An account with this email already exists.
                EmailUndeliverable:
                  summary: >-
                    O endereço não consegue receber e-mails (domínio
                    descartável)
                  value:
                    detail: >-
                      This email can't receive messages. Please use a different
                      email address.
                    code: email_undeliverable
                    reason: disposable_domain
                EmailLikelyTypo:
                  summary: Provável erro de digitação no domínio
                  value:
                    detail: >-
                      This email can't receive messages. Please use a different
                      email address.
                    code: email_undeliverable
                    reason: possible_typo
                    suggestion: gmail.com
        '429':
          description: >-
            Limite de pedidos atingido. Mais de 5 tentativas de registo a partir
            do mesmo IP na última hora, ou o orçamento horário para a rede do
            chamador (/24 para IPv4, /64 para IPv6, partilhado pelo registo e
            reenvios de código) esgotou-se. Ambos incluem `Retry-After: 3600`.
            Também retornado, com um cabeçalho `Retry-After: 5`, quando o
            serviço está momentaneamente a verificar o número máximo possível de
            palavras-passe ou códigos em simultâneo; tente novamente após o
            número indicado de segundos.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              examples:
                RateLimited:
                  value:
                    detail: Too many registration attempts. Please try again later.
                PasswordChecksBusy:
                  summary: Demasiadas verificações de palavra-passe em curso
                  value:
                    detail: >-
                      Too many sign-in attempts are being processed right now.
                      Please try again in a few seconds.
      security:
        - {}
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
              -H "Content-Type: application/json" \
              -d '{
                "email": "you@yourdomain.com",
                "password": "MyStr0ng!Pass"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # This call needs no API key.
            client = Didit()

            result = client.account.register(
                email="you@yourdomain.com",
                password="MyStr0ng!Pass",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // This call needs no API key.
            const didit = new Didit();

            const result = await didit.account.register({
              email: "you@yourdomain.com",
              password: "MyStr0ng!Pass",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.Register(ctx, didit.RegisterRequest{\n\tEmail:    \"you@yourdomain.com\",\n\tPassword: \"MyStr0ng!Pass\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: |-
            import me.didit.Didit;
            import me.didit.types.RegisterRequest;

            // This call needs no API key.
            Didit client = new Didit();

            var result = client.account().register(RegisterRequest.builder()
                    .email("you@yourdomain.com")
                    .password("MyStr0ng!Pass")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // This call needs no API key.
            $didit = new DiditClient();

            $result = $didit->account->register([
                'email' => 'you@yourdomain.com',
                'password' => 'MyStr0ng!Pass',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # This call needs no API key.
            didit = Didit::Client.new

            result = didit.account.register(
              email: "you@yourdomain.com",
              password: "MyStr0ng!Pass"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: |-
            using System;
            using System.Text.Json;
            using Didit;

            // This call needs no API key.
            using var client = new DiditClient();

            var result = await client.Account.RegisterAsync(new RegisterRequest
            {
                Email = "you@yourdomain.com",
                Password = "MyStr0ng!Pass",
            });
            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    RegisterRequest:
      type: object
      required:
        - email
        - password
      properties:
        email:
          type: string
          format: email
          description: >-
            Qualquer endereço de e-mail válido (pessoal, profissional, alias).
            Usado como o identificador único da conta.
          example: you@yourdomain.com
        password:
          type: string
          minLength: 8
          description: >-
            Mínimo de 8 carateres. Deve conter pelo menos uma letra maiúscula
            (`A-Z`), uma letra minúscula (`a-z`), um dígito (`0-9`) e um caráter
            especial de `!@#$%^&*()_+-=[]{}|;:,.<>?`. A validação indica uma
            regra que falhou de cada vez.
          example: MyStr0ng!Pass
    RegisterResponse:
      type: object
      properties:
        message:
          type: string
          description: Confirmação legível de que o código de verificação foi enviado.
          example: Registration successful. Check your email for the verification code.
        email:
          type: string
          format: email
          description: O e-mail para o qual o código de verificação foi enviado.
          example: you@yourdomain.com
    ValidationError:
      description: >-
        Corpo do erro de validação. O envelope pretendido é um mapa `{field:
        ["message", ...]}` para erros ao nível do campo ou um envelope de chave
        única `{detail: "..."}` para erros de regras de negócio. Um pequeno
        número de validadores (força da palavra-passe no registo, validade do
        código no verify-email) responde atualmente com um array simples
        `["message"]` -- inconsistência conhecida do lado do servidor. O esquema
        abaixo mantém essa ramificação de array simples para que o código de
        cliente gerado a partir desta especificação desserialize as respostas
        atuais, mas o novo código de cliente deve tratá-lo sob a forma relevante
        indexada por campo (`{password: [...]}` ou `{code: [...]}`) e o contrato
        do servidor convergirá para essa estrutura.
      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.
    EmailUndeliverableError:
      type: object
      description: >-
        Retornado por `POST /programmatic/register/` quando o endereço não
        consegue receber o código de verificação. A verificação é executada
        antes de qualquer conta ser criada ou alterada, pelo que nada fica para
        trás.
      required:
        - detail
        - code
        - reason
      properties:
        detail:
          type: string
          description: Mensagem legível.
          example: >-
            This email can't receive messages. Please use a different email
            address.
        code:
          type: string
          enum:
            - email_undeliverable
          description: Sempre `email_undeliverable`.
        reason:
          type: string
          enum:
            - invalid_address
            - reserved_domain
            - no_mail_records
            - disposable_domain
            - possible_typo
            - suppressed
          description: >-
            O motivo pelo qual o endereço foi recusado: `invalid_address` (não é
            um endereço válido), `reserved_domain` (um domínio reservado ou de
            teste, como `example.com`), `no_mail_records` (o domínio não tem
            servidor de correio), `disposable_domain` (um fornecedor de caixas
            de correio descartáveis), `possible_typo` (um provável erro de
            digitação de um fornecedor comum; consulte `suggestion`),
            `suppressed` (o endereço foi rejeitado anteriormente ou gerou uma
            reclamação).
        suggestion:
          type: string
          description: >-
            O domínio pretendido provável, presente apenas quando o domínio
            parece conter um erro de digitação (por exemplo, `gmail.com` em vez
            de `gmial.com`). A API não aceita uma confirmação: registe-se
            novamente com o endereço corrigido.
          example: gmail.com
    RateLimitError:
      type: object
      description: >-
        Resposta de limite de pedidos ou bloqueio progressivo. `wait` é o tempo
        de espera em segundos.
      properties:
        detail:
          type: string
          example: >-
            Too many login attempts from this IP address. Please wait before
            trying again.

````

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