{
  "openapi": "3.1.0",
  "info": {
    "title": "HookPulse",
    "version": "dev",
    "description": "Dead-man webhook/cron. Índice: GET /api/."
  },
  "servers": [
    {
      "url": "https://hookpulse.net"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Guest token (`POST /api/guest`) em `X-Guest-Token: hp_…` ou `Authorization: Bearer hp_…`. Sessão `sess_…` também serve."
      }
    }
  },
  "paths": {
    "/api/": {
      "get": {
        "summary": "Índice auto-descrito de toda a superfície.",
        "description": "Devolve: { name, description, auth, endpoints[], quickstart[] }",
        "security": [],
        "responses": {
          "200": {
            "description": "{ name, description, auth, endpoints[], quickstart[] }"
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "summary": "Liveness.",
        "description": "Devolve: { ok, app, ts }",
        "security": [],
        "responses": {
          "200": {
            "description": "{ ok, app, ts }"
          }
        }
      }
    },
    "/api/guest": {
      "post": {
        "summary": "Cria guest token `hp_…` (dono anônimo de endpoints).",
        "description": "Devolve: { token }",
        "security": [],
        "responses": {
          "200": {
            "description": "{ token }"
          }
        }
      }
    },
    "/api/endpoints": {
      "get": {
        "summary": "Lista endpoints do dono (guest ou sessão).",
        "description": "Devolve: { endpoints[], guest, billing? }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "{ endpoints[], guest, billing? }"
          }
        }
      },
      "post": {
        "summary": "Cria endpoint de dead-man. 2º+ ou intervalo < free_min → x402 (402 até pagar).",
        "description": "Devolve: { id, name, ingest_url, token, interval_sec, … }\nFree: 1 endpoint, intervalo ≥ 900s. Preços em GET /api/billing.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "cron prod",
                "interval_sec": 900,
                "alert_to": "opcional@email.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ id, name, ingest_url, token, interval_sec, … }"
          }
        }
      }
    },
    "/api/endpoints/{id}": {
      "get": {
        "summary": "Status de um endpoint (token de dono ou token do endpoint).",
        "description": "Devolve: { id, healthy, overdue, last_event_at, ingest_url, … }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ id, healthy, overdue, last_event_at, ingest_url, … }"
          }
        }
      },
      "patch": {
        "summary": "Atualiza nome/intervalo/alert_to (pode cobrar x402 se intervalo ficar pago).",
        "description": "Devolve: { ok, endpoint }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "…",
                "interval_sec": 300,
                "alert_to": null
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ ok, endpoint }"
          }
        }
      },
      "delete": {
        "summary": "Desativa/remove o endpoint do dono.",
        "description": "Devolve: { ok }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok }"
          }
        }
      }
    },
    "/api/endpoints/{id}/events": {
      "get": {
        "summary": "Últimos pings recebidos no ingest.",
        "description": "Devolve: { events[] }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ events[] }"
          }
        }
      }
    },
    "/in/{id}": {
      "get": {
        "summary": "URL de ingest — cron/webhook faz GET/POST aqui para provar vida.",
        "description": "Devolve: { ok } ou texto curto",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok } ou texto curto"
          }
        }
      },
      "post": {
        "summary": "Mesmo ingest via POST (body opcional).",
        "description": "Devolve: { ok }",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok }"
          }
        }
      }
    },
    "/api/billing": {
      "get": {
        "summary": "Free tier, preços e parâmetros x402 (incl. contact_agent_usd).",
        "description": "Devolve: { provider, network, prices, free_max_endpoints, … }",
        "security": [],
        "responses": {
          "200": {
            "description": "{ provider, network, prices, free_max_endpoints, … }"
          }
        }
      }
    },
    "/api/contact": {
      "post": {
        "summary": "Suporte: Turnstile (humano) ou x402 $0.10 (agente).",
        "description": "Devolve: { ok, path } | 402 accepts[]",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "…",
                "email": "a@example.com",
                "message": "…",
                "form_ts": 0
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ ok, path } | 402 accepts[]"
          }
        }
      }
    },
    "/api/me": {
      "get": {
        "summary": "Usuário da sessão + endpoints.",
        "description": "Devolve: { user, endpoints[] }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "{ user, endpoints[] }"
          }
        }
      }
    },
    "/api/auth/start": {
      "post": {
        "summary": "Envia OTP por e-mail.",
        "description": "Devolve: { ok }",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "email": "voce@exemplo.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ ok }"
          }
        }
      }
    },
    "/api/auth/verify": {
      "post": {
        "summary": "Troca OTP por sessão sess_…",
        "description": "Devolve: { ok, token, user }",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "email": "voce@exemplo.com",
                "code": "123456"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ ok, token, user }"
          }
        }
      }
    },
    "/api/auth/claim": {
      "post": {
        "summary": "Move endpoints do guest para a conta.",
        "description": "Devolve: { ok, claimed }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "guest_token": "hp_…"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ ok, claimed }"
          }
        }
      }
    },
    "/api/auth/logout": {
      "post": {
        "summary": "Invalida sessão.",
        "description": "Devolve: { ok }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok }"
          }
        }
      }
    },
    "/api/visit": {
      "post": {
        "summary": "Ping de audiência da UI (agente ignora).",
        "description": "Devolve: { ok, counted }",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "p": "/"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ ok, counted }"
          }
        }
      }
    },
    "/api/metrics": {
      "get": {
        "summary": "Métricas 7d (operador).",
        "description": "Devolve: { app, visits[], … }",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "{ app, visits[], … }"
          }
        }
      }
    }
  }
}