{
  "openapi": "3.0.0",
  "paths": {
    "/v1/customers": {
      "post": {
        "operationId": "ApiV1CustomersController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`duplicate_customer`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "duplicate_customer": {
                    "summary": "duplicate_customer",
                    "value": {
                      "error": {
                        "code": "duplicate_customer",
                        "message": "Já existe um customer com esse <campo> para este parceiro"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Cria um customer do parceiro.",
        "tags": [
          "customers"
        ]
      },
      "get": {
        "operationId": "ApiV1CustomersController_list",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "number"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "Cursor opaco devolvido em nextCursor.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "externalId",
            "required": false,
            "in": "query",
            "description": "Filtro exato por externalId.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kycStatus",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "NOT_SUBMITTED",
                "PENDING",
                "APPROVED",
                "REJECTED"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página de customers do parceiro.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CustomerResponseDto"
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "hasMore",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` · `invalid_cursor`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  },
                  "invalid_cursor": {
                    "summary": "invalid_cursor",
                    "value": {
                      "error": {
                        "code": "invalid_cursor",
                        "message": "cursor inválido"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Lista customers (paginação cursor-based).",
        "tags": [
          "customers"
        ]
      }
    },
    "/v1/customers/{idOrExternalId}": {
      "get": {
        "operationId": "ApiV1CustomersController_getOne",
        "parameters": [
          {
            "name": "idOrExternalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponseDto"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`customer_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "customer_not_found": {
                    "summary": "customer_not_found",
                    "value": {
                      "error": {
                        "code": "customer_not_found",
                        "message": "Customer não encontrado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Detalhe por id (cuid) ou externalId.",
        "tags": [
          "customers"
        ]
      },
      "patch": {
        "operationId": "ApiV1CustomersController_update",
        "parameters": [
          {
            "name": "idOrExternalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` · `immutable_field` · `kyc_locked`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  },
                  "immutable_field": {
                    "summary": "immutable_field",
                    "value": {
                      "error": {
                        "code": "immutable_field",
                        "message": "cpfCnpj é imutável e não pode ser alterado"
                      }
                    }
                  },
                  "kyc_locked": {
                    "summary": "kyc_locked",
                    "value": {
                      "error": {
                        "code": "kyc_locked",
                        "message": "name e address não podem ser alterados após o KYC aprovado"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`customer_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "customer_not_found": {
                    "summary": "customer_not_found",
                    "value": {
                      "error": {
                        "code": "customer_not_found",
                        "message": "Customer não encontrado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Atualiza campos não-críticos. cpfCnpj é imutável; name/address travam após KYC aprovado.",
        "tags": [
          "customers"
        ]
      }
    },
    "/v1/customers/{idOrExternalId}/kyc/session": {
      "post": {
        "description": "Devolve a `url` da página de verificação: o cliente fotografa o documento (CNH, RG ou passaporte) e faz a selfie ali, sem a marca da Numio. Ao terminar, volta para o `returnUrl` informado. O resultado chega pelos webhooks `customer.kyc.submitted` e, em seguida, `customer.kyc.approved` ou `customer.kyc.rejected` (com o motivo em `rejectionReason`); casos que precisam de revisão ficam em `PENDING` até a decisão da equipe. Chamar de novo com a sessão ainda aberta devolve a mesma sessão. Pode ser chamado de novo depois de um `REJECTED`.",
        "operationId": "ApiV1CustomersController_startKycSession",
        "parameters": [
          {
            "name": "idOrExternalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartKycSessionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KycSessionResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` · `birth_date_required` · `holder_underage`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  },
                  "birth_date_required": {
                    "summary": "birth_date_required",
                    "value": {
                      "error": {
                        "code": "birth_date_required",
                        "message": "birthDate é obrigatório para customer com CPF"
                      }
                    }
                  },
                  "holder_underage": {
                    "summary": "holder_underage",
                    "value": {
                      "error": {
                        "code": "holder_underage",
                        "message": "O titular precisa ter 18 anos ou mais"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`customer_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "customer_not_found": {
                    "summary": "customer_not_found",
                    "value": {
                      "error": {
                        "code": "customer_not_found",
                        "message": "Customer não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`kyc_already_submitted`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "kyc_already_submitted": {
                    "summary": "kyc_already_submitted",
                    "value": {
                      "error": {
                        "code": "kyc_already_submitted",
                        "message": "KYC já está em PENDING — aguarde a decisão"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "`kyc_verification_unavailable`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "kyc_verification_unavailable": {
                    "summary": "kyc_verification_unavailable",
                    "value": {
                      "error": {
                        "code": "kyc_verification_unavailable",
                        "message": "O serviço de verificação de identidade está indisponível agora. Tente em instantes."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Abre a verificação de identidade do cliente final.",
        "tags": [
          "customers"
        ]
      }
    },
    "/v1/customers/{idOrExternalId}/kyc": {
      "post": {
        "description": "Alternativa à verificação hospedada (`POST .../kyc/session`), que é o caminho recomendado. Aqui as fotos passam por análise manual da equipe. Valida magic bytes (jpeg/png/webp, máx 10MB). 202 quando aceito.",
        "operationId": "ApiV1CustomersController_uploadKyc",
        "parameters": [
          {
            "name": "idOrExternalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "multipart/form-data com os 3 arquivos (jpeg/png/webp, máx 10MB cada).",
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "selfie",
                  "documentFront",
                  "documentBack"
                ],
                "properties": {
                  "selfie": {
                    "type": "string",
                    "format": "binary"
                  },
                  "documentFront": {
                    "type": "string",
                    "format": "binary"
                  },
                  "documentBack": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "KYC recebido; entra em análise (kycStatus PENDING).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/CustomerResponseDto"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "example": "PENDING"
                        },
                        "submittedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`invalid_file`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "invalid_file": {
                    "summary": "invalid_file",
                    "value": {
                      "error": {
                        "code": "invalid_file",
                        "message": "Arquivo obrigatório ausente: <campo> | Arquivo inválido (<campo>)"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`customer_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "customer_not_found": {
                    "summary": "customer_not_found",
                    "value": {
                      "error": {
                        "code": "customer_not_found",
                        "message": "Customer não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`kyc_already_submitted`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "kyc_already_submitted": {
                    "summary": "kyc_already_submitted",
                    "value": {
                      "error": {
                        "code": "kyc_already_submitted",
                        "message": "KYC já está em <status> — não pode reenviar"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Envio manual do KYC: selfie + documentFront + documentBack (multipart).",
        "tags": [
          "customers"
        ]
      },
      "get": {
        "operationId": "ApiV1CustomersController_getKyc",
        "parameters": [
          {
            "name": "idOrExternalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "status": "APPROVED",
                    "submittedAt": "2026-06-18T10:00:00.000Z",
                    "reviewedAt": "2026-06-18T14:00:00.000Z",
                    "rejectionReason": null,
                    "session": {
                      "sessionId": "11111111-2222-3333-4444-555555555555",
                      "url": null,
                      "status": "Approved"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`customer_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "customer_not_found": {
                    "summary": "customer_not_found",
                    "value": {
                      "error": {
                        "code": "customer_not_found",
                        "message": "Customer não encontrado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Status do KYC do customer.",
        "tags": [
          "customers"
        ]
      }
    },
    "/v1/dids/available": {
      "get": {
        "description": "Catálogo de números livres para contratação. Pagine com `cursor` (opaco) até `hasMore=false`. Filtre por DDD com `?ddd=47`.",
        "operationId": "ApiV1DidsController_listAvailable",
        "parameters": [
          {
            "name": "ddd",
            "required": true,
            "in": "query",
            "description": "DDD (2 dígitos). Obrigatório.",
            "schema": {
              "example": "47",
              "type": "string"
            }
          },
          {
            "name": "city",
            "required": false,
            "in": "query",
            "description": "Filtra por cidade (nome do município, correspondência exata).",
            "schema": {
              "example": "Blumenau",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "number"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "Cursor opaco devolvido em nextCursor.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página do catálogo de DIDs disponíveis.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AvailableDidDto"
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "hasMore",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Lista DIDs disponíveis no catálogo (cursor, ?ddd=).",
        "tags": [
          "dids"
        ]
      }
    },
    "/v1/dids": {
      "post": {
        "description": "Reserva o número e inicia o provisionamento (assíncrono). O DID nasce `PURCHASED` e segue para `configuring` → `READY` (acompanhe por `GET /v1/dids/:didId` ou pelos webhooks `did.*`). O header opcional `Idempotency-Key` torna o retry seguro: replay com o MESMO corpo devolve a mesma resposta; corpo diferente na mesma key → 409 `idempotency_conflict`.",
        "operationId": "ApiV1DidsController_purchase",
        "parameters": [
          {
            "name": "idempotency-key",
            "required": false,
            "in": "header",
            "description": "Chave de idempotência (qualquer string única por operação, ex.: UUID). Replay com o mesmo corpo devolve a resposta cacheada por 24h.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PurchaseDidDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "DID contratado; provisionamento iniciado (status PURCHASED).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DidResponseDto"
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`kyc_not_approved`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "kyc_not_approved": {
                    "summary": "kyc_not_approved",
                    "value": {
                      "error": {
                        "code": "kyc_not_approved",
                        "message": "O KYC do customer precisa estar APPROVED para contratar DIDs"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`customer_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "customer_not_found": {
                    "summary": "customer_not_found",
                    "value": {
                      "error": {
                        "code": "customer_not_found",
                        "message": "Customer não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`did_unavailable` · `idempotency_conflict`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_unavailable": {
                    "summary": "did_unavailable",
                    "value": {
                      "error": {
                        "code": "did_unavailable",
                        "message": "Número indisponível ou inexistente no catálogo"
                      }
                    }
                  },
                  "idempotency_conflict": {
                    "summary": "idempotency_conflict",
                    "value": {
                      "error": {
                        "code": "idempotency_conflict",
                        "message": "Idempotency-Key já usada com um payload diferente neste parceiro"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Contrata um DID para um customer (KYC APPROVED).",
        "tags": [
          "dids"
        ]
      },
      "get": {
        "description": "Números do parceiro. Filtre por customer (`id` ou `externalId`) e/ou `status`. Pagine com `cursor` até `hasMore=false`.",
        "operationId": "ApiV1DidsController_list",
        "parameters": [
          {
            "name": "customerIdOrExternalId",
            "required": false,
            "in": "query",
            "description": "Filtra pelos DIDs de um customer (id ou externalId).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "RESERVED",
                "PURCHASED",
                "CONFIGURING",
                "PARTIALLY_ACTIVE",
                "ACTIVE",
                "READY",
                "WHATSAPP_FORWARD_ACTIVE",
                "SUSPENDED",
                "CANCELED",
                "RELEASED",
                "FAILED"
              ]
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "type": "number"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página de DIDs do parceiro.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DidResponseDto"
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "data",
                    "hasMore",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Lista DIDs do parceiro (cursor; ?customerIdOrExternalId, ?status).",
        "tags": [
          "dids"
        ]
      }
    },
    "/v1/dids/{didId}": {
      "get": {
        "operationId": "ApiV1DidsController_getOne",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DidResponseDto"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Detalhe de um DID do parceiro.",
        "tags": [
          "dids"
        ]
      },
      "delete": {
        "description": "Aceita o cancelamento (202) e desprovisiona de forma assíncrona. O DID vai para `CANCELED`. Irreversível.",
        "operationId": "ApiV1DidsController_cancel",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Cancelamento aceito; desprovisionamento assíncrono.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "id": "did_clx123",
                    "status": "CANCELED",
                    "canceledAt": "2026-06-19T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`already_canceled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "already_canceled": {
                    "summary": "already_canceled",
                    "value": {
                      "error": {
                        "code": "already_canceled",
                        "message": "Número já está cancelado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Cancela o DID (desprovisiona e libera o número). Irreversível.",
        "tags": [
          "dids"
        ]
      }
    },
    "/v1/dids/{didId}/sip": {
      "post": {
        "description": "O DID precisa estar `READY`. **TRUNK**: troca o subscriber por um gateway apontando pro PABX do cliente (`host`+`port`). **USER_PASSWORD**: reusa o subscriber já provisionado — pegue a senha em `GET /sip/password` (entrega única). O corpo da resposta varia conforme o modo.",
        "operationId": "ApiV1SipController_configure",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfigureSipDto"
              },
              "examples": {
                "TRUNK": {
                  "summary": "TRUNK — gateway pro PABX do cliente",
                  "value": {
                    "mode": "TRUNK",
                    "host": "200.1.2.3",
                    "port": 5060
                  }
                },
                "USER_PASSWORD": {
                  "summary": "USER_PASSWORD — softphone (senha via GET /sip/password)",
                  "value": {
                    "mode": "USER_PASSWORD"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SIP configurado. O shape varia conforme o modo.",
            "content": {
              "application/json": {
                "examples": {
                  "TRUNK": {
                    "value": {
                      "mode": "TRUNK",
                      "host": "200.1.2.3",
                      "port": 5060,
                      "configuredAt": "2026-06-19T12:00:00.000Z"
                    }
                  },
                  "USER_PASSWORD": {
                    "value": {
                      "mode": "USER_PASSWORD",
                      "sipServer": "203.0.113.10",
                      "sipPort": 5060,
                      "username": "4730000000",
                      "configuredAt": "2026-06-19T12:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` · `invalid_sip_ip`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  },
                  "invalid_sip_ip": {
                    "summary": "invalid_sip_ip",
                    "value": {
                      "error": {
                        "code": "invalid_sip_ip",
                        "message": "IP <host> não permitido (loopback, anycast ou reservado) ou inválido"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`whatsapp_forward_active` · `did_not_ready` · `sip_already_configured`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "whatsapp_forward_active": {
                    "summary": "whatsapp_forward_active",
                    "value": {
                      "error": {
                        "code": "whatsapp_forward_active",
                        "message": "Desative o WhatsApp Forward antes de configurar SIP"
                      }
                    }
                  },
                  "did_not_ready": {
                    "summary": "did_not_ready",
                    "value": {
                      "error": {
                        "code": "did_not_ready",
                        "message": "DID em status <X> não pode configurar SIP"
                      }
                    }
                  },
                  "sip_already_configured": {
                    "summary": "sip_already_configured",
                    "value": {
                      "error": {
                        "code": "sip_already_configured",
                        "message": "SIP já configurado — remova antes de reconfigurar"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Configura SIP: TRUNK (host+port do PABX) ou USER_PASSWORD.",
        "tags": [
          "sip"
        ]
      },
      "get": {
        "operationId": "ApiV1SipController_getConfig",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração atual. O shape varia conforme o modo.",
            "content": {
              "application/json": {
                "examples": {
                  "TRUNK": {
                    "value": {
                      "mode": "TRUNK",
                      "host": "200.1.2.3",
                      "port": 5060
                    }
                  },
                  "USER_PASSWORD": {
                    "value": {
                      "mode": "USER_PASSWORD",
                      "sipServer": "203.0.113.10",
                      "sipPort": 5060,
                      "username": "4730000000"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found` · `sip_not_configured`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  },
                  "sip_not_configured": {
                    "summary": "sip_not_configured",
                    "value": {
                      "error": {
                        "code": "sip_not_configured",
                        "message": "SIP não configurado para este número"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Configuração SIP atual (nunca retorna a senha).",
        "tags": [
          "sip"
        ]
      },
      "delete": {
        "operationId": "ApiV1SipController_deconfigure",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "SIP removido; número volta a READY.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "didId": "did_clx123",
                    "status": "READY"
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`sip_not_configured`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "sip_not_configured": {
                    "summary": "sip_not_configured",
                    "value": {
                      "error": {
                        "code": "sip_not_configured",
                        "message": "SIP não configurado para este número"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Remove a configuração SIP — número volta pra READY.",
        "tags": [
          "sip"
        ]
      }
    },
    "/v1/dids/{didId}/sip/password": {
      "get": {
        "description": "Só funciona no modo `USER_PASSWORD` e UMA vez: a 2ª chamada → 409 `password_already_delivered`. Para uma nova senha use `POST /sip/regenerate-password`.",
        "operationId": "ApiV1SipController_getPassword",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Credenciais SIP (entrega única).",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "username": "4730000000",
                    "password": "a1B2c3D4e5F6g7H8"
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found` · `sip_not_configured`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  },
                  "sip_not_configured": {
                    "summary": "sip_not_configured",
                    "value": {
                      "error": {
                        "code": "sip_not_configured",
                        "message": "Sem credenciais para este número"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`invalid_sip_mode` · `password_already_delivered`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "invalid_sip_mode": {
                    "summary": "invalid_sip_mode",
                    "value": {
                      "error": {
                        "code": "invalid_sip_mode",
                        "message": "Senha só existe no modo USER_PASSWORD"
                      }
                    }
                  },
                  "password_already_delivered": {
                    "summary": "password_already_delivered",
                    "value": {
                      "error": {
                        "code": "password_already_delivered",
                        "message": "A senha já foi entregue uma vez. Use regenerate-password para uma nova."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Senha SIP (USER_PASSWORD) — entregue UMA única vez (reveal-once).",
        "tags": [
          "sip"
        ]
      }
    },
    "/v1/dids/{didId}/sip/regenerate-password": {
      "post": {
        "operationId": "ApiV1SipController_regenerate",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Nova senha (entrega única nesta resposta).",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "mode": "USER_PASSWORD",
                    "username": "4730000000",
                    "password": "z9Y8x7W6v5U4t3S2",
                    "regeneratedAt": "2026-06-19T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`invalid_sip_mode` · `did_not_ready`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "invalid_sip_mode": {
                    "summary": "invalid_sip_mode",
                    "value": {
                      "error": {
                        "code": "invalid_sip_mode",
                        "message": "regenerate-password só vale no modo USER_PASSWORD"
                      }
                    }
                  },
                  "did_not_ready": {
                    "summary": "did_not_ready",
                    "value": {
                      "error": {
                        "code": "did_not_ready",
                        "message": "Número ainda não provisionado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Gera nova senha (USER_PASSWORD) — retorna UMA vez na resposta.",
        "tags": [
          "sip"
        ]
      }
    },
    "/v1/dids/{didId}/whatsapp-forward": {
      "post": {
        "description": "O DID precisa estar `READY`. Redireciona as ligações do número para o `destinationPhone` por 10 minutos (expira sozinho → webhook `whatsapp_forward.expired`). Alternativa ao recebimento do código pela Numio (`/whatsapp-verification`): aqui o cliente final atende a ligação da Meta no celular e ouve o código. Limite de 3 ativações/dia por número. O destino vai SEMPRE mascarado na resposta e nos webhooks.",
        "operationId": "ApiV1WhatsappForwardController_activate",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivateForwardDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Redirecionamento ativado (destino mascarado).",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "id": "wf_clx123",
                    "didId": "did_clx123",
                    "destinationPhone": "5519*****2655",
                    "status": "ACTIVE",
                    "activatedAt": "2026-06-19T12:00:00.000Z",
                    "expiresAt": "2026-06-19T12:10:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`WHATSAPP_FORWARD_ALREADY_ACTIVE` · `WHATSAPP_FORWARD_NOT_AVAILABLE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "WHATSAPP_FORWARD_ALREADY_ACTIVE": {
                    "summary": "WHATSAPP_FORWARD_ALREADY_ACTIVE",
                    "value": {
                      "error": {
                        "code": "WHATSAPP_FORWARD_ALREADY_ACTIVE",
                        "message": "Já existe um redirecionamento ativo para este número. Aguarde expirar ou desative antes de ativar de novo."
                      }
                    }
                  },
                  "WHATSAPP_FORWARD_NOT_AVAILABLE": {
                    "summary": "WHATSAPP_FORWARD_NOT_AVAILABLE",
                    "value": {
                      "error": {
                        "code": "WHATSAPP_FORWARD_NOT_AVAILABLE",
                        "message": "Este número ainda não está pronto para receber a verificação do WhatsApp Business."
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "`WHATSAPP_FORWARD_LIMIT_REACHED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "WHATSAPP_FORWARD_LIMIT_REACHED": {
                    "summary": "WHATSAPP_FORWARD_LIMIT_REACHED",
                    "value": {
                      "error": {
                        "code": "WHATSAPP_FORWARD_LIMIT_REACHED",
                        "message": "Limite de 3 ativações por dia atingido para este número. Tente novamente amanhã.",
                        "details": {
                          "dailyUsed": 3,
                          "dailyLimit": 3
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Ativa o Siga-me (10 min) pro número de destino informado.",
        "tags": [
          "whatsapp-forward"
        ]
      },
      "delete": {
        "operationId": "ApiV1WhatsappForwardController_deactivate",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Redirecionamento desativado.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "didId": "did_clx123",
                    "status": "DEACTIVATED",
                    "deactivatedAt": "2026-06-19T12:05:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`WHATSAPP_FORWARD_NOT_ACTIVE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "WHATSAPP_FORWARD_NOT_ACTIVE": {
                    "summary": "WHATSAPP_FORWARD_NOT_ACTIVE",
                    "value": {
                      "error": {
                        "code": "WHATSAPP_FORWARD_NOT_ACTIVE",
                        "message": "Não há redirecionamento ativo para este número."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Desativa o Siga-me manualmente.",
        "tags": [
          "whatsapp-forward"
        ]
      }
    },
    "/v1/dids/{didId}/whatsapp-forward/status": {
      "get": {
        "operationId": "ApiV1WhatsappForwardController_status",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status atual e ativações restantes no dia.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "status": "ACTIVE",
                    "current": {
                      "id": "wf_clx123",
                      "expiresAt": "2026-06-19T12:10:00.000Z",
                      "destinationPhone": "5519*****2655"
                    },
                    "remainingActivationsToday": 2
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Status do Siga-me + ativações restantes hoje (0–3).",
        "tags": [
          "whatsapp-forward"
        ]
      }
    },
    "/v1/dids/{didId}/whatsapp-verification": {
      "get": {
        "description": "`state`: `IDLE` (nada armado), `ARMED` (esperando a ligação da Meta), `CALL_IN_PROGRESS` (a Meta está na linha), `PROCESSING` (extraindo o código), `CODE_READY` (`code` preenchido — mostre ao cliente) ou `NO_CODE` (a ligação chegou mas o código não foi reconhecido; ouça o áudio em `/recording` ou peça outra ligação). `missedCallAt` indica uma ligação que chegou com o recebimento desarmado.",
        "operationId": "ApiV1WhatsappVerificationController_status",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "didId": "did_clx123",
                    "number": "1931234567",
                    "state": "CODE_READY",
                    "code": "482913",
                    "sessionId": "vcs_clx123",
                    "armedUntil": "2026-06-20T12:00:00.000Z",
                    "callReceivedAt": "2026-06-19T12:01:10.000Z",
                    "missedCallAt": null,
                    "hasRecording": true,
                    "outage": false,
                    "blocked": false,
                    "available": true
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Estado da ativação no WhatsApp e o código, quando pronto.",
        "tags": [
          "whatsapp-verification"
        ]
      },
      "post": {
        "description": "O número precisa estar `READY` e o KYC do customer `APPROVED`. Depois de armar, o cliente pede o código no WhatsApp escolhendo \"Ligue para mim\". A Numio atende a ligação, extrai os 6 dígitos e entrega pelo webhook `whatsapp_verification.code_ready` (e por este recurso, em `GET`). O recebimento fica armado por até 24 h.",
        "operationId": "ApiV1WhatsappVerificationController_arm",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArmWhatsappVerificationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "didId": "did_clx123",
                    "number": "1931234567",
                    "state": "ARMED",
                    "code": null,
                    "sessionId": "vcs_clx123",
                    "armedUntil": "2026-06-20T12:00:00.000Z",
                    "callReceivedAt": "2026-06-19T12:01:10.000Z",
                    "missedCallAt": null,
                    "hasRecording": true,
                    "outage": false,
                    "blocked": false,
                    "available": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`VERIFICATION_CALL_NOT_AVAILABLE` · `VERIFICATION_CALL_ALREADY_ACTIVE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VERIFICATION_CALL_NOT_AVAILABLE": {
                    "summary": "VERIFICATION_CALL_NOT_AVAILABLE",
                    "value": {
                      "error": {
                        "code": "VERIFICATION_CALL_NOT_AVAILABLE",
                        "message": "Este número ainda não está pronto para a verificação, ou há outro fluxo ativo."
                      }
                    }
                  },
                  "VERIFICATION_CALL_ALREADY_ACTIVE": {
                    "summary": "VERIFICATION_CALL_ALREADY_ACTIVE",
                    "value": {
                      "error": {
                        "code": "VERIFICATION_CALL_ALREADY_ACTIVE",
                        "message": "Já existe uma verificação em andamento para este número."
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "`VERIFICATION_CALL_LIMIT_REACHED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VERIFICATION_CALL_LIMIT_REACHED": {
                    "summary": "VERIFICATION_CALL_LIMIT_REACHED",
                    "value": {
                      "error": {
                        "code": "VERIFICATION_CALL_LIMIT_REACHED",
                        "message": "Limite de 10 verificações por dia atingido para este número. Tente novamente amanhã."
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "`VERIFICATION_CALL_OUTAGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VERIFICATION_CALL_OUTAGE": {
                    "summary": "VERIFICATION_CALL_OUTAGE",
                    "value": {
                      "error": {
                        "code": "VERIFICATION_CALL_OUTAGE",
                        "message": "As ligações de verificação estão temporariamente fora do ar por uma instabilidade na operadora."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Arma o recebimento da ligação de verificação do WhatsApp.",
        "tags": [
          "whatsapp-verification"
        ]
      },
      "delete": {
        "description": "Recusado com a Meta na linha (409 `VERIFICATION_CALL_IN_PROGRESS`): desarmar agora perderia o código.",
        "operationId": "ApiV1WhatsappVerificationController_cancel",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "didId": "did_clx123",
                    "number": "1931234567",
                    "state": "IDLE",
                    "code": null,
                    "sessionId": "vcs_clx123",
                    "armedUntil": "2026-06-20T12:00:00.000Z",
                    "callReceivedAt": "2026-06-19T12:01:10.000Z",
                    "missedCallAt": null,
                    "hasRecording": true,
                    "outage": false,
                    "blocked": false,
                    "available": true
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`VERIFICATION_CALL_IN_PROGRESS`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VERIFICATION_CALL_IN_PROGRESS": {
                    "summary": "VERIFICATION_CALL_IN_PROGRESS",
                    "value": {
                      "error": {
                        "code": "VERIFICATION_CALL_IN_PROGRESS",
                        "message": "A ligação da Meta está em andamento neste número."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Desarma o recebimento sem concluir.",
        "tags": [
          "whatsapp-verification"
        ]
      }
    },
    "/v1/dids/{didId}/whatsapp-verification/complete": {
      "post": {
        "operationId": "ApiV1WhatsappVerificationController_complete",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "didId": "did_clx123",
                    "number": "1931234567",
                    "state": "IDLE",
                    "code": null,
                    "sessionId": "vcs_clx123",
                    "armedUntil": "2026-06-20T12:00:00.000Z",
                    "callReceivedAt": "2026-06-19T12:01:10.000Z",
                    "missedCallAt": null,
                    "hasRecording": true,
                    "outage": false,
                    "blocked": false,
                    "available": true
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`VERIFICATION_CALL_NOT_ACTIVE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VERIFICATION_CALL_NOT_ACTIVE": {
                    "summary": "VERIFICATION_CALL_NOT_ACTIVE",
                    "value": {
                      "error": {
                        "code": "VERIFICATION_CALL_NOT_ACTIVE",
                        "message": "Não há verificação em andamento para este número."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Código usado: encerra e marca o número como verificado.",
        "tags": [
          "whatsapp-verification"
        ]
      }
    },
    "/v1/dids/{didId}/whatsapp-verification/recording": {
      "get": {
        "description": "Para o cliente ouvir os 6 dígitos quando `state` é `NO_CODE`. Disponível enquanto `hasRecording` é true; apagado em até 24 h.",
        "operationId": "ApiV1WhatsappVerificationController_recording",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`did_not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "did_not_found": {
                    "summary": "did_not_found",
                    "value": {
                      "error": {
                        "code": "did_not_found",
                        "message": "Número não encontrado"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Áudio da última ligação de verificação (quando o código não foi reconhecido).",
        "tags": [
          "whatsapp-verification"
        ]
      }
    },
    "/v1/sandbox/dids/{didId}/simulate-verification-call": {
      "post": {
        "description": "Faz de conta que a Meta ligou para o número com o recebimento armado (`POST /v1/dids/:didId/whatsapp-verification`). Com `result` = `CODE` (padrão), o código chega no webhook `whatsapp_verification.code_ready` e no `GET .../whatsapp-verification`. Com `NO_CODE`, o `state` vira `NO_CODE` e há um áudio de teste em `/recording`. Devolve o estado da ativação, no mesmo formato do `GET .../whatsapp-verification`.",
        "operationId": "SandboxController_simulateVerificationCall",
        "parameters": [
          {
            "name": "didId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimulateVerificationCallDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "didId": "did_clx123",
                    "number": "1931101000",
                    "state": "CODE_READY",
                    "code": "123456",
                    "sessionId": "vcs_clx123",
                    "armedUntil": "2026-10-03T12:00:00.000Z",
                    "callReceivedAt": "2026-10-02T12:01:10.000Z",
                    "missedCallAt": null,
                    "hasRecording": true,
                    "outage": false,
                    "blocked": false,
                    "available": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "not_found": {
                    "summary": "not_found",
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Disponível apenas no sandbox (sandbox-api.numio.com.br)"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`verification_not_armed`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "verification_not_armed": {
                    "summary": "verification_not_armed",
                    "value": {
                      "error": {
                        "code": "verification_not_armed",
                        "message": "O recebimento não está armado neste número, ou o código já foi entregue."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Simula a ligação de verificação do WhatsApp (só no sandbox).",
        "tags": [
          "sandbox"
        ]
      }
    },
    "/v1/sandbox/customers/{idOrExternalId}/kyc/decision": {
      "post": {
        "description": "Em produção, o KYC que fica em `PENDING` (CNPJ, dados divergentes, revisão pedida pela verificação ou envio manual de fotos) é decidido pela equipe Numio. No sandbox, você decide por aqui e recebe o mesmo webhook `customer.kyc.approved` ou `customer.kyc.rejected`.",
        "operationId": "SandboxController_decideKyc",
        "parameters": [
          {
            "name": "idOrExternalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxKycDecisionDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "status": "APPROVED"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Validation failed",
                        "details": {
                          "errors": [
                            "<campo>: <regra violada>"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` · `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "missing_api_key": {
                    "summary": "missing_api_key",
                    "value": {
                      "error": {
                        "code": "missing_api_key",
                        "message": "Authorization header com Bearer token é obrigatório"
                      }
                    }
                  },
                  "invalid_api_key": {
                    "summary": "invalid_api_key",
                    "value": {
                      "error": {
                        "code": "invalid_api_key",
                        "message": "API key inválida, revogada ou inativa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`not_found`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "not_found": {
                    "summary": "not_found",
                    "value": {
                      "error": {
                        "code": "not_found",
                        "message": "Disponível apenas no sandbox (sandbox-api.numio.com.br)"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`kyc_not_pending`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorBodyDto"
                },
                "examples": {
                  "kyc_not_pending": {
                    "summary": "kyc_not_pending",
                    "value": {
                      "error": {
                        "code": "kyc_not_pending",
                        "message": "Só dá pra decidir um KYC em PENDING (atual: <status>)"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "partner-api-key": []
          }
        ],
        "summary": "Decide um KYC em revisão manual (só no sandbox).",
        "tags": [
          "sandbox"
        ]
      }
    }
  },
  "info": {
    "title": "Numio API",
    "description": "API da Numio para parceiros (CRMs, ERPs, plataformas omnichannel) contratarem\ne gerenciarem números virtuais (DIDs) em nome dos clientes finais deles.\n\n## Autenticação (parceiro)\n\nTodos os endpoints `/api/v1/*` autenticam por **Bearer token** no header\n`Authorization`. A API key é gerada pelo time Numio e aparece **uma única\nvez** na criação: `numio_live_*` em produção e `numio_test_*` no sandbox.\nCada ambiente recusa a chave do outro.\n\n```\nAuthorization: Bearer numio_live_xxxxxxxxxxxxxxxxxxxx\n```\n\nFalha de auth → **401** `missing_api_key` (header ausente) ou\n`invalid_api_key` (key inválida/revogada/inativa).\n\n## Sandbox\n\nPara desenvolver e testar a integração sem contratar números de verdade:\n\n- **URL:** `https://sandbox-api.numio.com.br/api/v1`, com a chave `numio_test_*`.\n- **Mesma API:** os mesmos endpoints, formatos, erros e webhooks assinados de\n  produção. Para ir ao ar, troque só a URL e a chave.\n- **Nada é real:** o catálogo tem números fictícios em todos os DDDs, a compra\n  não reserva número na operadora, nenhuma ligação acontece e nada é faturado.\n  O número passa por `did.configuring` e `did.ready` em segundos.\n- **Verificação de identidade:** a `url` de `POST .../kyc/session` abre uma\n  página de teste com os botões **Aprovar**, **Recusar** e **Enviar para\n  revisão**, que disparam os mesmos webhooks `customer.kyc.*`. Customer com\n  CNPJ, com dados divergentes ou enviado para revisão fica em `PENDING`; decida\n  com `POST /v1/sandbox/customers/:id/kyc/decision`. O envio manual de fotos\n  (`POST .../kyc`) também cai em `PENDING`.\n- **Código do WhatsApp:** depois de armar o recebimento\n  (`POST /v1/dids/:didId/whatsapp-verification`), chame\n  `POST /v1/sandbox/dids/:didId/simulate-verification-call` para simular a\n  ligação da Meta. O código (`123456` por padrão, ou o que você mandar em\n  `code`) chega no webhook `whatsapp_verification.code_ready`. Com\n  `\"result\": \"NO_CODE\"`, a ligação chega sem código reconhecido.\n- **Siga-me e SIP** funcionam normalmente, com credenciais fictícias.\n\nOs endpoints `/v1/sandbox/*` só existem no sandbox; em produção respondem 404.\n\n## Formato de erro\n\nToda falha (4xx/5xx) tem o mesmo envelope:\n\n```json\n{ \"error\": { \"code\": \"did_not_found\", \"message\": \"Número não encontrado\" } }\n```\n\n- `code` é **estável** (snake_case) — trate erros por ele, não pela\n  `message` (humana, pode mudar).\n- Erros de validação de corpo/query vêm como **400** `VALIDATION_ERROR`\n  com `details.errors: string[]`.\n- Exceção: os endpoints de **WhatsApp Forward** delegam ao serviço B2C\n  compartilhado e usam códigos em **UPPER_SNAKE** (`WHATSAPP_FORWARD_*`).\n\n## Idempotência\n\n`POST /api/v1/dids` aceita o header opcional **`Idempotency-Key`** (qualquer\nstring única por operação, ex.: UUID). O replay com o **mesmo corpo** devolve\na resposta cacheada por 24h; o mesmo key com corpo **diferente** → **409**\n`idempotency_conflict`. Use sempre que fizer retry de contratação.\n\n## Verificação de identidade (KYC)\n\nPor exigência da Anatel, todo número precisa de um titular identificado: o\ncustomer só contrata DID com KYC `APPROVED`. A verificação é hospedada e\nnão mostra a marca Numio.\n\n1. `POST /api/v1/customers/:id/kyc/session` devolve uma `url`. Abra para o\n   cliente final (nova aba, janela ou redirecionamento): ele fotografa o\n   documento (CNH física ou digital, RG ou passaporte) e faz uma selfie.\n   Para customer com CPF, envie `birthDate` (`AAAA-MM-DD`); o titular\n   precisa ter 18 anos ou mais. Com `returnUrl`, o cliente volta para o seu\n   sistema ao terminar.\n2. Quando a verificação termina, o customer vai para `PENDING`\n   (`customer.kyc.submitted`) e, na maioria dos casos, a decisão sai na hora:\n   `customer.kyc.approved` ou `customer.kyc.rejected`, com o motivo em\n   `rejectionReason` para você mostrar ao cliente.\n3. Quando os dados não batem com o documento (nome abreviado, data de\n   nascimento diferente) ou o titular é CNPJ, o customer fica em `PENDING`\n   até a revisão da equipe, e a decisão chega pelo mesmo webhook.\n\nRecusado pode verificar de novo: chame `POST .../kyc/session` outra vez.\nEnquanto a sessão está aberta, a mesma chamada devolve a mesma sessão, e\n`GET /api/v1/customers/:id/kyc` traz a `url` para o cliente continuar de\nonde parou. O envio das fotos por `POST /api/v1/customers/:id/kyc`\n(multipart) continua disponível como alternativa, com análise manual.\n\n## Ativar o número no WhatsApp (código de verificação)\n\nO número é fixo e **não recebe SMS**: o WhatsApp entrega o código de 6 dígitos\npor **ligação de voz**. A Numio atende essa ligação, extrai o código e entrega\npara você mostrar na sua plataforma. O cliente final não atende nada.\n\n1. Com o número `READY` (webhook `did.ready`) e o KYC do customer\n   `APPROVED`, arme o recebimento:\n   `POST /api/v1/dids/:didId/whatsapp-verification` com\n   `{ \"recordingConsent\": true }` (a ligação é gravada só para ler o código\n   e apagada em até 24 h). O recebimento fica armado por até 24 h.\n2. O cliente cadastra o número no WhatsApp ou no WhatsApp Business, no formato\n   **+55 DDD número**, e na tela de verificação escolhe **\"Ligue para mim\"**\n   (não SMS). A opção de ligação pode levar alguns segundos para aparecer, e a\n   Meta pode levar alguns minutos para ligar.\n3. Segundos depois da ligação, o código chega no webhook\n   `whatsapp_verification.code_ready` (`data.verification.code`). Mostre\n   para o cliente digitar no WhatsApp. Sem webhook, consulte\n   `GET /api/v1/dids/:didId/whatsapp-verification` até `state` virar\n   `CODE_READY`.\n4. Com o número ativado no WhatsApp, chame\n   `POST /api/v1/dids/:didId/whatsapp-verification/complete`.\n\n`state` percorre `IDLE` → `ARMED` → `CALL_IN_PROGRESS` → `PROCESSING` →\n`CODE_READY`. Se vier `NO_CODE` (a ligação chegou mas o código não foi\nreconhecido), o áudio fica em `GET .../whatsapp-verification/recording` para\no cliente ouvir, ou o cliente pede outra ligação no WhatsApp com o recebimento\nainda armado. `DELETE .../whatsapp-verification` desarma. São até 10\nverificações por dia por número.\n\n**Alternativa — Siga-me:** `POST /api/v1/dids/:didId/whatsapp-forward`\nencaminha as ligações do número para o celular do cliente por 10 minutos (até\n3 vezes por dia); aí é ele quem atende a ligação da Meta e ouve o código. O\nSiga-me e o recebimento armado não funcionam ao mesmo tempo.\n\n## Ciclo de vida do DID\n\n```\nPOST /v1/dids → PURCHASED ──(provisionamento assíncrono)──▶ configuring ──▶ READY\n                                                                              │\n                              ┌───────────────────────────────────────────────┤\n                              ▼                                               ▼\n                   POST /sip (TRUNK | USER_PASSWORD)          POST /whatsapp-forward (10 min)\n                              │\n                   GET /sip/password  ◀── senha entregue UMA vez (reveal-once);\n                                          2ª chamada → 409. Use regenerate-password.\n```\n\nAcompanhe a transição por `GET /api/v1/dids/:didId` (campo `status`) ou pelos\nwebhooks `did.*`. `DELETE /api/v1/dids/:didId` cancela (irreversível).\n\n## Webhooks\n\nConfigure uma URL de webhook (via time Numio). Quando um evento ocorre, o Numio\nfaz **POST** nela com o corpo:\n\n```json\n{ \"id\": \"evt_AbC123\", \"type\": \"did.ready\", \"createdAt\": \"2026-06-19T12:00:00.000Z\", \"data\": { } }\n```\n\n**Assinatura:** header `Numio-Signature: t=<timestamp>,v1=<hmac>`, onde\n`<hmac>` é HMAC-SHA256 de `\"<timestamp>.<body>\"` com o seu signing secret.\nRecalcule localmente e compare antes de confiar no payload.\n\n**Entrega:** até **8 tentativas** com backoff (`Content-Type: application/json`,\n`User-Agent: Numio-Webhook/1.0`). Responda **2xx** para confirmar.\n\n**Eventos:**\n\n| Evento | Quando |\n|---|---|\n| `customer.created` / `customer.updated` | Customer criado / atualizado |\n| `customer.kyc.submitted` | Verificação concluída pelo cliente (entra em análise) |\n| `customer.kyc.approved` / `customer.kyc.rejected` | KYC aprovado / rejeitado |\n| `did.purchased` | DID contratado (PURCHASED) |\n| `did.configuring` | Provisionamento iniciado |\n| `did.ready` | DID pronto para uso (READY) |\n| `did.failed` | Provisionamento falhou |\n| `did.canceled` | DID cancelado |\n| `sip.configured` / `sip.deconfigured` | SIP configurado / removido |\n| `sip.password_regenerated` | Senha SIP regenerada (NUNCA no payload) |\n| `whatsapp_verification.code_ready` | Código de verificação do WhatsApp recebido (em `data.verification.code`) |\n| `whatsapp_forward.activated` / `whatsapp_forward.deactivated` / `whatsapp_forward.expired` | Siga-me ativado / desativado / expirado |\n\n> **Privacidade/segurança:** os webhooks de `sip.*` **nunca** carregam a senha;\n> os de `whatsapp_forward.*` levam o `destinationPhone` **sempre mascarado**.\n\n## Exemplo de fluxo (curl)\n\n```bash\nKEY=\"numio_live_xxxxxxxxxxxxxxxxxxxx\"\nBASE=\"https://api.numio.com.br/api/v1\"\n\n# 1) Cria o customer\ncurl -X POST \"$BASE/customers\" -H \"Authorization: Bearer $KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"externalId\":\"crm-42\",\"name\":\"Maria Oliveira Silva\",\"email\":\"maria@exemplo.com\",\"cpfCnpj\":\"12345678909\",\"phone\":\"11999999999\",\"address\":{\"street\":\"R. X\",\"number\":\"1\",\"neighborhood\":\"Centro\",\"city\":\"São Paulo\",\"state\":\"SP\",\"zipCode\":\"01000000\"}}'\n\n# 2) Abre a verificação de identidade e manda o cliente para a \"url\"\n#    da resposta; espere o webhook customer.kyc.approved para contratar\ncurl -X POST \"$BASE/customers/crm-42/kyc/session\" -H \"Authorization: Bearer $KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"birthDate\":\"1990-05-21\",\"returnUrl\":\"https://app.seuerp.com.br/volta\"}'\n\n# 3) Contrata um DID (idempotente)\ncurl -X POST \"$BASE/dids\" -H \"Authorization: Bearer $KEY\" \\\n  -H \"Content-Type: application/json\" -H \"Idempotency-Key: $(uuidgen)\" \\\n  -d '{\"customerIdOrExternalId\":\"crm-42\",\"didNumber\":\"4730000000\"}'\n\n# 4) Configura SIP USER_PASSWORD e pega a senha (reveal-once)\ncurl -X POST \"$BASE/dids/<didId>/sip\" -H \"Authorization: Bearer $KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"mode\":\"USER_PASSWORD\"}'\ncurl \"$BASE/dids/<didId>/sip/password\" -H \"Authorization: Bearer $KEY\"\n\n# 5) Com o número READY: arma o recebimento do código do WhatsApp; o código\n#    chega no webhook whatsapp_verification.code_ready\ncurl -X POST \"$BASE/dids/<didId>/whatsapp-verification\" -H \"Authorization: Bearer $KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"recordingConsent\":true}'\n```",
    "version": "1.0",
    "contact": {},
    "license": {
      "name": "Proprietary",
      "url": ""
    }
  },
  "tags": [
    {
      "name": "customers",
      "description": "API B2B — clientes finais do parceiro + KYC"
    },
    {
      "name": "dids",
      "description": "API B2B — contratação e gestão de DIDs"
    },
    {
      "name": "sip",
      "description": "API B2B — configuração SIP (Trunk / USER_PASSWORD)"
    },
    {
      "name": "whatsapp-forward",
      "description": "API B2B — Siga-me temporário pro WhatsApp Business"
    },
    {
      "name": "whatsapp-verification",
      "description": "API B2B — código de verificação do WhatsApp recebido pela Numio"
    },
    {
      "name": "sandbox",
      "description": "Endpoints que só existem no sandbox (`https://sandbox-api.numio.com.br/api/v1`, chave `numio_test_*`). Em produção respondem 404.\n\nTodos os outros endpoints desta documentação funcionam no sandbox do mesmo jeito que em produção: troque só a URL e a chave. No sandbox, o catálogo tem números fictícios, a compra não reserva número de verdade, nada é faturado e a verificação de identidade abre uma página de teste com os botões Aprovar, Recusar e Enviar para revisão. Estes dois endpoints simulam o que em produção depende de terceiros: a ligação da Meta com o código do WhatsApp e a decisão da equipe Numio sobre um KYC em revisão.\n\nDetalhes na seção \"Sandbox\" da visão geral."
    }
  ],
  "components": {
    "securitySchemes": {
      "partner-api-key": {
        "scheme": "bearer",
        "bearerFormat": "API_KEY",
        "type": "http",
        "description": "API key do parceiro B2B — numio_live_* em produção, numio_test_* no sandbox. Endpoints /api/v1/*."
      }
    },
    "schemas": {
      "ConfigureSipDto": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "TRUNK",
              "USER_PASSWORD"
            ]
          },
          "host": {
            "type": "string",
            "example": "200.1.2.3",
            "description": "IPv4 do PABX do cliente (obrigatório em TRUNK)."
          },
          "port": {
            "type": "number",
            "example": 5060,
            "description": "Porta SIP do PABX (obrigatório em TRUNK)."
          }
        },
        "required": [
          "mode"
        ]
      },
      "AddressDto": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string",
            "example": "Av. Paulista"
          },
          "number": {
            "type": "string",
            "example": "1000"
          },
          "complement": {
            "type": "string",
            "example": "Conj. 101"
          },
          "neighborhood": {
            "type": "string",
            "example": "Bela Vista"
          },
          "city": {
            "type": "string",
            "example": "São Paulo"
          },
          "state": {
            "type": "string",
            "example": "SP",
            "description": "UF — 2 letras maiúsculas"
          },
          "zipCode": {
            "type": "string",
            "example": "01310930",
            "description": "8 dígitos, sem hífen"
          }
        },
        "required": [
          "street",
          "number",
          "neighborhood",
          "city",
          "state",
          "zipCode"
        ]
      },
      "CustomerResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "cpfCnpj": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "address": {
            "$ref": "#/components/schemas/AddressDto"
          },
          "kycStatus": {
            "type": "string",
            "enum": [
              "NOT_SUBMITTED",
              "PENDING",
              "APPROVED",
              "REJECTED"
            ]
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "externalId",
          "name",
          "email",
          "cpfCnpj",
          "phone",
          "address",
          "kycStatus",
          "createdAt",
          "updatedAt"
        ]
      },
      "ApiErrorDetailDto": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "did_not_found"
          },
          "message": {
            "type": "string",
            "example": "Número não encontrado"
          },
          "details": {
            "type": "object",
            "additionalProperties": true,
            "description": "Contexto extra. Em VALIDATION_ERROR vem `{ errors: string[] }` com as falhas de validação do corpo/query.",
            "example": {
              "errors": [
                "destinationPhone deve estar no formato 55 + DDD + número"
              ]
            }
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "ApiErrorBodyDto": {
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ApiErrorDetailDto"
          }
        },
        "required": [
          "error"
        ]
      },
      "CreateCustomerDto": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "example": "crm_customer_123",
            "description": "ID do cliente no sistema do parceiro (opcional; único por parceiro quando informado)."
          },
          "name": {
            "type": "string",
            "example": "João Silva"
          },
          "email": {
            "type": "string",
            "example": "joao@example.com"
          },
          "cpfCnpj": {
            "type": "string",
            "example": "12345678900",
            "description": "CPF (11) ou CNPJ (14), só dígitos"
          },
          "phone": {
            "type": "string",
            "example": "19988192655",
            "description": "DDD + número (10 a 11 dígitos), só BR — sem o código do país 55."
          },
          "address": {
            "$ref": "#/components/schemas/AddressDto"
          }
        },
        "required": [
          "name",
          "email",
          "cpfCnpj",
          "phone",
          "address"
        ]
      },
      "UpdateCustomerDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "João Silva"
          },
          "email": {
            "type": "string",
            "example": "joao@example.com"
          },
          "phone": {
            "type": "string",
            "example": "19988192655"
          },
          "address": {
            "$ref": "#/components/schemas/AddressDto"
          },
          "cpfCnpj": {
            "type": "string",
            "description": "IMUTÁVEL — enviar este campo resulta em 400 immutable_field."
          }
        }
      },
      "StartKycSessionDto": {
        "type": "object",
        "properties": {
          "birthDate": {
            "type": "string",
            "example": "1990-05-21",
            "description": "Data de nascimento do titular (AAAA-MM-DD). Obrigatória quando o customer é CPF: é comparada com o documento e barra menor de 18 anos."
          },
          "fullName": {
            "type": "string",
            "example": "João da Silva Santos",
            "description": "Nome completo do titular, igual ao do documento. Padrão: o `name` do customer. Nome abreviado manda a verificação pra revisão manual."
          },
          "returnUrl": {
            "type": "string",
            "example": "https://app.seuerp.com.br/clientes/crm-42/verificacao",
            "description": "URL https para onde o cliente volta ao terminar a verificação. Sem ela, a verificação termina na própria tela de conclusão."
          }
        }
      },
      "KycSessionResponseDto": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          "url": {
            "type": "string",
            "example": "https://verify.didit.me/session/AbCdEf123",
            "description": "Página de verificação. Abra para o cliente final (nova aba, janela ou redirecionamento): ele fotografa o documento e faz a selfie ali."
          },
          "status": {
            "type": "string",
            "example": "Not Started",
            "description": "Status da sessão: `Not Started`, `In Progress`, `In Review`, `Approved`, `Declined`, `Abandoned` ou `Expired`."
          }
        },
        "required": [
          "sessionId",
          "url",
          "status"
        ]
      },
      "AvailableDidDto": {
        "type": "object",
        "properties": {
          "number": {
            "type": "string",
            "example": "4730000000"
          },
          "ddd": {
            "type": "number",
            "example": 47
          },
          "city": {
            "type": "string",
            "example": "Blumenau"
          }
        },
        "required": [
          "number",
          "ddd",
          "city"
        ]
      },
      "PurchaseDidDto": {
        "type": "object",
        "properties": {
          "customerIdOrExternalId": {
            "type": "string",
            "example": "crm_customer_123",
            "description": "id (cuid) ou externalId do customer dono do número."
          },
          "didNumber": {
            "type": "string",
            "example": "4730000000",
            "description": "10 ou 11 dígitos."
          },
          "metadata": {
            "type": "object",
            "description": "Metadata livre do parceiro (máx 5 chaves, valores string).",
            "example": {
              "plan": "pro",
              "ref": "abc"
            }
          }
        },
        "required": [
          "customerIdOrExternalId",
          "didNumber"
        ]
      },
      "DidResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "number": {
            "type": "string"
          },
          "customerId": {
            "type": "string"
          },
          "customerExternalId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "example": "PURCHASED"
          },
          "sipMode": {
            "type": "string",
            "enum": [
              "NONE",
              "TRUNK",
              "USER_PASSWORD"
            ]
          },
          "whatsappForwardActive": {
            "type": "boolean"
          },
          "metadata": {
            "type": "object",
            "nullable": true
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "purchasedAt": {
            "format": "date-time",
            "type": "string",
            "nullable": true
          },
          "canceledAt": {
            "format": "date-time",
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "number",
          "customerId",
          "customerExternalId",
          "status",
          "sipMode",
          "whatsappForwardActive",
          "metadata",
          "createdAt",
          "purchasedAt",
          "canceledAt"
        ]
      },
      "ActivateForwardDto": {
        "type": "object",
        "properties": {
          "destinationPhone": {
            "type": "string",
            "example": "5519988192655",
            "description": "55 + DDD + número"
          }
        },
        "required": [
          "destinationPhone"
        ]
      },
      "ArmWhatsappVerificationDto": {
        "type": "object",
        "properties": {
          "recordingConsent": {
            "type": "boolean",
            "example": true,
            "description": "Autorização do cliente final para gravar a ligação de verificação (o código é extraído do áudio, apagado em até 24 h). Obrigatório e sempre true."
          }
        },
        "required": [
          "recordingConsent"
        ]
      },
      "SimulateVerificationCallDto": {
        "type": "object",
        "properties": {
          "result": {
            "type": "string",
            "enum": [
              "CODE",
              "NO_CODE"
            ],
            "default": "CODE",
            "description": "`CODE`: a ligação chega e o código é reconhecido (webhook `whatsapp_verification.code_ready`). `NO_CODE`: a ligação chega mas o código não é reconhecido (`state` = `NO_CODE`, com áudio em `/recording`)."
          },
          "code": {
            "type": "string",
            "example": "123456",
            "default": "123456",
            "description": "Código de 6 dígitos a entregar quando `result` é `CODE`."
          }
        }
      },
      "SandboxKycDecisionDto": {
        "type": "object",
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "APPROVED",
              "REJECTED"
            ]
          },
          "reason": {
            "type": "string",
            "example": "Documento ilegível. Envie uma foto nítida.",
            "description": "Motivo da recusa (vai em `rejectionReason`)."
          }
        },
        "required": [
          "decision"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://api.numio.com.br/api",
      "description": "Produção"
    },
    {
      "url": "https://sandbox-api.numio.com.br/api",
      "description": "Sandbox"
    }
  ]
}
