{
  "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": {
      "post": {
        "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": "Submete KYC: selfie + documentFront + documentBack (multipart). Valida magic bytes (jpeg/png/webp, máx 10MB). 202 quando aceito.",
        "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
                  }
                }
              }
            }
          },
          "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 na TIP 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 (Centrex/Zeus + unlink na TIP). 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, desvincula na TIP). 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": "189.113.47.136",
                      "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/Zeus interno) 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": "189.113.47.136",
                      "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 no Zeus"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "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 via worker → webhook `whatsapp_forward.expired`). 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"
        ]
      }
    }
  },
  "info": {
    "title": "Numio API",
    "description": "Backend Numio — endpoints **admin (B2C)** e a **API B2B** para parceiros\n(CRMs, plataformas omnichannel) contratarem e gerenciarem DIDs em nome dos\nclientes finais deles.\n\nEsta página documenta principalmente a **API B2B** (`/api/v1/*`). Os\nendpoints `admin/*` são internos do painel Numio (auth por cookie).\n\n## Autenticação (parceiro)\n\nTodos os endpoints `/api/v1/*` autenticam por **Bearer token** no header\n`Authorization`. A API key (`numio_live_*`) é gerada pelo time Numio e\naparece **uma única vez** na criação.\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## 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## 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` | KYC enviado (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_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\":\"Acme\",\"email\":\"a@acme.com\",\"cpfCnpj\":\"12345678000190\",\"phone\":\"5511999999999\",\"address\":{\"street\":\"R. X\",\"number\":\"1\",\"neighborhood\":\"Centro\",\"city\":\"São Paulo\",\"state\":\"SP\",\"zipCode\":\"01000000\"}}'\n\n# 2) Envia o KYC (multipart) — após aprovado, contrata\ncurl -X POST \"$BASE/customers/crm-42/kyc\" -H \"Authorization: Bearer $KEY\" \\\n  -F selfie=@selfie.jpg -F documentFront=@front.jpg -F documentBack=@back.jpg\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```",
    "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"
    }
  ],
  "components": {
    "securitySchemes": {
      "partner-api-key": {
        "scheme": "bearer",
        "bearerFormat": "API_KEY",
        "type": "http",
        "description": "API key do parceiro B2B (numio_live_*) — endpoints /api/v1/*."
      }
    },
    "schemas": {
      "ConfigureSipDto": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "TRUNK",
              "USER_PASSWORD"
            ]
          },
          "host": {
            "type": "string",
            "example": "189.113.45.10",
            "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."
          }
        }
      },
      "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"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://api.numio.com.br/api",
      "description": "API Numio"
    }
  ]
}
