{
  "openapi": "3.1.0",
  "info": {
    "title": "Falia — API v1",
    "description": "API REST do Falia (atendimento com IA no WhatsApp). Base: https://falia.com.br/api/v1. Erros em application/problem+json (RFC 9457) com request_id. Datas em milissegundos UTC. Paginação por cursor. Aceita e devolve trace W3C (traceparent / X-Trace-Id). Webhooks assinados com HMAC-SHA256 (X-Proton-Signature). MCP em https://falia.com.br/mcp.",
    "contact": {
      "name": "Proton Code Studio",
      "url": "https://protoncode.com.br"
    },
    "license": {
      "name": ""
    },
    "version": "0.3.0"
  },
  "servers": [
    {
      "url": "https://falia.com.br"
    }
  ],
  "paths": {
    "/api/v1/conversations": {
      "get": {
        "tags": [
          "conversas"
        ],
        "summary": "Listar conversas",
        "description": "Da mais recente para a mais antiga. Paginação por cursor.",
        "operationId": "list_conversations",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "1 a 100 (padrão 50).",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConversationPage"
                }
              }
            }
          },
          "400": {
            "description": ""
          },
          "401": {
            "description": ""
          },
          "403": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "conversations:read"
            ]
          }
        ]
      }
    },
    "/api/v1/conversations/{id}/messages": {
      "get": {
        "tags": [
          "conversas"
        ],
        "summary": "Mensagens de uma conversa",
        "description": "As mensagens mais recentes, da mais antiga para a mais nova.",
        "operationId": "list_messages",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id da conversa (ex.: 5511999990000@s.whatsapp.net)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Quantas das mensagens mais recentes: 1 a 100 (padrão 40).",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageList"
                }
              }
            }
          },
          "400": {
            "description": ""
          },
          "401": {
            "description": ""
          },
          "403": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "conversations:read"
            ]
          }
        ]
      }
    },
    "/api/v1/conversations/{id}/status": {
      "post": {
        "tags": [
          "conversas"
        ],
        "summary": "Mudar o status da conversa",
        "description": "`open` (aberta), `pending` (aguardando o cliente) ou `resolved` (resolvida). Mensagem nova do cliente reabre a conversa.",
        "operationId": "post_status",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id da conversa (ex.: 5511999990000@s.whatsapp.net)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatusInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConversationStatus"
                }
              }
            }
          },
          "400": {
            "description": ""
          },
          "401": {
            "description": ""
          },
          "403": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "messages:send"
            ]
          }
        ]
      }
    },
    "/api/v1/messages": {
      "post": {
        "tags": [
          "conversas"
        ],
        "summary": "Enviar mensagem de texto ou modelo",
        "description": "Aceita `Idempotency-Key`: repetir a chamada com a mesma chave em até 24 h devolve a mesma resposta sem enviar de novo. Limite: 1000 mensagens por dia por empresa. Na API oficial, texto livre só até 24 h depois da última mensagem do cliente (409 depois disso); fora da janela, envie `template`.",
        "operationId": "post_message",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Chave única da operação (até 100 caracteres)",
            "required": false,
            "schema": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewMessage"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SentMessage"
                }
              }
            }
          },
          "400": {
            "description": ""
          },
          "403": {
            "description": ""
          },
          "409": {
            "description": ""
          },
          "429": {
            "description": ""
          },
          "502": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "messages:send"
            ]
          }
        ]
      }
    },
    "/api/v1/status": {
      "get": {
        "tags": [
          "conexao"
        ],
        "summary": "Estado da conexão com o WhatsApp",
        "operationId": "get_status",
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectionStatus"
                }
              }
            }
          },
          "401": {
            "description": ""
          },
          "502": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "conversations:read"
            ]
          }
        ]
      }
    },
    "/api/v1/templates": {
      "get": {
        "tags": [
          "conversas"
        ],
        "summary": "Modelos aprovados (API oficial)",
        "description": "Modelos aprovados pela Meta para a conta da empresa. Só para empresas na API oficial (409 nas demais).",
        "operationId": "list_templates",
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateList"
                }
              }
            }
          },
          "401": {
            "description": ""
          },
          "403": {
            "description": ""
          },
          "409": {
            "description": ""
          },
          "502": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "conversations:read"
            ]
          }
        ]
      }
    },
    "/api/v1/webhook-deliveries/{id}/retry": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Reenviar uma entrega",
        "operationId": "v1_retry",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "202": {
            "description": ""
          },
          "404": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "webhooks:manage"
            ]
          }
        ]
      }
    },
    "/api/v1/webhooks": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Listar endpoints de webhook",
        "operationId": "v1_list",
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Endpoint"
                  }
                }
              }
            }
          },
          "401": {
            "description": ""
          },
          "403": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "webhooks:manage"
            ]
          }
        ]
      },
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Cadastrar endpoint de webhook",
        "description": "Eventos: `message.received`, `message.sent`, `connection.updated`, `conversation.handoff_requested` ou `*`. O `secret` volta só nesta resposta.",
        "operationId": "v1_create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewEndpoint"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedEndpoint"
                }
              }
            }
          },
          "400": {
            "description": ""
          },
          "403": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "webhooks:manage"
            ]
          }
        ]
      }
    },
    "/api/v1/webhooks/{id}": {
      "delete": {
        "tags": [
          "webhooks"
        ],
        "summary": "Remover endpoint de webhook",
        "operationId": "v1_delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "404": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "webhooks:manage"
            ]
          }
        ]
      }
    },
    "/api/v1/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Últimas 100 entregas de um endpoint",
        "operationId": "v1_deliveries",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Delivery"
                  }
                }
              }
            }
          },
          "404": {
            "description": ""
          }
        },
        "security": [
          {
            "api_key": [
              "webhooks:manage"
            ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ApiMessage": {
        "type": "object",
        "required": [
          "id",
          "from_me",
          "sent_at",
          "kind",
          "text",
          "has_media"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "from_me": {
            "type": "boolean"
          },
          "sent_at": {
            "type": "integer",
            "format": "int64",
            "description": "Milissegundos UTC."
          },
          "kind": {
            "type": "string",
            "description": "`text`, `image`, `audio`, `video`, `document`, `sticker`, `poll`…"
          },
          "text": {
            "type": "string"
          },
          "has_media": {
            "type": "boolean"
          },
          "author": {
            "type": [
              "string",
              "null"
            ],
            "description": "Quem enviou pelo Falia (atendente, robô ou API key), quando `from_me`."
          },
          "sender": {
            "type": [
              "string",
              "null"
            ],
            "description": "Em grupos, quem mandou."
          }
        }
      },
      "ApiTemplate": {
        "type": "object",
        "required": [
          "name",
          "language",
          "category",
          "body",
          "params",
          "supported"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "language": {
            "type": "string",
            "description": "Ex.: `pt_BR`."
          },
          "category": {
            "type": "string",
            "description": "`MARKETING`, `UTILITY` ou `AUTHENTICATION`."
          },
          "body": {
            "type": "string",
            "description": "Texto do corpo com as variáveis `{{1}}`, `{{2}}`…"
          },
          "params": {
            "type": "integer",
            "minimum": 0
          },
          "supported": {
            "type": "boolean",
            "description": "`false`: cabeçalho ou botão variável; envie pelo Gerenciador do WhatsApp."
          }
        }
      },
      "ConnectionStatus": {
        "type": "object",
        "required": [
          "state",
          "provider"
        ],
        "properties": {
          "state": {
            "type": "string",
            "description": "`open` (conectado), `connecting`, `close` ou `inexistente` (nunca conectado)."
          },
          "provider": {
            "type": "string",
            "description": "`evolution` (QR code) ou `cloud` (API oficial da Meta)."
          }
        }
      },
      "Conversation": {
        "type": "object",
        "required": [
          "id",
          "name",
          "is_group",
          "unread",
          "last_message_at",
          "status",
          "tags"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador da conversa no WhatsApp (ex.: `5511999990000@s.whatsapp.net`)."
          },
          "name": {
            "type": "string"
          },
          "is_group": {
            "type": "boolean"
          },
          "unread": {
            "type": "integer",
            "format": "int64"
          },
          "last_message_at": {
            "type": "integer",
            "format": "int64",
            "description": "Última mensagem (milissegundos UTC); 0 se desconhecido."
          },
          "last_message_text": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_message_from_me": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "description": "`open` (cliente escreveu), `pending` (aguardando o cliente) ou `resolved`."
          },
          "assignee": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Person",
                "description": "Pessoa da equipe responsável, se houver."
              }
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Nomes das etiquetas da conversa."
          }
        }
      },
      "ConversationPage": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Conversation"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Passe em `cursor` para a próxima página; `null` quando acabou."
          }
        }
      },
      "ConversationStatus": {
        "type": "object",
        "required": [
          "id",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        }
      },
      "CreatedEndpoint": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Endpoint"
          },
          {
            "type": "object",
            "required": [
              "secret"
            ],
            "properties": {
              "secret": {
                "type": "string",
                "description": "Segredo para verificar a assinatura. Mostrado só agora."
              }
            }
          }
        ]
      },
      "Delivery": {
        "type": "object",
        "required": [
          "id",
          "event_id",
          "event_type",
          "status",
          "attempts",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "event_id": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "`pending`, `delivered` ou `failed`."
          },
          "attempts": {
            "type": "integer",
            "format": "int64"
          },
          "last_status": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "integer",
            "format": "int64"
          },
          "delivered_at": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64"
          }
        }
      },
      "Endpoint": {
        "type": "object",
        "required": [
          "id",
          "url",
          "events",
          "active",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "active": {
            "type": "boolean"
          },
          "created_at": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "MessageList": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiMessage"
            },
            "description": "Do mais antigo para o mais novo."
          }
        }
      },
      "NewEndpoint": {
        "type": "object",
        "required": [
          "url",
          "events"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "URL https:// pública que receberá os eventos."
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Eventos assinados; `[\"*\"]` para todos."
          }
        },
        "additionalProperties": false
      },
      "NewMessage": {
        "type": "object",
        "required": [
          "to"
        ],
        "properties": {
          "to": {
            "type": "string",
            "description": "Número com DDD (`11999990000`, `+55 11 99999-0000`) ou id da conversa."
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "description": "1 a 4096 caracteres. Omitido quando vai `template`."
          },
          "template": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/TemplateInput",
                "description": "Só na API oficial: modelo aprovado (obrigatório para quem não escreveu nas últimas 24 h)."
              }
            ]
          }
        },
        "additionalProperties": false
      },
      "Person": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "SentMessage": {
        "type": "object",
        "required": [
          "id",
          "conversation_id",
          "sent_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "conversation_id": {
            "type": "string"
          },
          "sent_at": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "StatusInput": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "description": "`open`, `pending` ou `resolved`."
          }
        },
        "additionalProperties": false
      },
      "TemplateInput": {
        "type": "object",
        "required": [
          "name",
          "language"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "params": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Valores de `{{1}}`, `{{2}}`… (até 10, sem quebra de linha)."
          }
        },
        "additionalProperties": false
      },
      "TemplateList": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiTemplate"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "api_key": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key criada pelo dono da empresa no painel (Integrações): `Authorization: Bearer fal_live_...`. Vence em até 365 dias."
      }
    }
  },
  "tags": [
    {
      "name": "conexao",
      "description": "Conexão do número de WhatsApp"
    },
    {
      "name": "conversas",
      "description": "Conversas e mensagens"
    },
    {
      "name": "webhooks",
      "description": "Eventos enviados para o seu sistema: message.received, message.sent, connection.updated, conversation.handoff_requested, conversation.updated, conversation.rated, message.status_updated"
    }
  ]
}