{
  "openapi": "3.1.1",
  "info": {
    "title": "Imóveis na Bio: API pública e acesso autorizado",
    "version": "1.0.0",
    "description": "Contrato estável v1 para consulta pública, captação autorizada e contexto da própria conta. Mudanças incompatíveis exigem uma nova versão principal. Não inclui endpoints internos do painel, administração, billing ou workers. Não existe GraphQL nem servidor MCP público. A publicação deste contrato não concede acesso aos dados privados.",
    "contact": {
      "name": "Imóveis na Bio",
      "url": "https://www.imoveisna.bio/contact",
      "email": "comercial@imoveisna.bio"
    },
    "x-api-lifecycle": {
      "current_major": "v1",
      "unversioned_routes": "Mantidas somente para compatibilidade do aplicativo atual; novas integrações devem usar /api/v1.",
      "minimum_notice_days": 180,
      "policy_url": "https://www.imoveisna.bio/api-lifecycle",
      "deprecation_policy": "Nenhuma versão está em descontinuação. Uma futura descontinuação será anunciada com o header Deprecation conforme RFC 9745 e, quando houver data de encerramento, com Sunset conforme RFC 8594, junto de orientação de migração."
    }
  },
  "servers": [
    {
      "url": "https://api.imoveisna.bio",
      "description": "Produção"
    }
  ],
  "externalDocs": {
    "description": "Autenticação, exemplos e limites",
    "url": "https://www.imoveisna.bio/docs"
  },
  "paths": {
    "/api/v1/status": {
      "get": {
        "operationId": "getApiStatus",
        "summary": "Verificar versão, conectividade e limites da API",
        "description": "Operação pública e sem efeitos colaterais. Não exige login ou API key. Use para verificar o cliente e ler os headers de limite antes de acessar recursos reais.",
        "security": [],
        "responses": {
          "200": {
            "description": "API disponível.",
            "headers": {
              "Link": {
                "description": "Política de ciclo de vida descoberta com rel=deprecation. Sua presença isolada não indica que v1 está descontinuada.",
                "schema": {"type": "string"}
              },
              "RateLimit-Policy": {
                "description": "Política efetiva conforme draft-ietf-httpapi-ratelimit-headers-11.",
                "schema": {"type": "string"}
              },
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar.",
                "schema": {"type": "string"}
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["service", "version", "status", "documentation", "openapi"],
                  "properties": {
                    "service": {"type": "string", "const": "Imóveis na Bio API"},
                    "version": {"type": "string", "const": "v1"},
                    "status": {"type": "string", "const": "ok"},
                    "documentation": {"type": "string", "format": "uri"},
                    "openapi": {"type": "string", "format": "uri"}
                  }
                }
              }
            }
          },
          "429": {
            "description": "Limite excedido. Aguarde Retry-After antes de repetir.",
            "headers": {
              "Retry-After": {"schema": {"type": "integer", "minimum": 1}},
              "RateLimit": {"schema": {"type": "string"}}
            },
            "content": {
              "application/json": {"schema": {"$ref": "#/components/schemas/Error"}}
            }
          }
        }
      }
    },
    "/api/v1/public/pages/{slug}": {
      "parameters": [
        {
          "in": "path",
          "name": "slug",
          "required": true,
          "description": "Endereço público escolhido pelo corretor.",
          "schema": {
            "type": "string",
            "maxLength": 63,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "example": "corretor-exemplo"
        }
      ],
      "get": {
        "operationId": "getPublicPage",
        "summary": "Consultar página publicada de um corretor",
        "description": "Somente páginas publicadas de contas ativas. Não aceita query parameters. Os campos retornados orientam o formulário. Não utilize tracking sem consentimento.",
        "security": [],
        "parameters": [
          {
            "in": "header",
            "name": "If-None-Match",
            "description": "ETag recebido anteriormente.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento público.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicPage"
                }
              }
            }
          },
          "304": {
            "description": "Não modificado; sem corpo.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Parâmetros, anti-spam ou corpo inválido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Recurso ausente ou não publicado.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Método não permitido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Campos inválidos.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite excedido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Segundos mínimos antes de tentar novamente.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Serviço temporariamente indisponível.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/pages/{slug}/leads": {
      "parameters": [
        {
          "in": "path",
          "name": "slug",
          "required": true,
          "description": "Endereço público escolhido pelo corretor.",
          "schema": {
            "type": "string",
            "maxLength": 63,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "example": "corretor-exemplo"
        }
      ],
      "post": {
        "operationId": "submitAuthorizedInterest",
        "summary": "Registrar interesse autorizado pelo visitante",
        "description": "Obtenha autorização explícita para compartilhar os dados com o corretor. Não envie testes ou contatos inventados à produção. Consulte fields[] e os campos required da página. Anti-spam e validação de origem continuam vigentes. A chave de idempotência vai no corpo, não no header.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Interesse aceito ou repetição idempotente da mesma intenção.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadReceipt"
                }
              }
            }
          },
          "400": {
            "description": "Parâmetros, anti-spam ou corpo inválido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Origem não permitida.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Recurso ausente ou não publicado.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Método não permitido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Chave idempotente reutilizada com outro conteúdo.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Campos inválidos.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite excedido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Segundos mínimos antes de tentar novamente.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Serviço temporariamente indisponível.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/context": {
      "get": {
        "operationId": "getOwnAccountContext",
        "summary": "Consultar o contexto da própria conta",
        "description": "Exige sessão existente do usuário via access token ou cookie. Não aceita query parameters. Associação ativa e isolamento por conta permanecem obrigatórios. Não solicite senhas pelo chat nem copie tokens para logs.",
        "security": [
          {
            "SupabaseBearer": []
          },
          {
            "SessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Associação, conta e assinatura; valores nulos sem contexto ativo.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountContext"
                }
              }
            }
          },
          "400": {
            "description": "Parâmetros, anti-spam ou corpo inválido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Sessão ausente, inválida ou expirada.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Conta inativa ou acesso negado.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Recurso ausente ou não publicado.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Método não permitido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Campos inválidos.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite excedido.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Segundos mínimos antes de tentar novamente.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Serviço temporariamente indisponível.",
            "headers": {
              "RateLimit": {
                "description": "Quota restante e segundos até reiniciar. Ex.: \"default\";r=119;t=42.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Política efetiva. Ex.: \"default\";q=120;w=60. Segue draft-ietf-httpapi-ratelimit-headers-11, ainda não RFC.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "SupabaseBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Access token Supabase já emitido para o próprio usuário. Nunca use service_role ou chaves administrativas."
      },
      "SessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-imoveisnabio-access",
        "description": "Cookie HttpOnly e Secure emitido no login do navegador."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "fields",
              "request_id"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "fields": {
                "type": "object",
                "additionalProperties": true
              },
              "request_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              }
            }
          }
        }
      },
      "AccountContext": {
        "type": "object",
        "required": [
          "membership",
          "tenant",
          "billing_plan"
        ],
        "properties": {
          "membership": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "tenant": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "billing_plan": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          }
        }
      },
      "PublicPage": {
        "type": "object",
        "required": [
          "page",
          "blocks",
          "properties",
          "form",
          "fields",
          "form_gate",
          "settings",
          "design",
          "tracking"
        ],
        "properties": {
          "page": {
            "type": "object",
            "additionalProperties": true
          },
          "blocks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "properties": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "form": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "form_gate": {
            "type": "object",
            "additionalProperties": true
          },
          "settings": {
            "type": "object",
            "additionalProperties": true
          },
          "design": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "tracking": {
            "type": "object",
            "required": [
              "enabled",
              "token"
            ],
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "token": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        },
        "additionalProperties": true
      },
      "LeadRequest": {
        "type": "object",
        "description": "Requer nome, email ou telefone, além dos campos obrigatórios publicados. Os contatos podem estar em fields, payload ou nos aliases de primeiro nível. Sem consentimento, omita tracking. Se tracking for incluído e estiver habilitado, exige token, visitor_id, session_id e idempotency_key juntos.",
        "properties": {
          "fields": {
            "type": "object",
            "additionalProperties": true,
            "description": "Campos por fields[].key; respeite required, type e options."
          },
          "payload": {
            "type": "object",
            "additionalProperties": true,
            "description": "Alternativa para transmitir os campos."
          },
          "idempotency_key": {
            "type": "string",
            "pattern": "^[A-Za-z0-9:_-]{8,200}$",
            "description": "Mesma chave e conteúdo ao repetir a mesma solicitação."
          },
          "started_at": {
            "type": "string",
            "pattern": "^[0-9]{13}$",
            "description": "Instante real de abertura do formulário em milissegundos Unix. Não invente."
          },
          "company_website": {
            "type": "string",
            "const": ""
          },
          "_gotcha": {
            "type": "string",
            "const": ""
          },
          "selected_property_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "selected_property_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "tracking_token": {
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "visitor_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "attribution": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Opcional, sujeito à validação de atribuição. Não invente."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "nome": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "lead_name": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 160
          },
          "e-mail": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 160
          },
          "lead_email": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 160
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 40
          },
          "telefone": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 40
          },
          "whatsapp": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 40
          },
          "lead_phone": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 40
          },
          "interest": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "interesse": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "tipo_de_imovel": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "tipo": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "budget": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "faixa_de_valor": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "faixa": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          },
          "valor": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 120
          }
        },
        "additionalProperties": false
      },
      "LeadReceipt": {
        "type": "object",
        "required": [
          "ok",
          "lead_id",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "lead_id": {
            "type": "string",
            "format": "uuid"
          },
          "message": {
            "type": "string"
          },
          "deduplicated": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    }
  }
}
