{
  "name": "Agentalog",
  "description": "Agent Auto Log: catalog of MCP servers, skills and plugins with an automatic change log, plus a monitor for what your agents install. Submissions are reviewed before publication. This is an independent catalog.",
  "auth": {
    "credito": "Credit token in `Authorization: Bearer cred_…` or `X-Credito`. For recovered x402 funds, use the wallet credential mmw_… in Bearer or X-Wallet-Token, issued through /api/auth/wallet/agent/start and /api/auth/wallet/agent/token.",
    "none": "Public, no credential.",
    "guest": "Guest token (`POST /api/guest`) in `X-Guest-Token: mr_…` or `Authorization: Bearer mr_…`. In the browser it also lives in the HttpOnly `mr_guest` cookie, which writes only from this site's exact Origin. A signed-in account (cookie) also works and takes precedence.",
    "session": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans.",
    "session_ou_x402": "A person can submit with the account cookie or a guest identity. An agent can submit without an account. Both paths use the same submission limits. With an account, submitting is free; without one, it costs US$ 0.10 through x402 or prepaid credit.",
    "session_ou_carteira": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account.",
    "token": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint.",
    "monitor_installation": "Private mmi_ credential in Authorization: Bearer, restricted to one installation and project. The account issues it after recent human sign-in. It cannot approve, buy or issue another credential.",
    "monitor_notices": "Dedicated mmn_ bearer credential for the existing product mail service. Only reserve, start and confirm one product's notices. Account cookies, API keys and installation tokens are refused.",
    "session_ou_monitor_reader": "The existing human account cookie, or a separate mmq_ bearer credential for one project's event GET. Do not mix the reader with cookies or X-API-Key. Account status, security version, expiry and revocation are checked on each use."
  },
  "docs": {
    "llms": "https://staging.agentalog.com/llms.txt",
    "llms_full": "https://staging.agentalog.com/llms-full.txt",
    "openapi": "https://staging.agentalog.com/openapi.json",
    "mcp": "https://staging.agentalog.com/mcp",
    "pricing": "https://staging.agentalog.com/api/pricing",
    "billing": "https://staging.agentalog.com/api/billing",
    "human_ui": "https://staging.agentalog.com/",
    "data_indexes": [
      {
        "id": "cep",
        "produto": "https://pontofato.com",
        "caminho": "/enderecos",
        "title": "Postal codes and addresses",
        "description": "Find addresses by location, with coordinates and a 2022 reference date. Not a current postal-code certification. Each HTML page opens the product app with its public data already rendered.",
        "hierarchy": "State → municipality → locality → street → addresses",
        "url": "https://pontofato.com/enderecos/",
        "formats": {
          "html": "https://pontofato.com/enderecos/",
          "json": "https://api.pontofato.com/enderecos/index.json",
          "md": "https://api.pontofato.com/enderecos/index.md",
          "okf": "https://api.pontofato.com/enderecos/index.okf.md"
        },
        "llms": "https://api.pontofato.com/enderecos/llms.txt",
        "openapi": "https://api.pontofato.com/enderecos/openapi.json",
        "mcp": "https://api.pontofato.com/enderecos/mcp",
        "okf": "https://api.pontofato.com/enderecos/okf/index.md",
        "access": "public-read-only",
        "pagination": {
          "max_items": 20,
          "next": "links.proximo"
        },
        "updates": "manual"
      },
      {
        "id": "editais",
        "produto": "https://editalmd.com",
        "caminho": "/licitacoes",
        "title": "Public procurement",
        "description": "Find public procurement by location and date. View documents and reading options in EditalMD. Each HTML page opens the product app with its public data already rendered.",
        "hierarchy": "Procedure → state → year → month → day → municipality → purchases",
        "url": "https://editalmd.com/licitacoes/",
        "formats": {
          "html": "https://editalmd.com/licitacoes/",
          "json": "https://api.editalmd.com/licitacoes/index.json",
          "md": "https://api.editalmd.com/licitacoes/index.md",
          "okf": "https://api.editalmd.com/licitacoes/index.okf.md"
        },
        "llms": "https://api.editalmd.com/licitacoes/llms.txt",
        "openapi": "https://api.editalmd.com/licitacoes/openapi.json",
        "mcp": "https://api.editalmd.com/licitacoes/mcp",
        "okf": "https://api.editalmd.com/licitacoes/okf/index.md",
        "access": "public-read-only",
        "pagination": {
          "max_items": 20,
          "next": "links.proximo"
        },
        "updates": "manual"
      }
    ],
    "local_monitor": {
      "download": "https://staging.agentalog.com/downloads/mat-monitor-0.4.2.mjs",
      "manifesto": "https://staging.agentalog.com/downloads/mat-monitor-0.4.2.mjs.json",
      "versao": "0.4.2",
      "comandos": [
        "preview",
        "init",
        "scan",
        "outbox",
        "status",
        "connect",
        "sync",
        "policy",
        "check",
        "hooks-preview",
        "hooks-install",
        "hooks-remove",
        "hooks-status"
      ],
      "requisitos": [
        "Node.js 26",
        "Linux and /usr/bin/flock for local state"
      ],
      "modo": "private_sync",
      "envia_dados": true,
      "envio": "sync sends persisted metadata batches after preview consent. Installing hooks with auto delivery also permits bounded sends on native session events and Stop. Choose manual delivery to require explicit sync.",
      "aprova": false,
      "bloqueia": true,
      "bloqueio_universal": false,
      "hooks": {
        "agente": "Claude Code",
        "modos": [
          "observe",
          "enforce"
        ],
        "padrao": "observe",
        "escopo": "Covered native calls with installed project hooks and an exact current signed policy.",
        "limites": "Disabled hooks, a missing executable or an outer timeout can allow the native action. MCP startup, arbitrary processes and network traffic remain outside this control."
      },
      "revalida": true,
      "consulta_eventos": {
        "opcional": true,
        "autoridade": "One project's event GET only. No ingest, approval, purchase or credential management.",
        "emissao": "Sign in again, then open Mine > API access. Keep the one-time download private.",
        "chaves_ativas_maximas": 3,
        "validade_segundos": 2592000,
        "revogavel": true
      },
      "webhook": {
        "opcional": true,
        "emissao": "Sign in again, then open Mine > Change webhook. Create a public HTTPS destination and keep the signing-key download private.",
        "destinos_ativos_maximos": 1,
        "validade_segundos": 2592000,
        "assinatura": "Standard Webhooks",
        "tentativas_maximas": 6,
        "deduplicacao": "Verify the signature and timestamp, then deduplicate webhook-id before any effect.",
        "recuperacao": "Read missing committed events through the project cursor.",
        "revogavel": true
      },
      "politica": {
        "assinatura": "Ed25519",
        "validade_maxima_segundos": 900,
        "chave_fixa_no_cliente": true
      }
    }
  },
  "endpoints": [
    {
      "method": "GET",
      "path": "/agent.json",
      "auth": "none",
      "summary": "Agent card: identity, operator, documentation, the MCP endpoint and the tools it serves. Same document as `/.well-known/agent-card.json`.",
      "grupo": "Discovery",
      "retorno": {
        "_texto": "`application/json`: `name`, `provider`, `protocol` (`mcp`), `interfaces[]` and `skills[]`."
      },
      "exemplo": "curl -s $ORIGIN/agent.json",
      "returns": "`application/json`: `name`, `provider`, `protocol` (`mcp`), `interfaces[]` and `skills[]`.",
      "url": "https://staging.agentalog.com/agent.json",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/okf/:arquivo",
      "auth": "none",
      "summary": "OKF bundle (Open Knowledge Format v0.1): markdown with frontmatter so an agent reads the whole product without parsing HTML.",
      "grupo": "Discovery",
      "params": {
        "arquivo": {
          "desc": "`index.md`, `sobre.md`, `api.md` or `faq.md`.",
          "exemplo": "index.md"
        }
      },
      "retorno": {
        "_texto": "`text/markdown`. Start at `/okf/index.md`, which lists the bundle."
      },
      "erros": {
        "404": "File outside the bundle."
      },
      "exemplo": "curl -s $ORIGIN/okf/index.md",
      "returns": "`text/markdown`. Start at `/okf/index.md`, which lists the bundle.",
      "url": "https://staging.agentalog.com/okf/:arquivo",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/.well-known/:arquivo",
      "auth": "none",
      "summary": "Machine discovery before the home page: `api-catalog` (RFC 9727, a linkset with the API and the MCP), `security.txt` (RFC 9116), `x402` (payment manifest: network, wallet and the routes that charge) and `mcp-registry-auth` (the official MCP registry key).",
      "grupo": "Discovery",
      "params": {
        "arquivo": {
          "desc": "`api-catalog`, `security.txt`, `x402`, `mcp-registry-auth` or `apis.json`.",
          "exemplo": "api-catalog"
        }
      },
      "retorno": {
        "_texto": "`application/linkset+json` for the api-catalog; `application/json` for x402 and apis.json; `text/plain` for the other two."
      },
      "erros": {
        "404": "Name outside the five published."
      },
      "exemplo": "curl -s $ORIGIN/.well-known/api-catalog",
      "returns": "`application/linkset+json` for the api-catalog; `application/json` for x402 and apis.json; `text/plain` for the other two.",
      "url": "https://staging.agentalog.com/.well-known/:arquivo",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/apis.json",
      "auth": "none",
      "summary": "APIs.json (apisjson.org, 0.19): the index APIs.io harvests — the API, the MCP, OpenAPI, guide and OKF bundle in one file. Also at `/.well-known/apis.json`.",
      "grupo": "Discovery",
      "retorno": {
        "_texto": "`application/json` in the APIs.json 0.19 format: `apis[]` with `baseURL`, `humanURL` and `properties[]`."
      },
      "exemplo": "curl -s $ORIGIN/apis.json",
      "returns": "`application/json` in the APIs.json 0.19 format: `apis[]` with `baseURL`, `humanURL` and `properties[]`.",
      "url": "https://staging.agentalog.com/apis.json",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/feed.xml",
      "auth": "none",
      "summary": "RSS 2.0 of the most recently published listings.",
      "grupo": "Discovery",
      "retorno": {
        "_texto": "`application/rss+xml`."
      },
      "exemplo": "curl -s $ORIGIN/feed.xml",
      "returns": "`application/rss+xml`.",
      "url": "https://staging.agentalog.com/feed.xml",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/feed.json",
      "auth": "none",
      "summary": "JSON Feed 1.1 of the most recently published listings — the same stream as the RSS.",
      "grupo": "Discovery",
      "retorno": {
        "_texto": "`application/feed+json`."
      },
      "exemplo": "curl -s $ORIGIN/feed.json",
      "returns": "`application/feed+json`.",
      "url": "https://staging.agentalog.com/feed.json",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/",
      "auth": "none",
      "summary": "Self-describing index: the whole API surface, with quota and quickstart.",
      "grupo": "Discovery",
      "retorno": {
        "name": {
          "tipo": "string",
          "desc": "Product name."
        },
        "description": {
          "tipo": "string",
          "desc": "What the registry is and what it is not."
        },
        "auth": {
          "tipo": "object",
          "desc": "Each authentication mode and how to obtain it."
        },
        "docs": {
          "tipo": "object",
          "desc": "Links to llms.txt, llms-full.txt, openapi.json, MCP and the UI."
        },
        "endpoints": {
          "tipo": "object[]",
          "desc": "Every endpoint with method, path, auth, absolute URL and what it returns."
        },
        "quota": {
          "tipo": "object",
          "desc": "What is free, what costs and how to pay — before you spend a call."
        },
        "mcp": {
          "tipo": "object",
          "desc": "Address and transport of the MCP server."
        },
        "quickstart": {
          "tipo": "string[]",
          "desc": "The calls that take you from zero to the first published listing."
        }
      },
      "returns": "{ name, description, auth, docs, endpoints, quota, mcp, quickstart }",
      "url": "https://staging.agentalog.com/api/",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/health",
      "auth": "none",
      "summary": "Liveness and the commit deployed right now — it is how the smoke waits for its own deploy.",
      "grupo": "Discovery",
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true` when the Worker answers."
        },
        "app": {
          "tipo": "string",
          "desc": "Product name."
        },
        "build": {
          "tipo": "string",
          "desc": "Deployed commit; CI passes the short SHA on deploy."
        },
        "ts": {
          "tipo": "string",
          "desc": "Time of the response (UTC, ISO-8601)."
        }
      },
      "returns": "{ ok, app, build, ts }",
      "url": "https://staging.agentalog.com/api/health",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/mcp",
      "auth": "none",
      "summary": "MCP server over HTTP (Streamable HTTP, JSON-RPC 2.0) — plugs into the client with nothing to install.",
      "grupo": "Discovery",
      "desc": "The tools are the operations of this same catalog; the MCP has no backend of its own. `GET /mcp` returns the server card.",
      "retorno": {
        "_texto": "JSON-RPC 2.0 response (`initialize`, `tools/list` or `tools/call`)."
      },
      "notes": [
        "Credentials go in the usual headers (X-Guest-Token, Authorization, X-PAYMENT) and are forwarded to the API.",
        "An exhausted quota comes back as a 402 with accepts[] inside the tool result — pay and repeat."
      ],
      "exemplo": "curl -s -XPOST $ORIGIN/mcp -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}'",
      "returns": "JSON-RPC 2.0 response (`initialize`, `tools/list` or `tools/call`).",
      "url": "https://staging.agentalog.com/mcp",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/guest",
      "auth": "none",
      "summary": "Creates a guest `mr_…` — it is the identity that likes, comments and visits.",
      "grupo": "Identity",
      "desc": "Asks for no e-mail. Publishing a listing is what requires an account (or a payment). At most 20 new guests per network per hour; a browser that already has one gets it back from the `mr_guest` cookie.",
      "retorno": {
        "token": {
          "tipo": "string",
          "desc": "The guest, prefix `mr_`. Send it in `X-Guest-Token` or as Bearer."
        }
      },
      "erros": {
        "429": "More than 20 new guests from the same network in the hour.",
        "503": "auth_unavailable"
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/guest",
      "returns": "{ token }",
      "url": "https://staging.agentalog.com/api/guest",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/listings",
      "auth": "none",
      "colecao": {
        "porPagina": 50,
        "anda": "next"
      },
      "summary": "The public mosaic: paginated search of the catalog's listings, the lower-signal tail last.",
      "grupo": "Catalog",
      "desc": "MCP servers with an active verification seal first (`verified`); `trusted=1` lists only them, and `warning` marks a page with listings that Agentalog does not check every day. Then `live` listings and the `low` tail (few stars or no clear license) after them in every order — `low=0` leaves the tail out. To walk everything, follow `next`: without `q` it is a cursor (`next_cursor`, keyset on the order's index) and has no ceiling; every listing also has an HTML page at `/l/:id` and the shards of `/sitemap-listings.xml` list them all. `q` runs on a full-text index (FTS5, bm25) kept in the same transaction as every text write. With `q` and `low=0`, `low_count` says how many `low` listings the filter left out — LIKE with a cap of 200. The query is mapped onto kind/topic/transport filters unless `interpret=0`.",
      "query": {
        "q": {
          "tipo": "string",
          "desc": "Free text over the name, the tagline, the description, the origin identifier and the README excerpt: every word (up to six, 2+ letters, accents ignored) must match; ranked by bm25 with the name weighing most (10), then tagline (5), identifier (3), description (2), README excerpt (1); ties by stars. Kind, topic and transport words become filters. The `low` tail is in the same index.",
          "exemplo": "browser testing"
        },
        "interpret": {
          "tipo": "string",
          "desc": "`0` disables query understanding and searches the raw string.",
          "valores": [
            "0"
          ]
        },
        "kind": {
          "tipo": "string",
          "desc": "Which kind of resource to fetch.",
          "valores": [
            "mcp",
            "skill",
            "plugin"
          ]
        },
        "category": {
          "tipo": "string",
          "desc": "Category declared by whoever published."
        },
        "sort": {
          "tipo": "string",
          "desc": "Result order. Without it, a query is ranked by relevance — bm25 over the full-text index (name 10, tagline 5, identifier 3, description 2, README excerpt 1) multiplied by 1 + 0.05·ln(1 + stars) + 0.1 if pushed in the last 180 days + 0.1 if a README was collected; ties by stars — and a plain listing by arrival.",
          "valores": [
            "relevancia",
            "recent",
            "stars",
            "likes",
            "visits",
            "nome"
          ],
          "padrao": "relevancia when q is set, recent otherwise"
        },
        "low": {
          "tipo": "string",
          "desc": "`0` leaves the `low` tail out; by default it comes after the `live` listings in every order.",
          "valores": [
            "0"
          ]
        },
        "trusted": {
          "tipo": "string",
          "desc": "`1` lists only the MCP servers with an active verification seal. By default, every listing comes, the verified ones first; `all=1` is the same as `0`.",
          "valores": [
            "0",
            "1"
          ]
        },
        "all": {
          "tipo": "string",
          "desc": "`1` lists every listing, with verified ones first; it is the same as `trusted=0`.",
          "valores": [
            "1"
          ]
        },
        "cursor": {
          "tipo": "string",
          "desc": "Opaque cursor from `next_cursor` of the previous page (orders `recent`, `stars` and `nome`, without `q`). With it, `offset` is ignored. A cursor from another order or a malformed one restarts at the first page."
        },
        "limit": {
          "tipo": "int",
          "desc": "Listings per page.",
          "padrao": 24
        },
        "offset": {
          "tipo": "int",
          "desc": "How many listings to skip. No ceiling since 2026-09-13, but the database reads every skipped row: to walk the catalog, follow `next` (cursor) instead.",
          "padrao": 0
        },
        "language": {
          "tipo": "string",
          "desc": "Repository code languages, comma-separated. Preserve case, for example Python."
        },
        "license": {
          "tipo": "string",
          "desc": "Repository licenses, comma-separated, for example MIT,Apache-2.0. Preserve case."
        },
        "min_stars": {
          "tipo": "int",
          "desc": "Minimum repository stars, from 0 to 999999999."
        },
        "min_forks": {
          "tipo": "int",
          "desc": "Minimum forks of a repository with collected activity data."
        },
        "min_prs": {
          "tipo": "int",
          "desc": "Minimum open pull requests of a repository with collected activity data."
        },
        "max_prs": {
          "tipo": "int",
          "desc": "Maximum open pull requests of a repository with collected activity data."
        },
        "added_since": {
          "tipo": "string",
          "desc": "Catalog arrival on or after YYYY-MM-DD. This is not the original publication date."
        },
        "pushed_since": {
          "tipo": "string",
          "desc": "Last repository code push on or after YYYY-MM-DD."
        },
        "has_code": {
          "tipo": "string",
          "desc": "Whether a repository link is available. This does not certify the code.",
          "valores": [
            "0",
            "1"
          ]
        }
      },
      "retorno": "PaginaDeAnuncios",
      "exemplo": "curl -s '$ORIGIN/api/listings?kind=mcp&sort=likes&limit=5'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "returns": "{ items[{seguranca_nivel?,seguranca_estado?,seguranca_api?,moderation?,verified?,seals?,seal_checked_at?,id,kind,category,name,tagline,body,url,status,origin,origin_id,install,source,transporte,ns,versao,oficial_status,repo_host,topico,linguagem,licenca,repo_topics,repo_slug,stars,forks,prs_abertos,pushed_at,repo_estado,likes,comments,visits,created_at,updated_at,mine,api,go,comments_api,readme_api?,historico?,readme_fonte?,readme_bytes,readme_sha,readme_em,docs_url?,payload}], limit, offset, next_offset, next_cursor, next, low_count, low_capped, low_included, interpretacao, trust?, warning?, all?, api }",
      "url": "https://staging.agentalog.com/api/listings",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/facets",
      "auth": "none",
      "summary": "The whole catalog's counts by kind, provenance, category and repository state.",
      "grupo": "Catalog",
      "query": {
        "q": {
          "tipo": "string",
          "desc": "The same text query as /api/listings."
        },
        "kind": {
          "tipo": "string",
          "desc": "Resource kind."
        },
        "language": {
          "tipo": "string",
          "desc": "Repository code languages, comma-separated. Preserve case, for example Python."
        },
        "license": {
          "tipo": "string",
          "desc": "Repository licenses, comma-separated, for example MIT,Apache-2.0. Preserve case."
        },
        "min_stars": {
          "tipo": "int",
          "desc": "Minimum repository stars, from 0 to 999999999."
        },
        "min_forks": {
          "tipo": "int",
          "desc": "Minimum forks of a repository with collected activity data."
        },
        "min_prs": {
          "tipo": "int",
          "desc": "Minimum open pull requests of a repository with collected activity data."
        },
        "max_prs": {
          "tipo": "int",
          "desc": "Maximum open pull requests of a repository with collected activity data."
        },
        "added_since": {
          "tipo": "string",
          "desc": "Catalog arrival on or after YYYY-MM-DD. This is not the original publication date."
        },
        "pushed_since": {
          "tipo": "string",
          "desc": "Last repository code push on or after YYYY-MM-DD."
        },
        "has_code": {
          "tipo": "string",
          "desc": "Whether a repository link is available. This does not certify the code.",
          "valores": [
            "0",
            "1"
          ]
        }
      },
      "desc": "Exists to build a filter without sweeping the listings: there are tens of thousands, and asking for the list just to count would be expensive. Each dimension ignores its own selection and respects the other filters. These counts describe the search. For catalog tab totals, use the unfiltered response. Language and license come from repository metadata. Also brings `topico_inferido`, deduced from the repositories.",
      "retorno": "Facetas",
      "exemplo": "curl -s $ORIGIN/api/facets",
      "returns": "{ total, facetas, topico_inferido, interpretacao, publicador?, api }",
      "url": "https://staging.agentalog.com/api/facets",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/v0.1/servers",
      "auth": "none",
      "summary": "MCP subregistry in the Official Registry format (spec v0.1), cursor-paginated.",
      "grupo": "Catalog",
      "desc": "Only `kind=mcp` and only `live`, verified servers first, each with its seals in `_meta`. A generic MCP client reads it without knowing this product. `GET /v0/servers` is an alias of the same resource, kept for whoever already pointed there — this is the canonical URL.",
      "query": {
        "search": {
          "tipo": "string",
          "desc": "Free text over the server's name and description."
        },
        "cursor": {
          "tipo": "string",
          "desc": "Opaque cursor of the next page, from `metadata.nextCursor`."
        },
        "limit": {
          "tipo": "int",
          "desc": "Servers per page.",
          "padrao": 30
        }
      },
      "retorno": "PaginaV01",
      "exemplo": "curl -s '$ORIGIN/v0.1/servers?search=postgres&limit=5'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "returns": "{ servers[{name,description,version,repository,remotes,packages}], metadata }",
      "url": "https://staging.agentalog.com/v0.1/servers",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id",
      "auth": "none",
      "summary": "One listing's page. The owner sees their own even when pending or hidden.",
      "grupo": "Catalog",
      "params": {
        "id": {
          "desc": "Listing ID, from `Anuncio.id`."
        }
      },
      "retorno": "Anuncio",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "The listing does not exist, or it is not yours and is not live/low.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/listings/ID",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ seguranca_nivel?, seguranca_estado?, seguranca_api?, moderation?, verified?, seals?, seal_checked_at?, id, kind, category, name, tagline, body, url, status, origin, origin_id, install, source, transporte, ns, versao, oficial_status, repo_host, topico, linguagem, licenca, repo_topics, repo_slug, stars, forks, prs_abertos, pushed_at, repo_estado, likes, comments, visits, created_at, updated_at, mine, api, go, comments_api, readme_api?, historico?, readme_fonte?, readme_bytes, readme_sha, readme_em, docs_url?, payload }",
      "url": "https://staging.agentalog.com/api/listings/:id",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/seals",
      "auth": "none",
      "summary": "Lists the verification seal types, plans and the signed-in owner's seal projects.",
      "grupo": "Trust",
      "retorno": {
        "seals": {
          "tipo": "object[]",
          "desc": "Available seal identifiers and icons."
        },
        "plans": {
          "tipo": "object[]",
          "desc": "The seal-pass offers and their purchase URLs."
        },
        "mine": {
          "tipo": "object[]",
          "desc": "The signed-in owner's seal projects, or null without an account.",
          "nulo": true
        }
      },
      "erros": {},
      "exemplo": "curl -s $ORIGIN/api/seals",
      "returns": "{ seals, plans, mine }",
      "url": "https://staging.agentalog.com/api/seals",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/seals/:id",
      "auth": "none",
      "summary": "Read the verification seal state of one MCP listing.",
      "grupo": "Catalog",
      "desc": "Public seal status for a listing. The owner also sees the proof, the approved and current readings, the selected seals and the available cancellation details.",
      "query": {
        "lingua": {
          "tipo": "string",
          "desc": "Language of cancellation details: `pt`; English is the default.",
          "valores": [
            "pt"
          ]
        }
      },
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "retorno": {
        "listing_id": {
          "tipo": "string",
          "desc": "The requested MCP listing ID."
        },
        "verified": {
          "tipo": "bool",
          "desc": "True when the active pass and every chosen seal agree with its reference."
        },
        "state": {
          "tipo": "string",
          "desc": "Current public seal state, or `none` when no pass is visible."
        },
        "checked_at": {
          "tipo": "string",
          "desc": "Last complete seal check in ISO 8601, or null.",
          "nulo": true
        },
        "seals": {
          "tipo": "object[]",
          "desc": "The selected seals and their latest state."
        },
        "_links": {
          "tipo": "object",
          "desc": "Links to this seal response and the listing page."
        },
        "eligible": {
          "tipo": "bool",
          "desc": "Whether the listing can use a seal pass."
        },
        "possible": {
          "tipo": "string[]",
          "desc": "Seal identifiers available for this listing, or null.",
          "nulo": true
        },
        "not_offered": {
          "tipo": "object",
          "desc": "Why a possible seal is not offered, or null.",
          "nulo": true
        },
        "plan": {
          "tipo": "object",
          "desc": "The seal-pass offer, or null when unavailable.",
          "nulo": true
        },
        "protection_plan": {
          "tipo": "object",
          "desc": "The protection offer, or null when unavailable.",
          "nulo": true
        },
        "owner": {
          "tipo": "bool",
          "desc": "True when the authenticated account controls the listing and owns the seal pass.",
          "opcional": true
        },
        "payer": {
          "tipo": "bool",
          "desc": "True when the authenticated account paid the active pass but does not control the listing.",
          "opcional": true
        },
        "chosen": {
          "tipo": "string[]",
          "desc": "Seal identifiers selected by the owner.",
          "opcional": true
        },
        "valid_until": {
          "tipo": "string",
          "desc": "The active pass expiry in ISO 8601 for the owner or original payer, or null.",
          "nulo": true,
          "opcional": true
        },
        "proof": {
          "tipo": "object",
          "desc": "Proof instructions while the owner's claim is pending.",
          "opcional": true
        },
        "cancel": {
          "tipo": "object",
          "desc": "Cancellation and refund details for the owner's or original payer's active pass.",
          "opcional": true
        },
        "can_simulate": {
          "tipo": "bool",
          "desc": "True only when the dev payment simulation is enabled.",
          "opcional": true
        }
      },
      "erros": {
        "404": "The path is not a valid MCP listing ID."
      },
      "exemplo": "curl -s '$ORIGIN/api/seals/mcp_9f3c2b1d7a4e58b0c2d4?lingua=pt'",
      "returns": "{ listing_id, verified, state, checked_at, seals, _links, eligible, possible, not_offered, plan, protection_plan, owner?, payer?, chosen?, valid_until?, proof?, cancel?, can_simulate? }",
      "url": "https://staging.agentalog.com/api/seals/:id",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/seals/:id/claim",
      "auth": "session",
      "summary": "Starts or restarts the ownership proof for an MCP listing.",
      "grupo": "Trust",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "retorno": {
        "listing_id": {
          "tipo": "string",
          "desc": "The requested MCP listing ID."
        },
        "verified": {
          "tipo": "bool",
          "desc": "True when the active pass and every chosen seal agree with its reference."
        },
        "state": {
          "tipo": "string",
          "desc": "Current public seal state, or `none` when no pass is visible."
        },
        "checked_at": {
          "tipo": "string",
          "desc": "Last complete seal check in ISO 8601, or null.",
          "nulo": true
        },
        "seals": {
          "tipo": "object[]",
          "desc": "The selected seals and their latest state. The owner also receives the complete `reference` and `current` readings with the matching `reference_hash` and `current_hash`."
        },
        "_links": {
          "tipo": "object",
          "desc": "Links to this seal response and the listing page."
        },
        "owner": {
          "tipo": "bool",
          "desc": "True for the account that owns this pending claim."
        },
        "chosen": {
          "tipo": "string[]",
          "desc": "Selected seal identifiers; empty until the pass is bought."
        },
        "valid_until": {
          "tipo": "string",
          "desc": "Pass expiry, or empty while proof is pending."
        },
        "proof": {
          "tipo": "object",
          "desc": "The line and DNS/HTTPS locations to prove control."
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "404": "The path is not a valid MCP listing ID.",
        "409": "The listing is not eligible for a seal."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/seals/mcp_9f3c2b1d7a4e58b0c2d4/claim\"",
      "returns": "{ listing_id, verified, state, checked_at, seals, _links, owner, chosen, valid_until, proof }",
      "url": "https://staging.agentalog.com/api/seals/:id/claim",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/seals/:id/prove",
      "auth": "session",
      "summary": "Confirms the ownership proof published by the MCP listing.",
      "grupo": "Trust",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "corpo": {
        "simulate": {
          "tipo": "bool",
          "desc": "In the dev payment simulation only, accept the synthetic proof without publishing the line."
        }
      },
      "body": {
        "simulate": true
      },
      "retorno": {
        "listing_id": {
          "tipo": "string",
          "desc": "The requested MCP listing ID."
        },
        "verified": {
          "tipo": "bool",
          "desc": "True when the active pass and every chosen seal agree with its reference."
        },
        "state": {
          "tipo": "string",
          "desc": "Current public seal state, or `none` when no pass is visible."
        },
        "checked_at": {
          "tipo": "string",
          "desc": "Last complete seal check in ISO 8601, or null.",
          "nulo": true
        },
        "seals": {
          "tipo": "object[]",
          "desc": "The selected seals and their latest state. The owner also receives the complete `reference` and `current` readings with the matching `reference_hash` and `current_hash`."
        },
        "_links": {
          "tipo": "object",
          "desc": "Links to this seal response and the listing page."
        },
        "proved_by": {
          "tipo": "string",
          "desc": "The proof channel: `well_known`, `dns` or `simulated`."
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "404": "The path is not a valid MCP listing ID.",
        "409": "The claim or proof is missing."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/seals/mcp_9f3c2b1d7a4e58b0c2d4/prove\" -H \"content-type: application/json\" -d '{\"simulate\":true}'",
      "returns": "{ listing_id, verified, state, checked_at, seals, _links, proved_by }",
      "url": "https://staging.agentalog.com/api/seals/:id/prove",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/seals/:id/buy",
      "auth": "session",
      "summary": "Buys the 30-day verification pass for the selected seals.",
      "grupo": "Trust",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "corpo": {
        "seals": {
          "tipo": "string[]",
          "desc": "Seal identifiers to check: `codigo`, `dns`, `ip`, `tls` or `dominio`."
        }
      },
      "body": {
        "seals": [
          "dns",
          "tls"
        ]
      },
      "retorno": {
        "listing_id": {
          "tipo": "string",
          "desc": "The requested MCP listing ID."
        },
        "verified": {
          "tipo": "bool",
          "desc": "True when the active pass and every chosen seal agree with its reference."
        },
        "state": {
          "tipo": "string",
          "desc": "Current public seal state, or `none` when no pass is visible."
        },
        "checked_at": {
          "tipo": "string",
          "desc": "Last complete seal check in ISO 8601, or null.",
          "nulo": true
        },
        "seals": {
          "tipo": "object[]",
          "desc": "The selected seals and their latest state. The owner also receives the complete `reference` and `current` readings with the matching `reference_hash` and `current_hash`."
        },
        "_links": {
          "tipo": "object",
          "desc": "Links to this seal response and the listing page."
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "402": "Payment is required through x402 or prepaid credit.",
        "404": "The path is not a valid MCP listing ID.",
        "409": "The listing has no completed proof or cannot use the requested seals."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/seals/mcp_9f3c2b1d7a4e58b0c2d4/buy\" -H \"content-type: application/json\" -d '{\"seals\":[\"dns\",\"tls\"]}'",
      "returns": "{ listing_id, verified, state, checked_at, seals, _links }",
      "url": "https://staging.agentalog.com/api/seals/:id/buy",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "PUT",
      "path": "/api/seals/:id",
      "auth": "session",
      "summary": "Changes the selected seals or approves the current readings.",
      "grupo": "Trust",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "corpo": {
        "seals": {
          "tipo": "string[]",
          "desc": "New seal identifiers; omitted to keep the current selection."
        },
        "approve": {
          "tipo": "string[]",
          "desc": "Seal identifiers whose current reading becomes the approved reference, or `all`."
        },
        "expected_hash": {
          "tipo": "object",
          "desc": "Map of approved seal identifiers to the hash shown in the owner's current reading. Required when `approve` names seals or is `all`; every approved reading must match before the atomic update.",
          "opcional": true
        }
      },
      "body": {
        "seals": [
          "dns",
          "tls"
        ],
        "approve": [
          "dns"
        ],
        "expected_hash": {
          "dns": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
        }
      },
      "retorno": {
        "listing_id": {
          "tipo": "string",
          "desc": "The requested MCP listing ID."
        },
        "verified": {
          "tipo": "bool",
          "desc": "True when the active pass and every chosen seal agree with its reference."
        },
        "state": {
          "tipo": "string",
          "desc": "Current public seal state, or `none` when no pass is visible."
        },
        "checked_at": {
          "tipo": "string",
          "desc": "Last complete seal check in ISO 8601, or null.",
          "nulo": true
        },
        "seals": {
          "tipo": "object[]",
          "desc": "The selected seals and their latest state. The owner also receives the complete `reference` and `current` readings with the matching `reference_hash` and `current_hash`."
        },
        "_links": {
          "tipo": "object",
          "desc": "Links to this seal response and the listing page."
        }
      },
      "erros": {
        "400": "An approval hash is missing or is not a SHA-256 hex string.",
        "401": "A signed-in account is required.",
        "404": "The path is not a valid MCP listing ID.",
        "409": "An active or reviewable seal pass is required, or a seal changed after the owner read it."
      },
      "exemplo": "curl -s -XPUT \"$ORIGIN/api/seals/mcp_9f3c2b1d7a4e58b0c2d4\" -H \"content-type: application/json\" -d '{\"approve\":[\"dns\"],\"expected_hash\":{\"dns\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}}'",
      "returns": "{ listing_id, verified, state, checked_at, seals, _links }",
      "url": "https://staging.agentalog.com/api/seals/:id",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/seals/:id/check",
      "auth": "session",
      "summary": "Runs a seal check for the owner's listing.",
      "grupo": "Trust",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "retorno": {
        "listing_id": {
          "tipo": "string",
          "desc": "The requested MCP listing ID."
        },
        "verified": {
          "tipo": "bool",
          "desc": "True when the active pass and every chosen seal agree with its reference."
        },
        "state": {
          "tipo": "string",
          "desc": "Current public seal state, or `none` when no pass is visible."
        },
        "checked_at": {
          "tipo": "string",
          "desc": "Last complete seal check in ISO 8601, or null.",
          "nulo": true
        },
        "seals": {
          "tipo": "object[]",
          "desc": "The selected seals and their latest state. The owner also receives the complete `reference` and `current` readings with the matching `reference_hash` and `current_hash`."
        },
        "_links": {
          "tipo": "object",
          "desc": "Links to this seal response and the listing page."
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "404": "The path is not a valid MCP listing ID.",
        "409": "An active or reviewable seal pass is required.",
        "429": "The listing was checked less than five minutes ago."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/seals/mcp_9f3c2b1d7a4e58b0c2d4/check\"",
      "returns": "{ listing_id, verified, state, checked_at, seals, _links }",
      "url": "https://staging.agentalog.com/api/seals/:id/check",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/seals/:id/cancel",
      "auth": "session",
      "summary": "Cancels a seal pass and returns its refund or paid-through date.",
      "grupo": "Trust",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "retorno": {
        "cancelled": {
          "tipo": "bool",
          "desc": "True when a pass ended or remains paid through a date."
        },
        "refund": {
          "tipo": "object",
          "desc": "Refund details, or null.",
          "nulo": true
        },
        "ended": {
          "tipo": "int",
          "desc": "Number of rights ended now."
        },
        "keeps_until": {
          "tipo": "string",
          "desc": "Paid-through date when the payment is not refundable, or null.",
          "nulo": true
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "404": "The path is not a valid MCP listing ID, or the account has no seal pass on this listing."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/seals/mcp_9f3c2b1d7a4e58b0c2d4/cancel\"",
      "returns": "{ cancelled, refund, ended, keeps_until }",
      "url": "https://staging.agentalog.com/api/seals/:id/cancel",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/protection",
      "auth": "session",
      "summary": "Reads the account's protection pass, quota, protected servers and pending tools.",
      "grupo": "Protection",
      "query": {
        "lingua": {
          "tipo": "string",
          "desc": "Language of cancellation details: `pt`; English is the default.",
          "valores": [
            "pt"
          ]
        }
      },
      "retorno": {
        "plan": {
          "tipo": "object",
          "desc": "The protection-pass offer."
        },
        "slot": {
          "tipo": "object",
          "desc": "The extra protected-server offer."
        },
        "quota": {
          "tipo": "object",
          "desc": "Total, used, free and plan-derived protection slots."
        },
        "active": {
          "tipo": "object",
          "desc": "The active pass and cancellation result, or null.",
          "nulo": true
        },
        "services": {
          "tipo": "object[]",
          "desc": "Protected MCP listings. Each pending item includes `tool`, `kind`, `seen_at`, `hash` (SHA-256) and `hash_input` (the complete text hashed for approval)."
        },
        "_links": {
          "tipo": "object",
          "desc": "Links to protection and account API-key management."
        }
      },
      "erros": {
        "401": "A signed-in account is required."
      },
      "exemplo": "curl -s '$ORIGIN/api/protection?lingua=pt'",
      "returns": "{ plan, slot, quota, active, services, _links }",
      "url": "https://staging.agentalog.com/api/protection",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/protection/buy",
      "auth": "session",
      "summary": "Buys the 30-day protection pass for ten MCP servers.",
      "grupo": "Protection",
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "True when the pass was bought."
        },
        "valid_until": {
          "tipo": "string",
          "desc": "Pass expiry, or null."
        },
        "automatic_renewal": {
          "tipo": "bool",
          "desc": "Always false; the pass does not renew automatically."
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "402": "Payment is required through x402 or prepaid credit.",
        "409": "A protection pass is already active, or another protection purchase is in progress.",
        "503": "Protection is temporarily unavailable."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/protection/buy\"",
      "returns": "{ ok, valid_until, automatic_renewal }",
      "url": "https://staging.agentalog.com/api/protection/buy",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/protection/cancel",
      "auth": "session",
      "summary": "Cancels the account protection pass.",
      "grupo": "Protection",
      "retorno": {
        "cancelled": {
          "tipo": "bool",
          "desc": "True when a pass ended or remains paid through a date."
        },
        "refund": {
          "tipo": "object",
          "desc": "Refund details, or null.",
          "nulo": true
        },
        "ended": {
          "tipo": "int",
          "desc": "Number of rights ended now."
        },
        "keeps_until": {
          "tipo": "string",
          "desc": "Paid-through date when the payment is not refundable, or null.",
          "nulo": true
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "409": "Another protection purchase is in progress.",
        "503": "Protection is temporarily unavailable."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/protection/cancel\"",
      "returns": "{ cancelled, refund, ended, keeps_until }",
      "url": "https://staging.agentalog.com/api/protection/cancel",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/protection/services",
      "auth": "session",
      "summary": "Adds a remote MCP listing to the account protection gateway.",
      "grupo": "Protection",
      "corpo": {
        "listing_id": {
          "tipo": "string",
          "desc": "The remote MCP listing ID, with the `mcp_` prefix.",
          "obrigatorio": true
        }
      },
      "body": {
        "listing_id": "mcp_9f3c2b1d7a4e58b0c2d4"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "True when the listing is protected."
        },
        "listing_id": {
          "tipo": "string",
          "desc": "The protected listing ID."
        },
        "gateway": {
          "tipo": "string",
          "desc": "The protected Streamable HTTP gateway URL."
        },
        "config": {
          "tipo": "object",
          "desc": "Claude Code and MCP JSON configuration using the account API key."
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "402": "A protection pass or extra slot is required through x402 or prepaid credit.",
        "404": "The path is not a valid MCP listing ID.",
        "409": "The listing is not a remote Streamable HTTP MCP server, asks for its own login, or another protection purchase is in progress.",
        "503": "Protection is temporarily unavailable."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/protection/services\" -H \"content-type: application/json\" -d '{\"listing_id\":\"mcp_9f3c2b1d7a4e58b0c2d4\"}'",
      "returns": "{ ok, listing_id, gateway, config }",
      "url": "https://staging.agentalog.com/api/protection/services",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "DELETE",
      "path": "/api/protection/services/:id",
      "auth": "session",
      "summary": "Removes one MCP listing from the account protection gateway.",
      "grupo": "Protection",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "True when the listing was removed."
        },
        "removed": {
          "tipo": "string",
          "desc": "The removed listing ID."
        }
      },
      "erros": {
        "401": "A signed-in account is required.",
        "404": "The path is not a valid MCP listing ID, or the listing is not protected by this account."
      },
      "exemplo": "curl -s -XDELETE \"$ORIGIN/api/protection/services/mcp_9f3c2b1d7a4e58b0c2d4\"",
      "returns": "{ ok, removed }",
      "url": "https://staging.agentalog.com/api/protection/services/:id",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/protection/services/:id/approve",
      "auth": "session",
      "summary": "Approves pending or changed tool definitions for one protected MCP listing.",
      "grupo": "Protection",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "corpo": {
        "tools": {
          "tipo": "string[]",
          "desc": "Tool names to approve; omit the list to approve all pending tools."
        },
        "expected_hashes": {
          "tipo": "object",
          "desc": "Map each selected tool name to the SHA-256 `hash` shown in the pending response. Required even when `tools` is omitted; a changed or missing hash returns 409 and approves none of the batch."
        }
      },
      "body": {
        "tools": [
          "search"
        ],
        "expected_hashes": {
          "search": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
        }
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "True when the approval was recorded."
        },
        "approved": {
          "tipo": "int",
          "desc": "Number of tool definitions approved."
        }
      },
      "erros": {
        "400": "The expected hash map is missing, incomplete or invalid.",
        "401": "A signed-in account is required.",
        "404": "The path is not a valid MCP listing ID, or the listing is not protected by this account.",
        "409": "A pending tool changed or disappeared after the owner read it; no tool in the batch was approved.",
        "503": "Protection is temporarily unavailable."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/api/protection/services/mcp_9f3c2b1d7a4e58b0c2d4/approve\" -H \"content-type: application/json\" -d '{\"tools\":[\"search\"],\"expected_hashes\":{\"search\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}}'",
      "returns": "{ ok, approved }",
      "url": "https://staging.agentalog.com/api/protection/services/:id/approve",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/g/:id/mcp",
      "auth": "token",
      "summary": "Proxies one protected remote MCP request through Agentalog's tool-definition guard.",
      "grupo": "Protection",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "desc": "Send the account API key in `X-Agentalog-Key`. The gateway forwards Streamable HTTP MCP POST requests, filters new or changed tools and pauses when the listing seal is in review. The origin accepts a request body up to 256 KiB and reads it for 15 seconds. This body-read deadline is separate from the gateway upstream timeout of 15 seconds. If no response bytes arrive, the origin socket can close after about 20 seconds.",
      "retorno": {
        "_texto": "The upstream MCP JSON-RPC response, or a guarded JSON-RPC error."
      },
      "erros": {
        "401": "The account API key is missing or invalid.",
        "402": "The account protection pass or quota does not cover this server.",
        "403": "The server is not protected by this account.",
        "404": "The path is not a valid MCP listing ID.",
        "409": "The listing is not a remote Streamable HTTP MCP server."
      },
      "exemplo": "curl -s -XPOST \"$ORIGIN/g/mcp_9f3c2b1d7a4e58b0c2d4/mcp\" -H \"X-Agentalog-Key: mmk_…\" -H \"content-type: application/json\" -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}'",
      "returns": "The upstream MCP JSON-RPC response, or a guarded JSON-RPC error.",
      "url": "https://staging.agentalog.com/g/:id/mcp",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "DELETE",
      "path": "/g/:id/mcp",
      "auth": "token",
      "summary": "Closes the protected remote MCP session through Agentalog's guard.",
      "grupo": "Protection",
      "params": {
        "id": {
          "desc": "MCP listing ID from `/api/listings`, with the `mcp_` prefix.",
          "exemplo": "mcp_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "desc": "Send the account API key in `X-Agentalog-Key`; the gateway forwards the MCP session deletion. The origin accepts a request body up to 256 KiB and reads it for 15 seconds. This body-read deadline is separate from the gateway upstream timeout of 15 seconds. If no response bytes arrive, the origin socket can close after about 20 seconds.",
      "retorno": {
        "_texto": "The upstream MCP response."
      },
      "erros": {
        "401": "The account API key is missing or invalid.",
        "403": "The server is not protected by this account.",
        "404": "The path is not a valid MCP listing ID."
      },
      "exemplo": "curl -s -XDELETE \"$ORIGIN/g/mcp_9f3c2b1d7a4e58b0c2d4/mcp\" -H \"X-Agentalog-Key: mmk_…\"",
      "returns": "The upstream MCP response.",
      "url": "https://staging.agentalog.com/g/:id/mcp",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id/readme",
      "auth": "none",
      "summary": "README collected from the listing's repository, served on open.",
      "grupo": "Catalog",
      "desc": "The text lives in R2 (`mural-coleta`). This call does not write and does not fetch GitHub. Same visibility as the listing page. Call it only when the listing page carries `readme_api`: a page without it has no README collected, and this route answers 404.",
      "params": {
        "id": {
          "desc": "Listing ID, from `Anuncio.id`."
        }
      },
      "retorno": "Readme",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "The listing does not exist, is not visible, or no README was collected.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/listings/ID/readme",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ markdown, bytes, sha, repo_slug, fonte, truncated, api }",
      "url": "https://staging.agentalog.com/api/listings/:id/readme",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/go/:id",
      "auth": "none",
      "summary": "Hop to the listing's URL: redirects and counts the visit.",
      "grupo": "Catalog",
      "desc": "Counts at most 1 visit per owner per day. The `X-Visit-Counted` header says whether this call counted — it is how the client knows without counting twice. A remote MCP server goes to its repository; without one, to the listing page `/l/:id`, which shows the endpoint to copy, and no visit counts.",
      "params": {
        "id": {
          "desc": "ID of the listing to visit.",
          "exemplo": "lst_9f3c2b1d7a4e58b0c2d4"
        }
      },
      "retorno": {
        "_texto": "`302` with `Location` to the listing's URL, and the `X-Visit-Counted` header."
      },
      "erros": {
        "404": "The listing does not exist or is not live/low."
      },
      "returns": "`302` with `Location` to the listing's URL, and the `X-Visit-Counted` header.",
      "url": "https://staging.agentalog.com/api/go/:id",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id/comments",
      "auth": "none",
      "summary": "Public comments on a live listing.",
      "grupo": "Community",
      "desc": "With a credential on the call, each comment of yours comes with `mine: true`.",
      "params": {
        "id": {
          "desc": "ID of the listing."
        }
      },
      "retorno": {
        "items": {
          "tipo": "Comentario[]",
          "desc": "The comments, newest first."
        },
        "total": {
          "tipo": "int",
          "desc": "How many comments the listing has."
        }
      },
      "erros": {
        "404": "The listing does not exist or is not live."
      },
      "exemplo": "curl -s $ORIGIN/api/listings/ID/comments",
      "returns": "{ items[{id,body,author,created_at,mine}], total }",
      "url": "https://staging.agentalog.com/api/listings/:id/comments",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/listings/:id/comments",
      "auth": "guest",
      "summary": "Writes a comment on the listing. Cap of 20 per hour per owner.",
      "grupo": "Community",
      "params": {
        "id": {
          "desc": "ID of the listing to comment on."
        }
      },
      "corpo": {
        "body": {
          "tipo": "string",
          "desc": "The comment text.",
          "obrigatorio": true
        }
      },
      "body": {
        "body": "text"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true` when the comment went in."
        },
        "id": {
          "tipo": "string",
          "desc": "ID of the created comment."
        },
        "body": {
          "tipo": "string",
          "desc": "The stored text."
        }
      },
      "erros": {
        "400": "Empty or too long text.",
        "401": null,
        "404": "The listing does not exist.",
        "429": "More than 20 comments in the hour."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/listings/ID/comments -H \"X-Guest-Token: $MR\" -H 'content-type: application/json' -d '{\"body\":\"works well with Claude Code\"}'",
      "returns": "{ ok, id, body }",
      "url": "https://staging.agentalog.com/api/listings/:id/comments",
      "auth_detail": "Guest token (`POST /api/guest`) in `X-Guest-Token: mr_…` or `Authorization: Bearer mr_…`. In the browser it also lives in the HttpOnly `mr_guest` cookie, which writes only from this site's exact Origin. A signed-in account (cookie) also works and takes precedence."
    },
    {
      "method": "DELETE",
      "path": "/api/comments/:id",
      "auth": "guest",
      "summary": "Deletes a comment of yours. Someone else's comment answers 404, not 403.",
      "grupo": "Community",
      "desc": "The 404 is on purpose: the API does not confirm that a comment with that id exists if it is not yours.",
      "params": {
        "id": {
          "desc": "Comment ID, from `Comentario.id`.",
          "exemplo": "cm_9f3c2b1d7a4e58b0c2"
        }
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true`."
        },
        "id": {
          "tipo": "string",
          "desc": "The id that was removed."
        }
      },
      "erros": [
        401,
        404
      ],
      "exemplo": "curl -s -XDELETE $ORIGIN/api/comments/CMT_ID -H \"X-Guest-Token: $MR\"",
      "returns": "{ ok, id }",
      "url": "https://staging.agentalog.com/api/comments/:id",
      "auth_detail": "Guest token (`POST /api/guest`) in `X-Guest-Token: mr_…` or `Authorization: Bearer mr_…`. In the browser it also lives in the HttpOnly `mr_guest` cookie, which writes only from this site's exact Origin. A signed-in account (cookie) also works and takes precedence."
    },
    {
      "method": "POST",
      "path": "/api/listings/:id/like",
      "auth": "guest",
      "summary": "Likes the listing; DELETE undoes it. Calling again does not add up: the counter counts people.",
      "grupo": "Community",
      "params": {
        "id": {
          "desc": "ID of the listing to like."
        }
      },
      "retorno": "Like",
      "erros": [
        401,
        404
      ],
      "exemplo": "curl -s -XPOST $ORIGIN/api/listings/ID/like -H \"X-Guest-Token: $MR\"",
      "returns": "{ ok, liked, likes }",
      "url": "https://staging.agentalog.com/api/listings/:id/like",
      "auth_detail": "Guest token (`POST /api/guest`) in `X-Guest-Token: mr_…` or `Authorization: Bearer mr_…`. In the browser it also lives in the HttpOnly `mr_guest` cookie, which writes only from this site's exact Origin. A signed-in account (cookie) also works and takes precedence."
    },
    {
      "method": "DELETE",
      "path": "/api/listings/:id/like",
      "auth": "guest",
      "summary": "Unlikes and gives the point back to the public counter.",
      "grupo": "Community",
      "params": {
        "id": {
          "desc": "ID of the listing to unlike."
        }
      },
      "retorno": "Like",
      "erros": [
        401,
        404
      ],
      "exemplo": "curl -s -XDELETE $ORIGIN/api/listings/ID/like -H \"X-Guest-Token: $MR\"",
      "returns": "{ ok, liked, likes }",
      "url": "https://staging.agentalog.com/api/listings/:id/like",
      "auth_detail": "Guest token (`POST /api/guest`) in `X-Guest-Token: mr_…` or `Authorization: Bearer mr_…`. In the browser it also lives in the HttpOnly `mr_guest` cookie, which writes only from this site's exact Origin. A signed-in account (cookie) also works and takes precedence."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id/dependencies",
      "auth": "none",
      "grupo": "Catalog",
      "summary": "Find the packages, publisher domains and repositories declared by a tool.",
      "desc": "Free declarations and cached public sources. No package installation or code execution. Paid watch passes add source collection, chain history and notices. Registry accounts, author-declared PyPI metadata and registry-provided attestations are distinguished. Provenance signatures are not independently verified.",
      "params": {
        "id": {
          "desc": "Live catalog listing ID."
        }
      },
      "retorno": "DependencySources",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "The public listing does not exist.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl \"$ORIGIN/api/listings/LISTING_ID/dependencies\"",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "agent_value": {
        "idioma": "en",
        "en": {
          "when": "Who publishes this tool's packages, and could its repository or maintainer domain have changed?",
          "result": "Declared packages and repositories, cached public evidence and dated repository state. Existing paid watches add the collected chain and before/after history.",
          "replaces": "Repeated registry, repository, registration and DNS lookups, comparison code and an alert process that must keep running after the conversation.",
          "free": "Read declared targets, cached sources and existing archive evidence before choosing a watch.",
          "paid": "The single-slot, Team and Business watch passes include chain collection, changes and verifiable expiry alerts. Reuse an active pass. This is continuing work beyond the free catalog lookup.",
          "limits": "A declaration does not prove ownership. Source failures and missing dates remain unknown. Collected PyPI provenance is not independently verified. No measured token or money saving is claimed.",
          "alternative": "Your existing dependency inventory already follows the same identities, domains and changes.",
          "start": {
            "href": "/",
            "label": "Find a tool"
          }
        },
        "pt": {
          "when": "Quem publica os pacotes desta ferramenta? O repositório ou o domínio do mantenedor mudou?",
          "result": "Pacotes e repositórios declarados, evidências públicas salvas e situação datada do repositório. A vigia paga acrescenta a cadeia coletada e o histórico antes/depois.",
          "replaces": "Consultas repetidas a registros de pacotes, repositórios, registro de domínio e DNS, código de comparação e operação de alertas após a conversa.",
          "free": "Leia os alvos declarados, as fontes salvas e a evidência de arquivamento antes de escolher a vigia.",
          "paid": "A vaga avulsa e os passes Equipe e Empresa incluem coleta da cadeia, mudanças e alertas de vencimento verificável. Reuse o passe ativo. O pagamento cobre trabalho contínuo além da consulta gratuita ao catálogo.",
          "limits": "Declaração não prova posse. Falhas e datas ausentes ficam desconhecidas. A proveniência do PyPI não recebe verificação independente. Não alegamos economia medida de tokens ou dinheiro.",
          "alternative": "Seu inventário já acompanha as mesmas identidades, os domínios e as mudanças.",
          "start": {
            "href": "/",
            "label": "Encontrar ferramenta"
          }
        }
      },
      "returns": "{ listing_id, declared_targets, alternatives, sources, catalog_observation, coverage, paid_addition, _links }",
      "url": "https://staging.agentalog.com/api/listings/:id/dependencies",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/me/vigia/:id/dependencies",
      "auth": "session_ou_carteira",
      "grupo": "Watch",
      "summary": "Read your watched tool's package, publisher, repository and domain changes.",
      "params": {
        "id": {
          "desc": "Live catalog listing ID."
        }
      },
      "query": {
        "events_after": {
          "tipo": "int",
          "desc": "Continue private history after this event number. Default 0."
        }
      },
      "retorno": "DependencyWatch",
      "erros": {
        "400": "Invalid event cursor.",
        "401": "Account or wallet authentication required.",
        "404": "The owner has no watch for this listing.",
        "503": "The watch service is unavailable."
      },
      "exemplo": "curl \"$ORIGIN/api/me/vigia/LISTING_ID/dependencies\" -H \"Authorization: Bearer $WALLET\"",
      "returns": "{ listing_id, included_in_active_watch_plan, monitoring, _links }",
      "url": "https://staging.agentalog.com/api/me/vigia/:id/dependencies",
      "auth_detail": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account."
    },
    {
      "method": "POST",
      "path": "/api/me/vigia/:id/dependencies",
      "auth": "session_ou_carteira",
      "grupo": "Watch",
      "summary": "Enable or stop chain monitoring included in existing paid watch passes.",
      "desc": "The listing must already be in your watchlist. No separate purchase. Sources refresh every six hours through shared caches. Source quotas can defer a check. History records before, after, source and observation date. Domain expiry alerts use 30, 15 and 7 days when the registry publishes a date. Missing dates and source failures remain unverified. Account holders receive operational e-mail; wallet owners read API history. No account-recovery or takeover attempt is made.",
      "params": {
        "id": {
          "desc": "Live catalog listing ID."
        }
      },
      "corpo": {
        "enabled": {
          "tipo": "bool",
          "obrigatorio": true,
          "desc": "Explicit requested state."
        }
      },
      "body": {
        "enabled": true
      },
      "retorno": "DependencyWatch",
      "erros": {
        "400": "Only a boolean enabled field is accepted.",
        "401": "Account or wallet authentication required.",
        "402": "An existing paid watch pass is required.",
        "403": "The current account request is not authorized.",
        "404": "The owner has no watch for this listing.",
        "503": "The watch service is unavailable."
      },
      "exemplo": "curl -XPOST \"$ORIGIN/api/me/vigia/LISTING_ID/dependencies\" -H \"Authorization: Bearer $WALLET\" -H \"Content-Type: application/json\" -d '{\"enabled\":true}'",
      "returns": "{ listing_id, included_in_active_watch_plan, monitoring, _links }",
      "url": "https://staging.agentalog.com/api/me/vigia/:id/dependencies",
      "auth_detail": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account."
    },
    {
      "method": "GET",
      "path": "/api/feeds",
      "auth": "none",
      "colecao": {
        "porPagina": 50,
        "anda": "next"
      },
      "summary": "The feed index: RSS, Atom and JSON feeds, OPML reading lists and sites that only become a feed through a bridge.",
      "grupo": "Feeds",
      "desc": "Find feeds by text, format, language and availability. Filter and text search run in the SAME full-text query: values inside one parameter are OR'd, different parameters are AND'd. Without `q` the order is by newest in the index (`recentes`) and `next_cursor` is a keyset — follow `next` to walk everything. With `q` the order is relevance and paging is by `offset`. We index and link; the feeds belong to whoever publishes them.",
      "query": {
        "q": {
          "tipo": "string",
          "desc": "Free text over the feed name, its description and the domain. Every word must match; accents are ignored.",
          "exemplo": "linux"
        },
        "origem": {
          "tipo": "string",
          "desc": "Where the record comes from. Comma-separated values are OR'd.",
          "valores": [
            "index",
            "blogroll",
            "bridge"
          ]
        },
        "tipo": {
          "tipo": "string",
          "desc": "Feed format. Comma-separated values are OR'd.",
          "valores": [
            "rss2",
            "rss1",
            "atom",
            "json",
            "rss"
          ]
        },
        "midia": {
          "tipo": "string",
          "desc": "Enclosures the feed carries — this is how you find podcasts and video feeds.",
          "valores": [
            "audio",
            "video"
          ]
        },
        "comunidade": {
          "tipo": "string",
          "desc": "Community the publisher belongs to, as the source's bitmask declares it.",
          "valores": [
            "fediverse",
            "indieweb",
            "mastodon",
            "friendica",
            "wordpress",
            "funkwhale",
            "blogroll"
          ]
        },
        "recurso": {
          "tipo": "string",
          "desc": "Namespace seen in the feed: `content` means the whole post travels in the feed, `itunes`/`podcast` mean podcast metadata, `slash` means comment counts.",
          "valores": [
            "content",
            "itunes",
            "podcast",
            "media",
            "slash",
            "wfw",
            "georss"
          ]
        },
        "lista": {
          "tipo": "string",
          "desc": "For OPML lists only: how the list presents itself.",
          "valores": [
            "web",
            "catalogo",
            "planeta"
          ]
        },
        "ano": {
          "tipo": "string",
          "desc": "Year of the newest item the crawler saw. `0` means the source never dated the content. It is a year, not a moving window: the value never drifts.",
          "exemplo": "2026,2025"
        },
        "saude": {
          "tipo": "string",
          "desc": "What our own check saw: `ok` answered, `erro` refused or timed out, `sumiu` returned 404/410. A feed not checked yet matches none of them.",
          "valores": [
            "ok",
            "erro",
            "sumiu"
          ],
          "exemplo": "ok"
        },
        "pais": {
          "tipo": "string",
          "desc": "ISO-3166 alpha-2 of the IP that serves the host, lowercase or uppercase, resolved in the same check.",
          "exemplo": "br,pt"
        },
        "dominio": {
          "tipo": "string",
          "desc": "Exact domain — the fastest way to ask whether a site has a feed."
        },
        "idioma": {
          "tipo": "string",
          "desc": "Language of the site's home page, two or three letters: `pt` matches `pt` and `pt-br`.",
          "exemplo": "pt"
        },
        "imagem": {
          "tipo": "string",
          "desc": "`1` keeps only feeds whose site has a stored preview image (`imagem` is not empty) — the list that looks like a wall of link cards.",
          "valores": [
            "1"
          ]
        },
        "sort": {
          "tipo": "string",
          "desc": "Result order. `recentes` is insertion in the index (what just arrived). `postando` is the newest post first, read from the feed itself (feeds without a dated post are left out). `frequentes` is most posts in the last 30 days first (same). `densidade` is how much item text discovery found — the closest thing to 'this feed has substance'. `dominio` is A–Z by site.",
          "valores": [
            "recentes",
            "postando",
            "frequentes",
            "densidade",
            "dominio",
            "relevancia"
          ],
          "padrao": "relevancia with q, recentes otherwise"
        },
        "cursor": {
          "tipo": "string",
          "desc": "Opaque cursor from `next_cursor` (orders `recentes`, `densidade` and `dominio`). A cursor from another order restarts at the first page."
        },
        "limit": {
          "tipo": "int",
          "desc": "Feeds per page, 1–50.",
          "padrao": 20
        },
        "offset": {
          "tipo": "int",
          "desc": "Offset, capped at 10000. Ignored when `cursor` is present.",
          "padrao": 0
        }
      },
      "retorno": "PaginaDeFeeds",
      "exemplo": "curl -s '$ORIGIN/api/feeds?midia=audio&recurso=itunes&limit=5'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "returns": "{ items[{id,kind,dominio,url,nome,descricao,tipo,audio,video,comunidade,comunidades,ano,recursos,densidade,itens,saude,pais,site_titulo,site_descricao,site_nome,site_og,site_og_alt,site_cor,site_idioma,idioma_bandeira,icone,imagem,ultimo_post,posts_24h,posts_7d,posts_30d,posts_dias,posts_no_feed,posts_parcial,atividade_em,pagina,api}], limit, offset, next_cursor, next_offset, next, sort, api }",
      "url": "https://staging.agentalog.com/api/feeds",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/feeds/facets",
      "auth": "none",
      "summary": "How many feeds exist in each filter value.",
      "grupo": "Feeds",
      "desc": "Counts reflect the latest catalog update.",
      "retorno": "FacetasDeFeeds",
      "exemplo": "curl -s $ORIGIN/api/feeds/facets",
      "returns": "{ total, facetas, api }",
      "url": "https://staging.agentalog.com/api/feeds/facets",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/feeds/:id",
      "auth": "none",
      "summary": "One feed: address, format, what it carries and where it was found.",
      "grupo": "Feeds",
      "desc": "The same record the HTML page at `/feeds/<id>` shows. 404 when the id is unknown.",
      "params": {
        "id": {
          "tipo": "string",
          "desc": "Feed id, prefix `fd_`.",
          "exemplo": "fd_nytimes_com_1a2b3c4d5e6f7a8b"
        }
      },
      "retorno": "Feed",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "No feed in this index has that id.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/feeds/fd_nytimes_com_1a2b3c4d5e6f7a8b",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ id, kind, dominio, url, nome, descricao, tipo, audio, video, comunidade, comunidades, ano, recursos, densidade, itens, saude, pais, site_titulo, site_descricao, site_nome, site_og, site_og_alt, site_cor, site_idioma, idioma_bandeira, icone, imagem, ultimo_post, posts_24h, posts_7d, posts_30d, posts_dias, posts_no_feed, posts_parcial, atividade_em, pagina, api }",
      "url": "https://staging.agentalog.com/api/feeds/:id",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/feeds/:id/items",
      "auth": "none",
      "summary": "The posts of one feed, as our queue read them.",
      "grupo": "Feeds",
      "desc": "Up to 40 posts, in the order the feed publishes them, WITHOUT the body — the body of one post comes from `/items/:ord`. It is OUR copy, read on our own schedule — not the live feed and not a proxy: the only thing this endpoint accepts is an id from this index, never a URL. `lido_em` says when we read it. Empty list when the feed has not been read yet.",
      "params": {
        "id": {
          "tipo": "string",
          "desc": "Feed id, prefix `fd_`.",
          "exemplo": "fd_nytimes_com_1a2b3c4d5e6f7a8b"
        }
      },
      "retorno": "PostsDeFeed",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "No feed in this index has that id. A feed we know but have not read yet answers 200 with an empty `itens` — the two are different answers on purpose.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/feeds/fd_nytimes_com_1a2b3c4d5e6f7a8b/items",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ id, itens[{ord,tags,media,comentarios,comentarios_n,titulo,link,quando,autor,resumo,bytes}], lido_em, api }",
      "url": "https://staging.agentalog.com/api/feeds/:id/items",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/feeds/:id/items/:ord",
      "auth": "none",
      "summary": "One post of a feed, with the body — the author's HTML and the same text in Markdown.",
      "grupo": "Feeds",
      "desc": "Two bodies for the same post, both from the copy we stored when we READ the feed — a request never fetches the site: `conteudo_html` keeps the author's formatting through an allowlist (only known tags and attributes survive; script, style, iframe and event handlers are dropped with their content), and `conteudo` is the same text as Markdown — the shape an agent usually wants. Neither can carry script. 404 when the feed or the position is unknown.",
      "params": {
        "id": {
          "tipo": "string",
          "desc": "Feed id, prefix `fd_`.",
          "exemplo": "fd_nytimes_com_1a2b3c4d5e6f7a8b"
        },
        "ord": {
          "tipo": "int",
          "desc": "Position of the post in the feed; 0 is the newest.",
          "exemplo": "0"
        }
      },
      "retorno": "PostDeFeedInteiro",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "Unknown feed id, or a position this feed does not have.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/feeds/fd_nytimes_com_1a2b3c4d5e6f7a8b/items/0",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ id, ord, titulo, link, quando, autor, resumo, conteudo_html, conteudo, lido_em, api }",
      "url": "https://staging.agentalog.com/api/feeds/:id/items/:ord",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/indices",
      "auth": "none",
      "summary": "The MCP indexes this catalog reads: credit, license, what each measures, counts and the last round.",
      "grupo": "MCP indexes",
      "desc": "Each index measures something different — one completes an MCP handshake, another reads the last commit, another only discovers that a resource exists — so `mede` comes with every source and every signal. Collected once a day on our own host, raw data kept, and credited on every response: the data is theirs. `coleta.falhou` says the last round failed; the error text stays private.",
      "retorno": "ListaDeIndices",
      "exemplo": "curl -s $ORIGIN/api/indices",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "returns": "{ ok, indices[{id,nome,url,licenca,mede,cadencia_h,sinais,no_catalogo,por_estado,coleta,_links}], _links }",
      "url": "https://staging.agentalog.com/api/indices",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/indices/sinais",
      "auth": "none",
      "summary": "What each MCP index says about one listing of this catalog.",
      "grupo": "MCP indexes",
      "desc": "A signal belongs to a listing only when it is the SAME object: the name in the official MCP registry, the exact remote endpoint URL or the GitHub `owner/repo`, in that order. A shared domain never matches — two servers on one host are different products. Up to 20 signals, one per index and record.",
      "query": {
        "listing": {
          "tipo": "string",
          "desc": "Listing id from `/api/listings`.",
          "exemplo": "mcp_com_stripe_mcp_b890f1d0",
          "obrigatorio": true
        }
      },
      "retorno": "SinaisDoRegistro",
      "erros": {
        "400": "`listing` is missing.",
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s '$ORIGIN/api/indices/sinais?listing=mcp_com_stripe_mcp_b890f1d0'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ ok, listing, count, sinais[{fonte,credito,mede,kind,nome,descricao,url,repo,estado,estado_na_fonte,motivo,acesso,detalhe,ficha_na_fonte,no_catalogo,medido_em,visto_em}], _links }",
      "url": "https://staging.agentalog.com/api/indices/sinais",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/indices/itens",
      "auth": "none",
      "colecao": {
        "porPagina": 50,
        "anda": "offset"
      },
      "summary": "Browse the signals, including servers this catalog does not list yet.",
      "grupo": "MCP indexes",
      "desc": "Newest change first. `casou=0` is what the indexes know and the catalog does not — the list to look at before submitting a server. Filters are AND'd. With `q`, `total` is the exact number of matches, including when the requested page is empty.",
      "query": {
        "fonte": {
          "tipo": "string",
          "desc": "Only the signals of this index — `/api/indices` says what each one measures.",
          "valores": [
            "wellknown",
            "agent_tools",
            "nerq",
            "truespar",
            "neuronto",
            "paygent",
            "hultra"
          ]
        },
        "estado": {
          "tipo": "string",
          "desc": "The state in this catalog's words.",
          "valores": [
            "vivo",
            "fora",
            "parado",
            "abandonado",
            "apagado",
            "desconhecido"
          ]
        },
        "casou": {
          "tipo": "string",
          "desc": "`1` only signals matched to a listing, `0` only unmatched.",
          "valores": [
            "0",
            "1"
          ]
        },
        "q": {
          "tipo": "string",
          "desc": "Substring of the name, the URL or the repository.",
          "exemplo": "postgres"
        },
        "limit": {
          "tipo": "int",
          "desc": "Signals per page, 1–50.",
          "padrao": 20
        },
        "offset": {
          "tipo": "int",
          "desc": "Offset, capped at 50000.",
          "padrao": 0
        }
      },
      "retorno": "PaginaDeSinais",
      "exemplo": "curl -s '$ORIGIN/api/indices/itens?fonte=truespar&estado=fora&casou=1&limit=5'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "returns": "{ ok, total, count, items[{fonte,credito,mede,kind,nome,descricao,url,repo,estado,estado_na_fonte,motivo,acesso,detalhe,ficha_na_fonte,no_catalogo,medido_em,visto_em}], _links }",
      "url": "https://staging.agentalog.com/api/indices/itens",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/check",
      "auth": "none",
      "summary": "Check an MCP server address before installing it: what we already measured about it, without visiting it.",
      "grupo": "Catalog",
      "desc": "Send the endpoint URL. The answer never contacts that address: it reads what our weekly visits measured and what our domain data knows. `sinais_do_endereco` comes from the address alone (consumer tunnel, `http://` without TLS). `registros` lists the catalog listings with this exact address first (`exato: true`), then up to 20 others on the same host, each with its level and signals; `mesmo_host` counts them all. `dominio` has the facts about the host's domain. An address outside the catalog answers `no_catalogo: false` and `registrar`: submit it to get it reviewed. Cached for 5 minutes.",
      "query": {
        "url": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "The http(s) endpoint of the MCP server, without credentials.",
          "exemplo": "https://agentalog.com/mcp"
        }
      },
      "retorno": "Checagem",
      "erros": {
        "400": "Missing, invalid or credential-bearing `url`.",
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s '$ORIGIN/api/check?url=https%3A%2F%2Fagentalog.com%2Fmcp'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ url, host, no_catalogo, sinais_do_endereco, registros, mesmo_host, dominio, registrar, api }",
      "url": "https://staging.agentalog.com/api/check",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id/security",
      "auth": "none",
      "summary": "Security review of a remote MCP server or SKILL.md: level, measured signals, evidence and changes.",
      "grupo": "Catalog",
      "desc": "We visit remote MCP servers: `initialize` and `tools/list`, without credentials or tool calls, again 7 days after a success. A failure needs a second check. MCP signals: dns_morto, sem_https, tls_invalido, tunel, nao_responde, nao_mcp, texto_suspeito, redireciona_fora, repo_arquivado, repo_parado, dominio_recente, login, bloqueado. For skills, `tipo: skill` identifies a static SKILL.md review. It flags secret reads, download-and-execute commands, external uploads, invisible characters, long encoded text and broad allowed-tools. `revisao.achados` supplies the path, original line, excerpt and context. Examples and prohibitions do not raise the level. Excerpts hide sensitive values. The review does not run commands or follow references. Supported source: public raw.githubusercontent.com SKILL.md. Watched, visited, starred and new skills get priority within the shared GitHub governor and a daily cap. Unread or unsupported skills remain explicitly unchecked. Local MCP servers and plugins answer `nao_remoto`. No request fetches a third-party source. Cached for 5 minutes.",
      "params": {
        "id": {
          "desc": "Listing ID, from `Anuncio.id`."
        }
      },
      "query": {
        "lang": {
          "tipo": "string",
          "desc": "Language of the `aviso` sentence: `en` (default) or `pt`.",
          "exemplo": "pt"
        }
      },
      "retorno": "Seguranca",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "The listing does not exist or is not visible.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/listings/ID/security",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ id, conferido, motivo?, nivel, tipo?, revisao?, fonte?, caminho?, vigiavel?, sinais, servidor?, dominio?, ferramentas?, verificado_em?, proxima_em?, mudou_em?, eventos?, aviso, api }",
      "url": "https://staging.agentalog.com/api/listings/:id/security",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id/tools",
      "auth": "none",
      "summary": "The tools and instructions a remote MCP server announced at its last check.",
      "grupo": "Catalog",
      "desc": "The announced manifest, normalized: each tool's name, title, description (up to 4,000 characters), input schema (null above 8,000 characters) and protocol annotations, plus the server instructions. `capacidades` and `suspeitas` come from the current rules, applied when you read. Reading this endpoint never contacts the server. Cached for 5 minutes.",
      "params": {
        "id": {
          "desc": "Listing ID, from `Anuncio.id`."
        }
      },
      "retorno": "FerramentasAnunciadas",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "The listing does not exist or is not visible (`not_found`), or its tools were not read yet (`tools_not_read`).",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/listings/ID/tools",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ id, sha, verificado_em, mudou_em, instrucoes, ferramentas, capacidades, suspeitas, api }",
      "url": "https://staging.agentalog.com/api/listings/:id/tools",
      "auth_detail": "Public, no credential."
    },
    {
      "auth": "credito",
      "method": "GET",
      "path": "/api/x402/check",
      "summary": "Checks an MCP server address for an agent, paid per call: what we measured, the catalog listings and the domain facts.",
      "grupo": "Catalog",
      "desc": "The answer of `GET /api/check`, sold per call to agents, with no account and no allowance before. A request without payment gets the 402 with the price; a paid one gets the check in the same response, with the payment in `cobranca`. The check never visits the address. When the check is unavailable, the answer is 503 and nothing is charged.",
      "query": {
        "url": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "The http(s) endpoint of the MCP server, without credentials.",
          "exemplo": "https://agentalog.com/mcp"
        }
      },
      "retorno": "ChecagemAvulsa",
      "exemploRetorno": {
        "url": "https://agentalog.com/mcp",
        "host": "agentalog.com",
        "no_catalogo": true,
        "sinais_do_endereco": [],
        "registros": [
          {
            "id": "mcp_com_agentalog_meta_agent_tools_0c3ebff2",
            "nome": "Agentalog — Agent Auto Log",
            "exato": true,
            "nivel": "atencao",
            "sinais": [
              "dominio_recente"
            ],
            "verificado_em": "2026-10-24T11:07:05.051Z",
            "ficha": "https://api.agentalog.com/l/mcp_com_agentalog_meta_agent_tools_0c3ebff2",
            "security": "https://api.agentalog.com/api/listings/mcp_com_agentalog_meta_agent_tools_0c3ebff2/security"
          }
        ],
        "mesmo_host": 2,
        "dominio": {
          "nome": "agentalog.com",
          "registrado": {
            "desde": "2026-08-31",
            "ate": "2026-09-07",
            "fonte": "nrd7"
          },
          "organizacao": null,
          "tambem_cobre": [
            {
              "dominio": "classificado.app.br",
              "certificados": 1,
              "visto_em": "2026-09-23"
            }
          ],
          "mudou_em": "2026-10-07T10:15:27.832Z"
        },
        "registrar": null,
        "api": "https://api.agentalog.com/api/check?url=https%3A%2F%2Fagentalog.com%2Fmcp"
      },
      "erros": {
        "400": "Paid without `url` (`missing_input`, with `example`), or with an invalid or credential-bearing `url` (`url`). Not charged.",
        "401": "API key refused (`invalid_api_key`), OAuth token refused (`invalid_token`), credit refused (`credito_invalido`), test credit outside dev (`credito_simulado`), or recovery without wallet authentication (`wallet_proof_required`). The first x402 purchase needs no account.",
        "402": "No payment: `accepts` (x402, USDC on Base) with the price of this call, at least US$ 0.01; `credito.preco_desta_chamada`, the lower price with prepaid credit; and `pacotes` (the credit top-ups and how many calls each one pays). Credit without balance answers `saldo_insuficiente`.",
        "409": "Payment is in progress, the request differs from the original, or the amount was recovered as balance. Do not sign another authorization to retry the purchase.",
        "410": "The 24-hour response recovery period ended. The financial record remains; the same proof cannot cause another charge.",
        "503": "The check is unavailable (`check_unavailable`). Not charged."
      },
      "exemplo": "curl -s -i '$ORIGIN/api/x402/check?url=https%3A%2F%2Fagentalog.com%2Fmcp'",
      "headers": {
        "authorization": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "`Bearer mmk_…` (API key) or `Bearer mmo_…` (OAuth): the paid call uses the account balance without another header. Without an account, use prepaid credit from `POST /api/credito` as `Bearer cred_…`."
        },
        "x-api-key": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "The mmk_… API key for this product. It identifies the account and authorizes its balance for the paid call."
        },
        "payment-signature": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "The signed x402 payment proof (base64): `PAYMENT-SIGNATURE` (v2) or `X-PAYMENT` (v1)."
        },
        "x-wallet-token": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "To recover an x402 response within 24 hours, repeat the same request and payment proof. Send the payer wallet's `mmw_…` credential here, issued through `/api/auth/wallet/agent/start` and `/api/auth/wallet/agent/token`. There is no new charge."
        }
      },
      "returns": "{ url, host, no_catalogo, sinais_do_endereco, registros, mesmo_host, dominio, registrar, api, cobranca{via,preco_usd,repetido,saldo_usd?} }",
      "url": "https://staging.agentalog.com/api/x402/check",
      "auth_detail": "Credit token in `Authorization: Bearer cred_…` or `X-Credito`. For recovered x402 funds, use the wallet credential mmw_… in Bearer or X-Wallet-Token, issued through /api/auth/wallet/agent/start and /api/auth/wallet/agent/token."
    },
    {
      "method": "GET",
      "path": "/api/me/vigia",
      "auth": "session_ou_carteira",
      "summary": "The MCP servers and skills you watch, with the current review, your slots and the plans.",
      "grupo": "Watch",
      "desc": "Daily checks cover MCP tools, state, level, country and version. Supported skills cover changes in SKILL.md text and review signals. Source quotas can delay a check; read proxima_em and verificado_em. The e-mail goes to the verified account address and includes an unsubscribe link. Wallet-only owners read the changes in `GET /api/me/vigia/avisos`.",
      "retorno": "Vigia",
      "erros": {
        "401": "Sign in with your account, or send an agent wallet: `Authorization: Bearer mmw_…` or the prepaid credit in `Authorization: Bearer cred_…` or `X-Credito`."
      },
      "exemplo": "curl -s $ORIGIN/api/me/vigia -H \"Cookie: __Host-mm-auth=…\"",
      "returns": "{ itens, cota, planos, claude_code, api }",
      "url": "https://staging.agentalog.com/api/me/vigia",
      "auth_detail": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account."
    },
    {
      "method": "POST",
      "path": "/api/me/vigia",
      "auth": "session_ou_carteira",
      "summary": "Watch a remote MCP or supported SKILL.md. Uses a free slot; without one, answers 402 for another slot.",
      "grupo": "Watch",
      "desc": "Choose a live remote MCP or a skill with a supported public raw.githubusercontent.com SKILL.md, after skill collection is enabled. Unsupported skills are rejected before payment. Watching again is a no-op (`ja_vigiado`). Pay the 402 with x402 or prepaid credit and repeat the request. Slots last 30 days with no automatic renewal. Skills do not enter the Claude Code MCP allowlist.",
      "corpo": {
        "listing_id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Listing ID (`mcp_…` or `skl_…`) from `/api/listings`."
        }
      },
      "body": {
        "listing_id": "mcp_io_github_upstash_context7_d016de0d"
      },
      "retorno": "VigiaAlterada",
      "erros": {
        "400": "Invalid JSON, unavailable skill review, unsupported source or a listing that cannot be watched (`nao_vigiavel`).",
        "401": "Sign in with your account, or send an agent wallet: `Authorization: Bearer mmw_…` or the prepaid credit in `Authorization: Bearer cred_…` or `X-Credito`.",
        "402": "No free slot: pay for one more.",
        "403": "Missing or invalid X-CSRF-Token.",
        "409": "Expired passes leave paused tools in the list. Stop watching one or buy slots before adding another tool. A concurrent request can also use the last slot; refresh the list and retry."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/me/vigia -H \"Content-Type: application/json\" -H \"X-CSRF-Token: $CSRF\" -d '{\"listing_id\":\"mcp_…\"}'",
      "agent_value": {
        "principal": true,
        "idioma": "en",
        "en": {
          "when": "How do I track changes in an MCP server or skill I use?",
          "result": "Daily watch notices with the change type, before and after values, observation date and links to review the affected tool.",
          "replaces": "We collect and compare the supported sources daily. Your agent reads the changes without maintaining its own watch process.",
          "free": "Inspect catalog and history, then use POST /api/me/vigia within free coverage. Read GET /api/me/vigia/avisos and keep its cursor. Check de, para and visto_em before deciding what the change affects.",
          "paid": "Add watch slots or compare a 30-day team package for the tools you use. The paid GET /api/x402/check has the same analysis as free GET /api/check.",
          "limits": "Catalog signals and change notices are not a security audit or proof that remote code is safe. Local hooks do not freeze remote MCP code.",
          "alternative": "You only need a known project's URL, the free allowance covers your tools, or your existing inventory already tracks equivalent changes.",
          "start": {
            "href": "/",
            "label": "Find and watch a tool"
          }
        },
        "pt": {
          "when": "Como acompanhar mudanças em um MCP ou skill que uso?",
          "result": "Avisos da vigia diária com tipo de mudança, valores anteriores e atuais, data observada e links para revisar a ferramenta afetada.",
          "replaces": "Coletamos e comparamos as fontes cobertas todo dia. Seu agente lê as mudanças sem operar uma vigia própria.",
          "free": "Confira catálogo e histórico. Use POST /api/me/vigia na cobertura gratuita. Leia GET /api/me/vigia/avisos e guarde o cursor. Confira de, para e visto_em antes de avaliar o impacto.",
          "paid": "Amplie as vagas ou compare um pacote de equipe de 30 dias para as ferramentas que usa. GET /api/x402/check tem a mesma análise do gratuito GET /api/check.",
          "limits": "Sinais do catálogo e avisos não são auditoria de segurança nem prova de código remoto seguro. Hooks locais não congelam o código remoto do MCP.",
          "alternative": "Basta a URL de um projeto conhecido, a franquia cobre suas ferramentas ou seu inventário já acompanha mudanças equivalentes.",
          "start": {
            "href": "/",
            "label": "Encontrar e acompanhar ferramenta"
          }
        }
      },
      "returns": "{ ok, id?, ja_vigiado?, cota }",
      "url": "https://staging.agentalog.com/api/me/vigia",
      "auth_detail": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account."
    },
    {
      "method": "DELETE",
      "path": "/api/me/vigia/:id",
      "auth": "session_ou_carteira",
      "summary": "Stop watching a tool; its slot becomes free.",
      "grupo": "Watch",
      "params": {
        "id": {
          "desc": "Listing ID (`mcp_…` or `skl_…`)."
        }
      },
      "retorno": "VigiaAlterada",
      "erros": {
        "401": "Sign in with your account, or send an agent wallet: `Authorization: Bearer mmw_…` or the prepaid credit in `Authorization: Bearer cred_…` or `X-Credito`.",
        "404": "The listing is not in your watch list."
      },
      "exemplo": "curl -s -XDELETE $ORIGIN/api/me/vigia/mcp_… -H \"X-CSRF-Token: $CSRF\"",
      "returns": "{ ok, id?, ja_vigiado?, cota }",
      "url": "https://staging.agentalog.com/api/me/vigia/:id",
      "auth_detail": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account."
    },
    {
      "method": "GET",
      "path": "/api/plans",
      "auth": "none",
      "summary": "The plans for sale and the authenticated account or wallet's active plan.",
      "desc": "Each purchase lasts 30 days, with no automatic renewal. Without an account or wallet credential, `account` is `null`.",
      "grupo": "Watch",
      "query": {
        "resumo": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Use `1` to read the active plan without cancellation, retention and refund details.",
          "exemplo": "1"
        }
      },
      "retorno": {
        "plans": {
          "tipo": "object[]",
          "desc": "Each plan: `id`, `name`, `watched_tools`, `days`, `price_usd`, `automatic_renewal`, `charged_now` and the `buy` URL."
        },
        "account": {
          "tipo": "object",
          "desc": "`active` (the plan that ends last, with `valid_until`) and `cancel` (what cancelling removes when the plan ends, the free-days offer, the refund, `keeps_until`, until when what you paid for stays active, `ends_now`, true when cancelling ends part of the plan now, and `renews`, true when a monthly subscription renews it). Without a refund, `ends_now` or `renews`, cancelling changes nothing.",
          "nulo": true
        }
      },
      "erros": {
        "401": "session_ended",
        "503": "auth_unavailable"
      },
      "exemplo": "curl -s $ORIGIN/api/plans",
      "returns": "{ plans, account }",
      "url": "https://staging.agentalog.com/api/plans",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/plans/:plan",
      "auth": "none",
      "summary": "Buys a plan for the account or paying wallet.",
      "desc": "Each purchase lasts 30 days, with no automatic renewal. Without payment, the answer is 402 with the price. Pay with prepaid credit (`X-Credito`) or x402 (`PAYMENT-SIGNATURE` v2 or `X-PAYMENT` v1). Without an account, the verified paying wallet owns the purchase. Use wallet agent authentication to read its plan, or claim it after account sign-in. The `compra` mark prevents repeat credit debits. An x402 nonce can settle only once; keep the receipt after a delivery error.",
      "grupo": "Watch",
      "params": {
        "plan": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "`vaga` (1 more tool), `equipe` (50 more tools and up to 10 private projects), `empresa` (500 more tools and up to 10 private projects)",
          "exemplo": "vaga"
        }
      },
      "query": {
        "compra": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Mark of one credit purchase, 8 to 64 letters, digits, `-` or `_`. Repeating it with the same credit token does not debit again.",
          "exemplo": "purchase-2026-10-12"
        }
      },
      "retorno": {
        "plan": {
          "tipo": "string",
          "desc": "The plan bought."
        },
        "watched_tools_added": {
          "tipo": "number",
          "desc": "Units granted by this purchase."
        },
        "valid_until": {
          "tipo": "string",
          "desc": "When this purchase ends (ISO 8601)."
        },
        "automatic_renewal": {
          "tipo": "bool",
          "desc": "`false` for Pix, USDC and credit."
        },
        "account": {
          "tipo": "object",
          "desc": "The active plan for the owner; `null` if its summary is unavailable.",
          "nulo": true
        },
        "_links": {
          "tipo": "object",
          "desc": "Plans URL and, for a wallet purchase, wallet authentication and claim URLs."
        }
      },
      "erros": {
        "401": "An explicit account, wallet or credit credential was refused.",
        "402": "Payment required: the price and the accepted payments.",
        "403": "Writes with the account cookie need the same Origin and `X-CSRF-Token`.",
        "404": "Unknown plan (`unknown_plan`).",
        "409": "Plans are not on sale now (`sales_closed`) or billing is off (`billing_off`)."
      },
      "exemplo": "curl -s -X POST \"$ORIGIN/api/plans/vaga?compra=purchase-2026-10-12\" -H \"X-CSRF-Token: $CSRF\" -H \"X-Credito: $CREDITO\" -b \"$COOKIE\"",
      "returns": "{ plan, watched_tools_added, valid_until, automatic_renewal, account, _links }",
      "url": "https://staging.agentalog.com/api/plans/:plan",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/plans/cancel",
      "auth": "session",
      "summary": "Cancels the active plan: nothing else is charged, and what you paid for stays active until the end of its period.",
      "desc": "Send `{ \"accept_data_removal\": true }`. The monthly card subscription stops. A purchase made less than 7 days ago and a paid period that has not started yet, such as a renewal, go back the same way they were paid (card or Pix) and end now. The rest of the paid period stays active until `keeps_until`; then what the plan added ends (`account.cancel.losses` in `GET /api/plans` says what). A purchase paid with USDC or with credit from another purchase stays active until its end; ask for its refund by e-mail, as the cancellation page says.",
      "grupo": "Watch",
      "corpo": {
        "accept_data_removal": {
          "tipo": "bool",
          "obrigatorio": true,
          "desc": "Must be `true`: you accept losing what the plan added."
        }
      },
      "body": {
        "accept_data_removal": true
      },
      "retorno": {
        "canceled": {
          "tipo": "bool",
          "desc": "`true` when a valid plan was canceled: it ended now, or it stays active until `keeps_until`."
        },
        "refund": {
          "tipo": "object",
          "desc": "`method` (`original`), `amount_cents` and its `currency` (`brl` when Asaas refunds, `usd` when Stripe refunds; `null` when both do).",
          "nulo": true
        },
        "keeps_until": {
          "tipo": "string",
          "desc": "When the paid period that stays active ends (ISO 8601); `null` when everything ended now.",
          "nulo": true
        },
        "account": {
          "tipo": "object",
          "desc": "The account state after cancelling, as in `GET /api/plans`."
        }
      },
      "erros": {
        "400": "Missing `accept_data_removal: true` (`confirmation_required`).",
        "401": "Sign in first (`account_required`), or the session ended (`session_ended`).",
        "403": "Writes with the account cookie need the same Origin and `X-CSRF-Token`."
      },
      "exemplo": "curl -s -X POST $ORIGIN/api/plans/cancel -H \"Content-Type: application/json\" -H \"X-CSRF-Token: $CSRF\" -b \"$COOKIE\" -d '{\"accept_data_removal\":true}'",
      "returns": "{ canceled, refund, keeps_until, account }",
      "url": "https://staging.agentalog.com/api/plans/cancel",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/plans/:plan/grace",
      "auth": "session",
      "summary": "Takes the free-days offer from the cancellation: the offered plan, free for 7 days, once per account.",
      "desc": "`account.cancel.offer` in `GET /api/plans` says which plan and for how long. Nothing renews by itself, and what you paid for stays active until its end; the free days start after it.",
      "grupo": "Watch",
      "params": {
        "plan": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "`vaga` (1 more tool), `equipe` (50 more tools and up to 10 private projects), `empresa` (500 more tools and up to 10 private projects)",
          "exemplo": "vaga"
        }
      },
      "retorno": {
        "plan": {
          "tipo": "string",
          "desc": "The plan granted."
        },
        "valid_until": {
          "tipo": "string",
          "desc": "When the free days end."
        },
        "price_usd": {
          "tipo": "number",
          "desc": "Always `0`."
        },
        "account": {
          "tipo": "object",
          "desc": "The account state after the offer, as in `GET /api/plans`."
        }
      },
      "erros": {
        "401": "Sign in first (`account_required`), or the session ended (`session_ended`).",
        "403": "Writes with the account cookie need the same Origin and `X-CSRF-Token`.",
        "404": "Unknown plan (`unknown_plan`).",
        "409": "No offer for this account or plan (`offer_unavailable`)."
      },
      "exemplo": "curl -s -X POST $ORIGIN/api/plans/vaga/grace -H \"X-CSRF-Token: $CSRF\" -b \"$COOKIE\"",
      "returns": "{ plan, valid_until, price_usd, account }",
      "url": "https://staging.agentalog.com/api/plans/:plan/grace",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/me/vigia/claude-code",
      "auth": "session_ou_carteira",
      "summary": "Your watch list as Claude Code managed settings: an allowlist of the servers you watch, a denylist of the ones at risk.",
      "grupo": "Watch",
      "desc": "`managed_settings` goes into a Claude Code managed settings source (see `docs`). `allowManagedMcpServersOnly` restricts user-added servers to this list. Checked servers rated as `risco` go to `deniedMcpServers`. The exact URL and that URL followed by `?*` permit the checked route with optional query parameters. Expired or unchecked items stay out. `comandos` has one quoted `claude mcp add` command per allowed server.",
      "retorno": "ListaClaudeCode",
      "erros": {
        "401": "Sign in with your account, or send an agent wallet: `Authorization: Bearer mmw_…` or the prepaid credit in `Authorization: Bearer cred_…` or `X-Credito`."
      },
      "exemplo": "curl -s $ORIGIN/api/me/vigia/claude-code -H \"Cookie: __Host-mm-auth=…\"",
      "returns": "{ managed_settings, comandos, fora, aviso, docs, api }",
      "url": "https://staging.agentalog.com/api/me/vigia/claude-code",
      "auth_detail": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account."
    },
    {
      "method": "GET",
      "path": "/api/me/vigia/avisos",
      "auth": "session_ou_carteira",
      "summary": "The changes in the tools you watch, oldest first, with a cursor: the alert feed for agents without e-mail.",
      "grupo": "Watch",
      "desc": "The same changes the account e-mail reports, while each tool was watched. Without `depois`, the last 30 days. Up to 100 per page: repeat with `depois` set to the `cursor` of the last response while `mais` is `true`. With nothing new, the answer keeps the same cursor, so poll with the last one. `email: true` means the account also gets these changes by e-mail.",
      "query": {
        "depois": {
          "tipo": "string",
          "desc": "The `cursor` of the last response. Leave it out to read the last 30 days."
        },
        "lingua": {
          "tipo": "string",
          "desc": "Language of `texto`: `en` (default) or `pt`.",
          "exemplo": "pt"
        }
      },
      "retorno": "AvisosDaVigia",
      "erros": {
        "400": "Invalid cursor (`cursor`).",
        "401": "Sign in with your account, or send an agent wallet: `Authorization: Bearer mmw_…` or the prepaid credit in `Authorization: Bearer cred_…` or `X-Credito`."
      },
      "exemplo": "curl -s \"$ORIGIN/api/me/vigia/avisos?depois=$CURSOR\" -H \"Authorization: Bearer cred_…\"",
      "returns": "{ avisos, cursor?, mais, email }",
      "url": "https://staging.agentalog.com/api/me/vigia/avisos",
      "auth_detail": "The global account (the session cookie of this domain), or, for an agent without an account, the wallet credential in `Authorization: Bearer mmw_…` (`POST /api/auth/wallet/agent/start`, sign, `POST /api/auth/wallet/agent/token`) or the prepaid credit token in `Authorization: Bearer cred_…` or `X-Credito` (`POST /api/credito`). With both, the `mmw_…` wallet owns the watches and the credit only pays. An agent reads the changes in `GET /api/me/vigia/avisos`; the change e-mail goes only to an account."
    },
    {
      "method": "GET",
      "path": "/api/monitor/projetos",
      "auth": "session",
      "grupo": "Installed agents",
      "summary": "List your private agent projects and their human labels.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Basic accounts can create three projects. An active Team or Business pass permits ten, with three active installations per project. The response includes current limits and their expiry. After the pass ends, existing projects remain readable and exportable. Archived references and decisions are read only. New projects and installation credentials return to basic capacity. Separate single-slot purchases do not combine into this benefit. A guest or a wide API key cannot read projects.",
      "retorno": {
        "projetos": {
          "tipo": "object[]",
          "desc": "Owned projects: id, nome, criado_em (Unix seconds) and apagando (pending erasure)."
        },
        "limites": {
          "tipo": "object",
          "desc": "Current capacity: projetos (3 or 10), instalacoes (3), expira_em (Unix seconds or null)."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/projetos\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ projetos, limites }",
      "url": "https://staging.agentalog.com/api/monitor/projetos",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos",
      "auth": "session",
      "grupo": "Installed agents",
      "summary": "Create a private project with a retry ID and a short label.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Use the same ID on retry. A replay keeps the original name and performs no new domain write. Labels must not contain local paths, control characters or secrets.",
      "corpo": {
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "32 lower-case hexadecimal characters, generated once per creation attempt."
        },
        "nome": {
          "tipo": "string",
          "desc": "A short human label, from 1 to 80 characters. No file path or secret."
        }
      },
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "The created or already owned project ID."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:JSON.stringify({id:crypto.randomUUID().replaceAll(\"-\",\"\"),nome:\"Build agent\"})});",
      "exemploLinguagem": "js",
      "returns": "{ id }",
      "url": "https://staging.agentalog.com/api/monitor/projetos",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/instalacoes",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Issue one installation credential for this private project.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Requires authentication within 2 hours and exact empty JSON. The secret is returned once; store its download privately with mode 0600. At most three active installations per project. If the account exceeds its current project capacity, renew the pass or delete excess projects before issuance. A new token expires within 30 days or at the active pass end, whichever comes first. It cannot approve, buy, create a project or issue another credential.",
      "corpo": {},
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "Credential contract version: credencial-1."
        },
        "projeto": {
          "tipo": "string",
          "desc": "The credential's single private project."
        },
        "instalacao": {
          "tipo": "string",
          "desc": "The credential's single installation ID."
        },
        "token": {
          "tipo": "string",
          "desc": "Private mmi_ bearer secret, returned only by this issuance response."
        },
        "expira_em": {
          "tipo": "int",
          "desc": "Expiry timestamp in Unix seconds."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/instalacoes\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:JSON.stringify({})});",
      "exemploLinguagem": "js",
      "returns": "{ esquema, projeto, instalacao, token, expira_em }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/instalacoes",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/monitor/projetos/:projeto/inventario",
      "summary": "Read the received inventory for your active installations.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Installation metadata and the preserved normalized reference. Null inventory means no reference has arrived. A partial scan does not remove prior items. Receiving metadata does not approve a tool or prove execution. With historico=1, return at most three current-epoch references: active installations first, then the most recent archived installations. Archived entries have ativa=false and are read only. This option does not authorize sends, links, approvals or signed policies. References become eligible for cleanup 45 days after credential expiry.",
      "query": {
        "historico": {
          "tipo": "int",
          "desc": "Optional. Use exactly 1 to include archived references."
        }
      },
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "Received inventory state contract: estado-remoto-1."
        },
        "projeto": {
          "tipo": "string",
          "desc": "The owned private project."
        },
        "instalacoes": {
          "tipo": "object[]",
          "desc": "At most three current-epoch installations: id, expira_em, confirmado_em and inventario. historico=1 also includes ativa. No secret."
        }
      },
      "exemploLinguagem": "js",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/inventario?historico=1\", {credentials: \"same-origin\"}).then(r => r.json());",
      "returns": "{ esquema, projeto, instalacoes }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/inventario",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/monitor/projetos/:projeto/vigias",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Read explicit inventory links and your active catalog watches.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. At most three current-epoch installations, 500 links per installation and 1,000 watches. Only the signed-in owner can read these links. A watch ID or inventory name does not prove that the tools match. An expired watch leaves its link inactive.",
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "Link state contract: vigias-inventario-1."
        },
        "projeto": {
          "tipo": "string",
          "desc": "The owned private project."
        },
        "alvos": {
          "tipo": "object[]",
          "desc": "Active owned catalog watches: id and valido_ate (expiry in Unix seconds). No private account information."
        },
        "instalacoes": {
          "tipo": "object[]",
          "desc": "Active installations: id and vinculos. Each link has item, alvo and ativa. No credential."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/vigias\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ esquema, projeto, alvos, instalacoes }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/vigias",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/vigias",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Link one received inventory item to an existing watch, or remove its link.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Requires the human account cookie and CSRF. Installation tokens and wide API keys cannot select watches. The item must be present in this active installation. The watch must already be active and owned by the account. Set alvo to null to remove a link, including after item removal. An exact retry writes nothing. Changed links share the global 512 registrations per day. This creates no watch, charge or approval.",
      "corpo": {
        "instalacao": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Owned installation ID: 32 lower-case hexadecimal characters."
        },
        "item": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Received inventory item ID: 64 lower-case hexadecimal characters."
        },
        "alvo": {
          "tipo": "string",
          "obrigatorio": true,
          "nulo": true,
          "desc": "Existing watch ID, or null to remove the link."
        }
      },
      "retorno": {
        "vinculado": {
          "tipo": "bool",
          "desc": "True when linked; false when the link is absent."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "Inventory is absent, the selected watch is inactive or the link limit is reached.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/vigias\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:JSON.stringify({instalacao:\"INSTALLATION_ID\",item:\"ITEM_ID\",alvo:\"WATCH_ID\"})});",
      "exemploLinguagem": "js",
      "returns": "{ vinculado }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/vigias",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/monitor/projetos/:projeto/eventos",
      "auth": "session_ou_monitor_reader",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Read committed inventory changes and native actions after a private project cursor.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Use the account cookie or, when configured, an mmq_ bearer reader for this project. Installation tokens cannot read the project cursor. Do not mix the reader with cookies or X-API-Key. Keyset pagination, up to five batches and 4 MiB per response. Store the returned cursor; the next page retains any batch omitted by the byte limit. Zero starts at available history. Future cursors fail. Expired history returns 410 with cursor_inicial; it is not an empty unchanged result. Events become eligible for deletion after 45 days. Reread the same page to check current notice state without creating another event or send.",
      "query": {
        "desde": {
          "tipo": "int",
          "desc": "Last confirmed project cursor. Start with zero."
        },
        "limite": {
          "tipo": "int",
          "desc": "Maximum batches per response, from 1 to 5."
        }
      },
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "Cursor response contract: eventos-inventario-1."
        },
        "projeto": {
          "tipo": "string",
          "desc": "The owned private project."
        },
        "itens": {
          "tipo": "EventoMonitor[]",
          "desc": "Committed inventory batches. evento-inventario-2 also contains up to 64 native metadata actions. Attempts, observed outcomes and monitor failures remain distinct. Notice state is current read metadata, not part of the committed event or an approval. Provider acceptance does not prove inbox delivery."
        },
        "cursor": {
          "tipo": "int",
          "desc": "Cursor to store after consuming this response. An empty page marks the current end."
        },
        "anterior_expirado": {
          "tipo": "bool",
          "desc": "True when starting at zero omitted already expired history. Report the coverage gap."
        },
        "avisos_ativos": {
          "tipo": "bool",
          "desc": "True when the durable notice queue is configured. False means notice state is unavailable. It does not prove that account mail is enabled."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "410": "History expired. Read cursor_inicial and report the coverage gap.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/eventos?desde=0&limite=5\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ esquema, projeto, itens[{esquema,numero,instalacao,lote,sequencia,quando,cobertura,cobertura_alertas?,mudancas,acoes?,vigias?,aviso}], cursor, anterior_expirado, avisos_ativos }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/eventos",
      "auth_detail": "The existing human account cookie, or a separate mmq_ bearer credential for one project's event GET. Do not mix the reader with cookies or X-API-Key. Account status, security version, expiry and revocation are checked on each use."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/instalacoes/:instalacao/revogar",
      "auth": "session",
      "grupo": "Installed agents",
      "summary": "Revoke one installation credential without changing local files.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. A repeated revocation is idempotent. New sends with this credential fail. This does not stop or uninstall the local agent, erase local state or reset the project's cursor.",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        },
        "instalacao": {
          "desc": "An installation ID inside this owned project."
        }
      },
      "corpo": {},
      "retorno": {
        "revogada": {
          "tipo": "bool",
          "desc": "True once the credential is revoked."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/instalacoes/INSTALLATION_ID/revogar\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:JSON.stringify({})});",
      "exemploLinguagem": "js",
      "returns": "{ revogada }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/instalacoes/:instalacao/revogar",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/excluir",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Delete an owned project and its private monitor data.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Requires authentication within 2 hours, CSRF and exact empty JSON. Stop all project credentials immediately. Remove at most 64 events and 64 installations per call. Pending erasure resumes hourly, including after account deactivation. Local files, legacy watches and purchased credits remain. Installation tokens cannot erase a project.",
      "corpo": {},
      "retorno": {
        "excluido": {
          "tipo": "bool",
          "desc": "True when the project and all its private records are gone."
        },
        "pendente": {
          "tipo": "bool",
          "desc": "True while bounded erasure must continue. New sends remain disabled."
        },
        "eventos": {
          "tipo": "int",
          "desc": "Events removed in this batch, at most 64."
        },
        "instalacoes": {
          "tipo": "int",
          "desc": "Installations removed in this batch, at most 64."
        },
        "acoes": {
          "tipo": "int",
          "desc": "Native action IDs removed, at most 64. Optional."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/excluir\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:JSON.stringify({})});",
      "exemploLinguagem": "js",
      "returns": "{ excluido, pendente, eventos, instalacoes, acoes }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/excluir",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/monitor/instalacao",
      "auth": "monitor_installation",
      "grupo": "Installed agents",
      "summary": "Check the narrow credential and its confirmed remote reference.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. The fixed client authority is https://api.agentalog.com. This route returns no inventory, owner information or secret. Account epoch, revocation and expiry are checked on every call. A read does not update presence.",
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "Reference contract: instalacao-remota-1."
        },
        "projeto": {
          "tipo": "string",
          "desc": "The credential's single project."
        },
        "instalacao": {
          "tipo": "string",
          "desc": "The credential's installation."
        },
        "sequencia": {
          "tipo": "int",
          "desc": "Last committed installation sequence, zero before the first batch."
        },
        "lote": {
          "tipo": "string",
          "desc": "Last committed batch ID, null before the first batch.",
          "nulo": true
        },
        "expira_em": {
          "tipo": "int",
          "desc": "Credential expiry timestamp in Unix seconds."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "curl --fail -H \"Authorization: Bearer INSTALLATION_TOKEN\" \"$ORIGIN/api/monitor/instalacao\"",
      "returns": "{ esquema, projeto, instalacao, sequencia, lote, expira_em }",
      "url": "https://staging.agentalog.com/api/monitor/instalacao",
      "auth_detail": "Private mmi_ credential in Authorization: Bearer, restricted to one installation and project. The account issues it after recent human sign-in. It cannot approve, buy or issue another credential."
    },
    {
      "method": "POST",
      "path": "/api/monitor/inventario",
      "auth": "monitor_installation",
      "grupo": "Installed agents",
      "summary": "Commit one bounded private inventory batch and return its receipt.",
      "desc": "Private and no-store. No catalog quota, paid read, public cache or CORS grant. Send only a persisted lote-1 or lote-2 body from the client outbox. lote-1 has no actions; lote-2 requires 1 to 64 distinct actions and the optional action receiver. The server checks the sequence and preceding ID, preserves incomplete sources and acknowledges after commit. Exact replays return the same receipt without an extra event or budget debit. Native IDs are deduplicated across batches. A changed action under the same ID returns 409. New actions share the global 512 registrations per day. Extra fields, raw URLs, local paths and raw arguments fail. Global limit: 256 batches and 32 MiB logical bytes per day. Per installation: 20 batches per day and 600 before expiry.",
      "corpo": {
        "esquema": {
          "tipo": "string",
          "obrigatorio": true,
          "valores": [
            "lote-1",
            "lote-2"
          ],
          "desc": "Persisted batch version. lote-2 requires the optional native action receiver."
        },
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Persisted 64-character batch ID. Keep it unchanged on retry."
        },
        "sequencia": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Next positive installation sequence, in order."
        },
        "anterior": {
          "tipo": "string",
          "obrigatorio": true,
          "nulo": true,
          "desc": "Previous persisted batch ID, null for the first batch."
        },
        "inventario": {
          "tipo": "object",
          "obrigatorio": true,
          "desc": "Normalized inventario-1 from the client: agente, itens and cobertura. Item types: mcp, skill, plugin, dependencia or configuracao. Configuration contains only its hash, fixed categories and selected destination domains. Maximum 500 items and 1 MiB."
        },
        "acoes": {
          "tipo": "AcaoMonitor[]",
          "desc": "Required only for lote-2; forbidden in lote-1. From 1 to 64 distinct native metadata events. No prompts, transcripts, raw arguments, local paths or output text."
        }
      },
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "Exactly the submitted batch ID."
        },
        "sequencia": {
          "tipo": "int",
          "desc": "Exactly the submitted installation sequence."
        },
        "numero": {
          "tipo": "int",
          "desc": "Committed project cursor assigned under its transaction lock."
        }
      },
      "erros": {
        "400": "Invalid field, cursor or bounded request body.",
        "401": "A valid account session or installation credential is required.",
        "403": "Origin or CSRF proof is invalid for a human write.",
        "404": "The project or installation does not belong to this account.",
        "409": "The project, installation or sequence limit prevents the operation.",
        "429": "The daily budget is exhausted. Preserve pending local batches.",
        "503": "Monitoring is unavailable. Preserve the previous state and retry."
      },
      "exemplo": "curl --fail -H \"Authorization: Bearer INSTALLATION_TOKEN\" -H \"Content-Type: application/json\" --data-binary @lote.json \"$ORIGIN/api/monitor/inventario\"",
      "returns": "{ id, sequencia, numero }",
      "url": "https://staging.agentalog.com/api/monitor/inventario",
      "auth_detail": "Private mmi_ credential in Authorization: Bearer, restricted to one installation and project. The account issues it after recent human sign-in. It cannot approve, buy or issue another credential."
    },
    {
      "method": "GET",
      "path": "/api/monitor/projetos/:projeto/consultas",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "List your project's event readers without their secrets.",
      "desc": "Private, no-store and no CORS grant. The optional project event reader must be configured. Installation tokens and wide API keys cannot manage readers. At most 64 records. No last-used tracking or write on read.",
      "retorno": {
        "consultas": {
          "tipo": "object[]",
          "desc": "Reader id, criado_em, expira_em (Unix seconds) and ativa. No token or digest."
        }
      },
      "erros": {
        "400": "Unknown field or invalid bounded request.",
        "401": "Sign in with the existing account. Issuance and revocation require authentication within 2 hours.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The project or reader does not belong to this account.",
        "409": "Three active or 64 retained readers already exist in this project.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "The optional reader or current account authorization is unavailable."
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/consultas\", {credentials:\"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ consultas }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/consultas",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/consultas",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Issue one credential to read this project's event cursor.",
      "desc": "Private, no-store and no CORS grant. The optional project event reader must be configured. Installation tokens and wide API keys cannot manage readers. Requires recent authentication, CSRF and exact empty JSON. Return the secret once. Store it privately with mode 0600. At most three active readers per project. The mmq_ credential expires after 30 days and only permits GET /api/monitor/projetos/:projeto/eventos. It cannot ingest, approve, buy or issue credentials. A timeout can leave an issued reader without its secret; list and revoke it before another issuance.",
      "corpo": {},
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "Credential contract: consulta-inventario-1."
        },
        "consulta": {
          "tipo": "string",
          "desc": "Reader ID, 32 lower-case hexadecimal characters."
        },
        "projeto": {
          "tipo": "string",
          "desc": "The credential's single private project."
        },
        "token": {
          "tipo": "string",
          "desc": "Private mmq_ bearer secret. Returned only on issuance."
        },
        "expira_em": {
          "tipo": "int",
          "desc": "Credential expiry timestamp in Unix seconds."
        }
      },
      "erros": {
        "400": "Unknown field or invalid bounded request.",
        "401": "Sign in with the existing account. Issuance and revocation require authentication within 2 hours.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The project or reader does not belong to this account.",
        "409": "Three active or 64 retained readers already exist in this project.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "The optional reader or current account authorization is unavailable."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/consultas\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:\"{}\"});",
      "exemploLinguagem": "js",
      "returns": "{ esquema, consulta, projeto, token, expira_em }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/consultas",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/consultas/:consulta/revogar",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        },
        "consulta": {
          "desc": "Reader ID inside this owned project."
        }
      },
      "summary": "Revoke one project event reader.",
      "desc": "Private, no-store and no CORS grant. The optional project event reader must be configured. Installation tokens and wide API keys cannot manage readers. Requires recent authentication, CSRF and exact empty JSON. Repeated revocation does not write. An already expired or invalidated reader remains inactive without another write. This preserves inventory, events, local files and purchased rights.",
      "corpo": {},
      "retorno": {
        "revogada": {
          "tipo": "bool",
          "desc": "True when this credential can no longer read events."
        }
      },
      "erros": {
        "400": "Unknown field or invalid bounded request.",
        "401": "Sign in with the existing account. Issuance and revocation require authentication within 2 hours.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The project or reader does not belong to this account.",
        "409": "Three active or 64 retained readers already exist in this project.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "The optional reader or current account authorization is unavailable."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/consultas/READER_ID/revogar\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:\"{}\"});",
      "exemploLinguagem": "js",
      "returns": "{ revogada }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/consultas/:consulta/revogar",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/monitor/projetos/:projeto/webhooks",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Read your project's webhook status and recent delivery results.",
      "desc": "Private, no-store and no CORS grant. Requires the configured optional webhook service. Only the human account owner can manage destinations. Installation tokens and API keys are refused. At most 16 destination records and ten delivery records. Returns the domain without the URL path or signing key. Reads perform no write.",
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "webhooks-inventario-1."
        },
        "destinos": {
          "tipo": "object[]",
          "desc": "Scoped ID, domain, active state and Unix creation, expiry and revocation times."
        },
        "envios": {
          "tipo": "object[]",
          "desc": "Scoped delivery and webhook IDs, event number or null for the test, state, attempts, Unix times and optional HTTP status. No remote response body."
        }
      },
      "erros": {
        "400": "Invalid field, request ID or destination. Use public HTTPS on port 443 without a query or fragment.",
        "401": "Sign in with the existing account. Creation and revocation require authentication within 2 hours.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The project or webhook does not belong to this account.",
        "409": "An active destination exists, 16 retained destinations exist, or this request ID has another destination.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "The optional webhook or current account authorization is unavailable."
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/webhooks\", {credentials:\"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ esquema, destinos, envios }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/webhooks",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/webhooks",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        }
      },
      "summary": "Create one signed webhook and download its private signing key.",
      "desc": "Private, no-store and no CORS grant. Requires the configured optional webhook service. Only the human account owner can manage destinations. Installation tokens and API keys are refused. Requires recent authentication and CSRF. Generate and retain one random request ID. Retry an uncertain request only with the same ID and exact URL; this returns the same key without another test or registration. One active destination per project, valid for 30 days. Creation queues a separate signed test. Changed inventory, activity that needs attention and changed incomplete coverage use the same committed event as the cursor. The initial reference and routine approved actions do not notify. Delivery uses Standard Webhooks headers webhook-id, webhook-timestamp and webhook-signature. Verify the signature and timestamp before use, then deduplicate webhook-id before any effect. Lost receipts can repeat a delivery. At most six attempts share the global 512 daily attempts with email. Public HTTPS only; no private network or redirect. Recover missing events through the cursor.",
      "corpo": {
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Random request ID: 32 lower-case hexadecimal characters. Preserve it for an explicit retry."
        },
        "url": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Public HTTPS destination, at most 512 characters. No credentials, IP address, query, fragment or nonstandard port."
        }
      },
      "retorno": {
        "esquema": {
          "tipo": "string",
          "desc": "webhook-credencial-1."
        },
        "projeto": {
          "tipo": "string",
          "desc": "The single private project."
        },
        "webhook": {
          "tipo": "string",
          "desc": "The destination ID."
        },
        "segredo": {
          "tipo": "string",
          "desc": "Private whsec_ signing key. Store outside the repository and logs. Only creation or its explicit identical retry returns it."
        },
        "expira_em": {
          "tipo": "int",
          "desc": "Expiry timestamp in Unix seconds."
        }
      },
      "erros": {
        "400": "Invalid field, request ID or destination. Use public HTTPS on port 443 without a query or fragment.",
        "401": "Sign in with the existing account. Creation and revocation require authentication within 2 hours.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The project or webhook does not belong to this account.",
        "409": "An active destination exists, 16 retained destinations exist, or this request ID has another destination.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "The optional webhook or current account authorization is unavailable."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nconst id = crypto.randomUUID().replaceAll(\"-\",\"\");\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/webhooks\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:JSON.stringify({id,url:\"https://receiver.example/events\"})});",
      "exemploLinguagem": "js",
      "returns": "{ esquema, projeto, webhook, segredo, expira_em }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/webhooks",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/webhooks/:webhook/revogar",
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private project ID owned by the signed-in account."
        },
        "webhook": {
          "desc": "Webhook ID in this owned project."
        }
      },
      "summary": "Stop future sends to one project webhook.",
      "desc": "Private, no-store and no CORS grant. Requires the configured optional webhook service. Only the human account owner can manage destinations. Installation tokens and API keys are refused. Requires recent authentication, CSRF and exact empty JSON. Revocation prevents a reserved delivery from starting. A request already in flight can still arrive. Repeated revocation performs no write. Inventory, email, event readers and purchased rights remain available.",
      "corpo": {},
      "retorno": {
        "revogado": {
          "tipo": "bool",
          "desc": "True when this destination cannot start another delivery."
        }
      },
      "erros": {
        "400": "Invalid field, request ID or destination. Use public HTTPS on port 443 without a query or fragment.",
        "401": "Sign in with the existing account. Creation and revocation require authentication within 2 hours.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The project or webhook does not belong to this account.",
        "409": "An active destination exists, 16 retained destinations exist, or this request ID has another destination.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "The optional webhook or current account authorization is unavailable."
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/webhooks/WEBHOOK_ID/revogar\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:\"{}\"});",
      "exemploLinguagem": "js",
      "returns": "{ revogado }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/webhooks/:webhook/revogar",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "auth": "monitor_notices",
      "grupo": "Notice delivery service",
      "erros": {
        "400": "Invalid bounded JSON, receipt, result or query.",
        "401": "The dedicated product notice credential is absent or invalid.",
        "405": "Only POST is permitted.",
        "409": "The reservation expired or the project or installation is no longer active.",
        "413": "The request body exceeds 4 KiB.",
        "415": "Content-Type must be application/json.",
        "429": "The shared daily reservation or delivery-attempt budget is exhausted. No send is authorized.",
        "503": "Notice delivery is unavailable or another service operation is active."
      },
      "method": "POST",
      "path": "/api/monitor/avisos/reivindicar",
      "summary": "Reserve at most one committed notice for the existing product mail service.",
      "desc": "Private and no-store. Set ORIGIN to the fixed service authority https://api.agentalog.com. Dedicated service only; no customer or MCP tool authority. Exact empty JSON and no query. Reads the indexed pending range, then revalidates account epoch, project and installation. MAT covers changes after the initial reference and native observations that need attention, including unlinked items. Approved routine activity stays in the private cursor without mail. Active human-selected watch links add catalog context; they are optional. Empty polling writes nothing. Reservation lasts two minutes. Reply contains bounded event metadata, owner ID and reservation proof, never email or installation credentials. No send occurs here.",
      "corpo": {},
      "retorno": {
        "aviso": {
          "tipo": "object",
          "nulo": true,
          "desc": "Null when no eligible notice exists; otherwise produto, projeto, numero, lease, dono, nome and evento. Maximum 4 MiB."
        }
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/avisos/reivindicar\", {method:\"POST\", redirect:\"manual\", headers:{\"Authorization\":\"Bearer NOTICE_SERVICE_TOKEN\",\"Content-Type\":\"application/json\"}, body:JSON.stringify({})});",
      "exemploLinguagem": "js",
      "returns": "{ aviso }",
      "url": "https://staging.agentalog.com/api/monitor/avisos/reivindicar",
      "auth_detail": "Dedicated mmn_ bearer credential for the existing product mail service. Only reserve, start and confirm one product's notices. Account cookies, API keys and installation tokens are refused."
    },
    {
      "auth": "monitor_notices",
      "grupo": "Notice delivery service",
      "erros": {
        "400": "Invalid bounded JSON, receipt, result or query.",
        "401": "The dedicated product notice credential is absent or invalid.",
        "405": "Only POST is permitted.",
        "409": "The reservation expired or the project or installation is no longer active.",
        "413": "The request body exceeds 4 KiB.",
        "415": "Content-Type must be application/json.",
        "429": "The shared daily reservation or delivery-attempt budget is exhausted. No send is authorized.",
        "503": "Notice delivery is unavailable or another service operation is active."
      },
      "method": "POST",
      "path": "/api/monitor/avisos/iniciar",
      "summary": "Revalidate the reservation before one mail attempt.",
      "desc": "Private and no-store. Account epoch, project, installation and recorded notice evidence must remain valid. Records send intent and reserves one of 512 shared delivery attempts per UTC day in the same transaction before authorizing mail. Retries consume this same budget. Exhaustion preserves preparation and returns 429 without authorizing a send. Missing or invalid budget returns 503. Returns only catalog links still active from the committed event; the list can be empty for an unlinked change or native observation. It does not send mail or grant tool approval. After two minutes, interrupted preparation can be recovered and send intent without a receipt is eligible for uncertain recovery. Hourly maintenance performs bounded recovery. Uncertain sends are not automatically resent.",
      "corpo": {
        "projeto": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Reserved private project ID: 32 hexadecimal characters."
        },
        "numero": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Reserved positive committed event number."
        },
        "lease": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Private reservation proof: 64 hexadecimal characters."
        }
      },
      "retorno": {
        "autorizado": {
          "tipo": "bool",
          "desc": "True only after the send intent is durably recorded."
        },
        "vigias": {
          "tipo": "object[]",
          "desc": "Zero to 500 active item/alvo pairs; a subset of the committed event links."
        }
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/avisos/iniciar\", {method:\"POST\", redirect:\"manual\", headers:{\"Authorization\":\"Bearer NOTICE_SERVICE_TOKEN\",\"Content-Type\":\"application/json\"}, body:JSON.stringify({projeto:\"PROJECT_ID\",numero:1,lease:\"RESERVATION_PROOF\"})});",
      "exemploLinguagem": "js",
      "returns": "{ autorizado, vigias }",
      "url": "https://staging.agentalog.com/api/monitor/avisos/iniciar",
      "auth_detail": "Dedicated mmn_ bearer credential for the existing product mail service. Only reserve, start and confirm one product's notices. Account cookies, API keys and installation tokens are refused."
    },
    {
      "auth": "monitor_notices",
      "grupo": "Notice delivery service",
      "erros": {
        "400": "Invalid bounded JSON, receipt, result or query.",
        "401": "The dedicated product notice credential is absent or invalid.",
        "405": "Only POST is permitted.",
        "409": "The reservation expired or the project or installation is no longer active.",
        "413": "The request body exceeds 4 KiB.",
        "415": "Content-Type must be application/json.",
        "429": "The shared daily reservation or delivery-attempt budget is exhausted. No send is authorized.",
        "503": "Notice delivery is unavailable or another service operation is active."
      },
      "method": "POST",
      "path": "/api/monitor/avisos/finalizar",
      "summary": "Confirm the result of the single reserved mail attempt.",
      "desc": "Private and no-store. Accept enviado, adiado, rejeitado or incerto. enviado means provider acceptance, not inbox delivery. adiado is valid only when no send occurred: retry after one hour, with at most six reservations. rejeitado discards the notice. incerto prevents automatic resend. A late matching receipt can confirm an uncertain send. Exact confirmation replay does not write or extend a deadline.",
      "corpo": {
        "projeto": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Reserved private project ID: 32 hexadecimal characters."
        },
        "numero": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Reserved positive committed event number."
        },
        "lease": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Private reservation proof: 64 hexadecimal characters."
        },
        "resultado": {
          "tipo": "string",
          "obrigatorio": true,
          "valores": [
            "enviado",
            "adiado",
            "rejeitado",
            "incerto"
          ],
          "desc": "Observed mail result. Never infer success after a timeout."
        }
      },
      "retorno": {
        "estado": {
          "tipo": "string",
          "valores": [
            "enviado",
            "pendente",
            "descartado",
            "incerto"
          ],
          "desc": "Durably confirmed current notice state."
        }
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/avisos/finalizar\", {method:\"POST\", redirect:\"manual\", headers:{\"Authorization\":\"Bearer NOTICE_SERVICE_TOKEN\",\"Content-Type\":\"application/json\"}, body:JSON.stringify({projeto:\"PROJECT_ID\",numero:1,lease:\"RESERVATION_PROOF\",resultado:\"incerto\"})});",
      "exemploLinguagem": "js",
      "returns": "{ estado }",
      "url": "https://staging.agentalog.com/api/monitor/avisos/finalizar",
      "auth_detail": "Dedicated mmn_ bearer credential for the existing product mail service. Only reserve, start and confirm one product's notices. Account cookies, API keys and installation tokens are refused."
    },
    {
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private owned project ID: 32 lower-case hexadecimal characters."
        },
        "instalacao": {
          "desc": "Current-epoch installation in this project: 32 hexadecimal characters. A decision requires an active credential."
        }
      },
      "erros": {
        "400": "Invalid field, bounded JSON or cursor.",
        "401": "A human cookie is required. Reauthenticate within 2 hours before a decision.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The owned active project or installation was not found.",
        "405": "Only the declared method is permitted.",
        "409": "The observed candidate, sequence or review version changed; coverage is incomplete; or a cursor is in the future.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "Review is unconfigured or unavailable. No permission is granted."
      },
      "method": "GET",
      "path": "/api/monitor/projetos/:projeto/instalacoes/:instalacao/revisoes",
      "summary": "Compare observed candidates with your reviewed reference and read decision receipts.",
      "desc": "Private and no-store. Requires the human account cookie. Expired or revoked current-epoch installations remain readable. This read does not authorize a new decision or signed policy. One request reads at most 500 current candidates and 500 reviewed references. Each candidate includes the server's fingerprint, comparison state and changed fields. Incomplete coverage cannot grant approval. No installation secret or local path is returned. Read at most five audit receipts after the cursor. Future cursors fail. This reads no public catalog and writes nothing. Available only when the optional review service is configured.",
      "colecao": {
        "porPagina": 5,
        "anda": "desde"
      },
      "query": {
        "desde": {
          "tipo": "int",
          "padrao": 0,
          "desc": "Last consumed decision number, from 0 to 600."
        },
        "limite": {
          "tipo": "int",
          "padrao": 5,
          "desc": "Maximum audit receipts in this page, from 1 to 5."
        }
      },
      "retorno": {
        "esquema": {
          "tipo": "string",
          "valores": [
            "revisoes-inventario-1"
          ],
          "desc": "Review state contract."
        },
        "instalacao": {
          "tipo": "string",
          "desc": "The owned installation."
        },
        "sequencia": {
          "tipo": "int",
          "desc": "Current inventory sequence. Send this exact number in a decision."
        },
        "versao": {
          "tipo": "int",
          "desc": "Current review version. Send this exact number in a decision."
        },
        "candidatos": {
          "tipo": "object[]",
          "desc": "At most 500 records: item, candidato, estado and campos. Each item uses inventario-1 metadata, including selected configuration hashes and fixed permission categories. estado is novo, igual, alterado or incompleto. campos identifies changed captured metadata. Use candidato in the human decision; do not recompute it in the browser."
        },
        "revisoes": {
          "tipo": "object[]",
          "desc": "At most 500 item/candidato/decisao/responsavel/decidido_em/numero records. Each item uses inventario-1 metadata. An observed upgrade preserves the previous reviewed reference."
        },
        "historico": {
          "tipo": "object[]",
          "desc": "Up to five receipts: id, item, candidato, decisao, quando, numero and responsavel. No request hash or secret."
        },
        "cursor": {
          "tipo": "int",
          "desc": "Last returned receipt number. Use it as desde for the next page."
        },
        "fim": {
          "tipo": "bool",
          "desc": "True at the current end of the audit."
        }
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/instalacoes/INSTALLATION_ID/revisoes?desde=0&limite=5\", {credentials:\"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ esquema, instalacao, sequencia, versao, candidatos, revisoes, historico, cursor, fim }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/instalacoes/:instalacao/revisoes",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "auth": "session",
      "grupo": "Installed agents",
      "params": {
        "projeto": {
          "desc": "Private owned project ID: 32 lower-case hexadecimal characters."
        },
        "instalacao": {
          "desc": "Current-epoch installation in this project: 32 hexadecimal characters. A decision requires an active credential."
        }
      },
      "erros": {
        "400": "Invalid field, bounded JSON or cursor.",
        "401": "A human cookie is required. Reauthenticate within 2 hours before a decision.",
        "403": "Origin or CSRF proof is invalid.",
        "404": "The owned active project or installation was not found.",
        "405": "Only the declared method is permitted.",
        "409": "The observed candidate, sequence or review version changed; coverage is incomplete; or a cursor is in the future.",
        "413": "Body exceeds 4 KiB.",
        "415": "Content-Type must be application/json.",
        "429": "The shared daily registration budget is exhausted.",
        "503": "Review is unconfigured or unavailable. No permission is granted."
      },
      "method": "POST",
      "path": "/api/monitor/projetos/:projeto/instalacoes/:instalacao/revisoes",
      "summary": "Approve exact observed content or suspend it with a durable human receipt.",
      "desc": "Private and no-store. Requires a human cookie authenticated within 2 hours, exact Origin and CSRF. Refuses installation bearer credentials and API keys. Recheck candidate fingerprint, inventory sequence and review version under the project lock. Partial coverage cannot grant approval. A suspension can retain a reviewed item after removal. Retry with the same ID and exact body to obtain the original receipt without writes. A changed body under the same ID fails. Limits: 500 references, 600 total decisions per installation, 2 MiB stored state, and the shared 512 registrations per day. No tool runs or is installed by this endpoint. A model result never grants permission.",
      "corpo": {
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Generate 32 lower-case hexadecimal characters once per human decision. Keep it on retry."
        },
        "item": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Received inventory item ID: 64 hexadecimal characters."
        },
        "candidato": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "64-character SHA-256 fingerprint from @mm/revisao/inventario-candidato. Covers identity, content hash and all captured metadata; it is not the content hash alone."
        },
        "decisao": {
          "tipo": "string",
          "obrigatorio": true,
          "valores": [
            "aprovar",
            "suspender"
          ],
          "desc": "Explicit human decision for the selected candidate."
        },
        "versao": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Review version read for this installation, from 0 to 600."
        },
        "sequencia": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Positive inventory sequence shown to the reviewer."
        }
      },
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "Decision retry ID: 32 lower-case hexadecimal characters."
        },
        "item": {
          "tipo": "string",
          "desc": "The reviewed inventory item ID: 64 hexadecimal characters."
        },
        "candidato": {
          "tipo": "string",
          "desc": "Fingerprint of the exact content and captured metadata."
        },
        "decisao": {
          "tipo": "string",
          "valores": [
            "aprovar",
            "suspender"
          ],
          "desc": "The human decision."
        },
        "quando": {
          "tipo": "int",
          "desc": "Decision timestamp in Unix seconds, assigned by the server."
        },
        "numero": {
          "tipo": "int",
          "desc": "The installation's durable review version."
        },
        "responsavel": {
          "tipo": "string",
          "desc": "Account identity from the authenticated cookie, never the body."
        }
      },
      "exemplo": "const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\nawait fetch(\"$ORIGIN/api/monitor/projetos/PROJECT_ID/instalacoes/INSTALLATION_ID/revisoes\", {method:\"POST\", credentials:\"same-origin\", headers:{\"Content-Type\":\"application/json\",\"X-CSRF-Token\":csrf}, body:JSON.stringify({id:crypto.randomUUID().replaceAll(\"-\",\"\"),item:\"ITEM_ID\",candidato:\"CANDIDATE_FINGERPRINT\",decisao:\"aprovar\",versao:0,sequencia:1})});",
      "exemploLinguagem": "js",
      "returns": "{ id, item, candidato, decisao, quando, numero, responsavel }",
      "url": "https://staging.agentalog.com/api/monitor/projetos/:projeto/instalacoes/:instalacao/revisoes",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/monitor/politica",
      "auth": "monitor_installation",
      "grupo": "Installed agents",
      "summary": "Read a signed short-lived policy for this installation only.",
      "desc": "Private and no-store. Set ORIGIN to https://api.agentalog.com. Exact path, no query and no write. Revalidate credential expiry, revocation and account epoch on each read. Ed25519 signature; at most 500 rules, 1 MiB and 15 minutes, shortened to credential expiry. Client 0.4.0 pins the public key and verifies product/project/installation/epoch through its trusted connection. Reject expired, future, changed, differently scoped or older policies. An already cached policy can remain valid until expiry after an online revocation. policy downloads a signed decision. check recollects the selected configurations and target item before checking their exact candidates. The policy and check commands do not activate tools or install hooks. Optional hooks-install can install project hooks after preview consent. In enforce mode, covered calls require exact reviewed configuration and tool metadata. Removing a reviewed configuration prevents confirmation until that configuration is restored and reviewed. This does not freeze a remote MCP's code or guarantee universal blocking. Available only when the optional review service is configured.",
      "retorno": {
        "esquema": {
          "tipo": "string",
          "valores": [
            "politica-assinada-1"
          ],
          "desc": "Signed envelope contract."
        },
        "politica": {
          "tipo": "object",
          "desc": "politica-inventario-1: produto, projeto, instalacao, epoca, versao, emitida_em, expira_em and revisoes. Rules contain exact item metadata, candidate fingerprint, human decision, responsible account, decision timestamp and number."
        },
        "assinatura": {
          "tipo": "string",
          "desc": "86 base64url characters. Verify with the separately trusted Ed25519 public key; never trust a key supplied by an untrusted envelope."
        }
      },
      "erros": {
        "400": "Unexpected query.",
        "401": "The installation credential is absent, expired or revoked.",
        "405": "Only GET is permitted.",
        "503": "The optional review service is unconfigured or unavailable."
      },
      "exemplo": "await fetch(\"$ORIGIN/api/monitor/politica\", {headers:{\"Authorization\":\"Bearer INSTALLATION_TOKEN\"}, redirect:\"manual\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ esquema, politica, assinatura }",
      "url": "https://staging.agentalog.com/api/monitor/politica",
      "auth_detail": "Private mmi_ credential in Authorization: Bearer, restricted to one installation and project. The account issues it after recent human sign-in. It cannot approve, buy or issue another credential."
    },
    {
      "method": "GET",
      "path": "/api/a2a/agents",
      "auth": "none",
      "colecao": {
        "porPagina": 50,
        "teto": 20000,
        "anda": "_links.next"
      },
      "grupo": "A2A agents",
      "summary": "The A2A agent index: agents that publish an AgentCard, with text search and filters.",
      "desc": "Collected from public A2A registries and served as it comes — no review queue hides a record; quality is the order, never visibility. One row per agent, merged across the registries that list it: `fontes` says which, and `creditos` carries each one's license, which travels with the data. Values inside one parameter are OR'd, different parameters are AND'd. Cached for 60 seconds. A MAT catalog read, served by the index host `https://api.agentalog.com`; this host forwards the call there.",
      "query": {
        "q": {
          "tipo": "string",
          "desc": "Substring of the name, description, key, publisher or the card's skills, in any letter case (`%` and `_` are taken literally); up to 80 characters.",
          "exemplo": "weather"
        },
        "saude": {
          "tipo": "string",
          "desc": "Health the registries measured: `sim` answered, `nao` did not, `sem_medida` never measured. Comma-separated values are OR'd (up to 12, each up to 200 characters).",
          "valores": [
            "sim",
            "nao",
            "sem_medida"
          ]
        },
        "protocolo": {
          "tipo": "string",
          "desc": "A2A protocol version as normalized (`0.3`, `1.0`…); `/api/a2a/facets` lists the ones present. Comma-separated values are OR'd (up to 12, each up to 200 characters).",
          "exemplo": "0.3,1.0"
        },
        "fonte": {
          "tipo": "string",
          "desc": "Only agents listed by this registry. Comma-separated values are OR'd (up to 12, each up to 200 characters).",
          "valores": [
            "a2a_registry",
            "a2a_global",
            "agenstry"
          ]
        },
        "tag": {
          "tipo": "string",
          "desc": "Exact tag of the card's skills, case-sensitive; `/api/a2a/facets` lists the 40 most used. Comma-separated values are OR'd (up to 12, each up to 200 characters).",
          "exemplo": "x402"
        },
        "publicador": {
          "tipo": "string",
          "desc": "Exact publisher, as `publicador` shows it. Comma-separated values are OR'd (up to 12, each up to 200 characters)."
        },
        "skills": {
          "tipo": "string",
          "desc": "`1` keeps only agents whose card lists at least one skill.",
          "valores": [
            "1"
          ]
        },
        "limit": {
          "tipo": "int",
          "desc": "Items per page, 1–50; more is capped at 50, anything else means 20.",
          "padrao": 20
        },
        "offset": {
          "tipo": "int",
          "desc": "Offset, capped at 20000 (a larger value reads as 20000). Prefer `_links.next`.",
          "padrao": 0
        }
      },
      "retorno": "PaginaDeAgentesA2A",
      "exemplo": "curl -s '$ORIGIN/api/a2a/agents?saude=sim&protocolo=0.3,1.0&limit=5'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "returns": "{ ok, total, count, items[{chave,dominio,nome,descricao,url,cartao,publicador,protocolo,saudavel,conforme,verificado,uptime,skills_n,tags,fontes,creditos,visto_em}], _links }",
      "url": "https://staging.agentalog.com/api/a2a/agents",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/a2a/agents/:chave",
      "auth": "none",
      "grupo": "A2A agents",
      "summary": "One A2A agent: its card's skills and capabilities, protocol, health and the registries that list it.",
      "desc": "The same row as the list plus what the card declares: every skill, the `capabilities` object, the protocol version as written, the documentation and icon URLs, and when we first saw it. Cached for 60 seconds; a MAT catalog read, like the list.",
      "params": {
        "chave": {
          "tipo": "string",
          "desc": "The agent's `chave` from `/api/a2a/agents` — usually the card's domain. URL-encode it; up to 200 characters are read.",
          "exemplo": "coinrailz.com"
        }
      },
      "retorno": "FichaDeAgenteA2A",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "No agent is indexed under that key (`error: not_found`).",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/a2a/agents/coinrailz.com",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ ok, agent{chave,dominio,nome,descricao,url,cartao,publicador,protocolo,saudavel,conforme,verificado,uptime,skills_n,tags,fontes,creditos,visto_em,protocolo_declarado,documentacao,icone,capacidades,skills,primeiro_em} }",
      "url": "https://staging.agentalog.com/api/a2a/agents/:chave",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/a2a/facets",
      "auth": "none",
      "grupo": "A2A agents",
      "summary": "How many A2A agents exist per health state, protocol, registry, tag and publisher.",
      "desc": "The counts behind the filters of `/api/a2a/agents`, over the whole index — no filter applies here. The index host checks collection checkpoints about every 9 minutes and recounts after a change or once a day. The last valid response survives restarts on disk; while it renews, a previously confirmed response is served for up to 6 hours. Free and outside the MAT read allowance. This host answers with a 308 to the index host `https://api.agentalog.com` — follow the redirect.",
      "retorno": "FacetasA2A",
      "erros": {
        "503": "No count in memory yet and the database did not answer; retry after `Retry-After` seconds."
      },
      "exemplo": "curl -sL $ORIGIN/api/a2a/facets",
      "returns": "{ ok, facets, _links }",
      "url": "https://staging.agentalog.com/api/a2a/facets",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/a2a/acervo",
      "auth": "none",
      "colecao": {
        "porPagina": 50,
        "teto": 50000,
        "anda": "offset"
      },
      "grupo": "A2A agents",
      "summary": "What came along with the A2A registries — MCP servers, skills, paid APIs, workflows, repositories — matched to this catalog.",
      "desc": "Agent registries ship more than agents: Agenstry's feed also carries MCP servers, skills, paid APIs and workflows, and the curated GitHub lists cite repositories and domains. Every item is kept and shown with its source and license; `no_catalogo` says whether this catalog already lists it (same GitHub repository or same URL) — provenance, never a visibility filter. Filters are AND'd, one value each. Items the catalog does not have yet come first; `total` counts the filter and paging is by `offset` (there is no `next` link). Cached for 60 seconds; a MAT catalog read.",
      "query": {
        "kind": {
          "tipo": "string",
          "desc": "What the item is: see `kind` in the item.",
          "valores": [
            "mcp",
            "skill",
            "paid_api",
            "workflow",
            "repo",
            "semente",
            "lista"
          ]
        },
        "fonte": {
          "tipo": "string",
          "desc": "Only the items of this source.",
          "valores": [
            "agenstry",
            "a2a_github"
          ]
        },
        "q": {
          "tipo": "string",
          "desc": "Substring of the name, description or key, in any letter case (`%` and `_` are taken literally); up to 80 characters.",
          "exemplo": "postgres"
        },
        "casou": {
          "tipo": "string",
          "desc": "`1` only items this catalog already lists, `0` only the ones it does not.",
          "valores": [
            "0",
            "1"
          ]
        },
        "limit": {
          "tipo": "int",
          "desc": "Items per page, 1–50; more is capped at 50, anything else means 20.",
          "padrao": 20
        },
        "offset": {
          "tipo": "int",
          "desc": "Offset, capped at 50000 (a larger value reads as 50000).",
          "padrao": 0
        }
      },
      "retorno": "PaginaDoAcervoA2A",
      "exemplo": "curl -s '$ORIGIN/api/a2a/acervo?kind=paid_api&casou=0&limit=5'",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "returns": "{ ok, total, count, items[{fonte,credito,chave,kind,nome,descricao,url,dominio,repo,no_catalogo,visto_em}], _links }",
      "url": "https://staging.agentalog.com/api/a2a/acervo",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/a2a/stats",
      "auth": "none",
      "grupo": "A2A agents",
      "summary": "Where the A2A index comes from: records per source, credit and license, and each source's last collection round.",
      "desc": "An index that does not show where its data came from asks for trust instead of giving proof. `bruto_por_fonte` counts the raw records kept per source, `acervo_por_kind` sizes `/api/a2a/acervo`, and `coleta` gives each source's last round: when, how many, how long, the error if it failed and when the next is due. The same collector reads the MCP indexes, so they appear here too, with `credito: null` — `/api/indices` credits them. The index host checks collection checkpoints about every 9 minutes and recounts after a change or once a day. The last valid response survives restarts on disk; while it renews, a previously confirmed response is served for up to 6 hours. Free and outside the MAT read allowance. This host answers with a 308 to the index host `https://api.agentalog.com` — follow the redirect.",
      "retorno": "EstadoDaColetaA2A",
      "erros": {
        "503": "No count in memory yet and the database did not answer; retry after `Retry-After` seconds."
      },
      "exemplo": "curl -sL $ORIGIN/api/a2a/stats",
      "returns": "{ ok, agentes, agentes_com_skills, bruto_por_fonte[{fonte,itens,credito}], acervo_por_kind[{kind,itens,no_catalogo}], coleta[{fonte,credito,rodada_em,itens,novos,mudados,ms,http,erro,proxima_em}], _links }",
      "url": "https://staging.agentalog.com/api/a2a/stats",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/listings",
      "auth": "session_ou_x402",
      "summary": "Registers an MCP server, a skill or a plugin in the catalog. It comes in as `pending`.",
      "grupo": "Publish",
      "desc": "Automatic review approves supported low-risk MCP listings; uncertain cases wait for a person. Poll `status_api` (`GET /api/listings/:id/status`, no credential) to learn the decision. A person or agent can submit without an account for US$ 0.10, paid through x402 or prepaid credit; with an account, it is free. Each owner can submit once a day and keep up to three submissions in the queue. For a skill, provide its SKILL.md URL. The service checks the body and quota before charging. An invalid body returns 400; an exhausted quota returns 429.",
      "corpo": {
        "kind": {
          "tipo": "string",
          "desc": "What is being registered.",
          "valores": [
            "mcp",
            "skill",
            "plugin",
            "okf"
          ],
          "obrigatorio": true
        },
        "url": {
          "tipo": "string",
          "desc": "MCP endpoint, SKILL.md URL, the plugin's repository or the OKF bundle's `index.md`. For an OKF bundle on a domain you control, `POST /api/okf/ping` is free.",
          "obrigatorio": true
        },
        "name": {
          "tipo": "string",
          "desc": "Display name; without it, taken from the source."
        },
        "tagline": {
          "tipo": "string",
          "desc": "One line saying what it is for."
        },
        "body": {
          "tipo": "string",
          "desc": "Long description, optional."
        },
        "category": {
          "tipo": "string",
          "desc": "Category so the listing shows up under the right filter."
        }
      },
      "body": {
        "kind": "mcp",
        "category": "tools",
        "name": "Name",
        "tagline": "One line",
        "url": "https://example.com/mcp"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true` when the request went in."
        },
        "id": {
          "tipo": "string",
          "desc": "ID of the created listing."
        },
        "status": {
          "tipo": "string",
          "desc": "Always `pending`: everything goes through the queue before turning live."
        },
        "status_api": {
          "tipo": "string",
          "desc": "Where to poll for the review, with no credential (`GET /api/listings/:id/status`)."
        }
      },
      "erros": {
        "400": "`kind` or `url` missing, invalid URL, URL that does not answer or refused field.",
        "402": null,
        "429": "1 per day, at most 3 pending — applies to both doors, and is checked before charging.",
        "502": "The payment settled and the write failed. The body carries `transaction`: keep it and talk to support."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/listings -H \"X-PAYMENT: $PAYMENT\" -H 'content-type: application/json' -d '{\"kind\":\"mcp\",\"url\":\"https://example.com/mcp\",\"name\":\"My MCP\"}'",
      "returns": "{ ok, id, status, status_api }",
      "url": "https://staging.agentalog.com/api/listings",
      "auth_detail": "A person can submit with the account cookie or a guest identity. An agent can submit without an account. Both paths use the same submission limits. With an account, submitting is free; without one, it costs US$ 0.10 through x402 or prepaid credit."
    },
    {
      "method": "PATCH",
      "path": "/api/listings/:id",
      "auth": "guest",
      "summary": "Edits a listing of yours. Changing its public content sends it back to moderation.",
      "grupo": "Publish",
      "desc": "The URL and public text are what moderation checks; changing either after approval sends the listing back to `pending`.",
      "params": {
        "id": {
          "desc": "ID of the listing to edit."
        }
      },
      "corpo": {
        "name": {
          "tipo": "string",
          "desc": "New display name."
        },
        "tagline": {
          "tipo": "string",
          "desc": "New summary line."
        },
        "body": {
          "tipo": "string",
          "desc": "New long description."
        },
        "category": {
          "tipo": "string",
          "desc": "New category."
        },
        "url": {
          "tipo": "string",
          "desc": "New URL — changing this sends the listing back to `pending`, as with public text edits."
        },
        "docs_url": {
          "tipo": "string",
          "desc": "Link to the project documentation, shown as **Docs** on the listing page. https only, up to 500 characters; an empty string removes it. It does not send the listing back to moderation."
        }
      },
      "body": {
        "tagline": "…"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true`."
        },
        "id": {
          "tipo": "string",
          "desc": "ID of the edited listing."
        },
        "status": {
          "tipo": "string",
          "desc": "State after the edit; back to `pending` if public content changed."
        }
      },
      "erros": {
        "400": "Invalid field in the body.",
        "401": null,
        "404": "The listing is not yours or does not exist."
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/listings/ID\", {method: \"PATCH\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({tagline: \"now with SSE support\"})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ ok, id, status }",
      "url": "https://staging.agentalog.com/api/listings/:id",
      "auth_detail": "Guest token (`POST /api/guest`) in `X-Guest-Token: mr_…` or `Authorization: Bearer mr_…`. In the browser it also lives in the HttpOnly `mr_guest` cookie, which writes only from this site's exact Origin. A signed-in account (cookie) also works and takes precedence."
    },
    {
      "method": "GET",
      "path": "/api/me/listings",
      "auth": "guest",
      "summary": "The owner's listings in any state, including pending and hidden.",
      "grupo": "Publish",
      "desc": "It is the only route that shows what is not live yet — the public mosaic never does. A temporary guest sees its own submissions here and keeps them when it links an account.",
      "retorno": {
        "items": {
          "tipo": "Anuncio[]",
          "desc": "This owner’s listings, in any state."
        }
      },
      "erros": [
        401
      ],
      "exemplo": "await fetch(\"$ORIGIN/api/me/listings\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ items[{seguranca_nivel?,seguranca_estado?,seguranca_api?,moderation?,verified?,seals?,seal_checked_at?,id,kind,category,name,tagline,body,url,status,origin,origin_id,install,source,transporte,ns,versao,oficial_status,repo_host,topico,linguagem,licenca,repo_topics,repo_slug,stars,forks,prs_abertos,pushed_at,repo_estado,likes,comments,visits,created_at,updated_at,mine,api,go,comments_api,readme_api?,historico?,readme_fonte?,readme_bytes,readme_sha,readme_em,docs_url?,payload}] }",
      "url": "https://staging.agentalog.com/api/me/listings",
      "auth_detail": "Guest token (`POST /api/guest`) in `X-Guest-Token: mr_…` or `Authorization: Bearer mr_…`. In the browser it also lives in the HttpOnly `mr_guest` cookie, which writes only from this site's exact Origin. A signed-in account (cookie) also works and takes precedence."
    },
    {
      "method": "GET",
      "path": "/api/me",
      "auth": "session",
      "summary": "The session's account and, for the admin, the load state.",
      "desc": "The account is the global account; `user.id` is its id — the same id that owns the listings, likes and comments made with it, and the guest's after the claim.",
      "grupo": "Account",
      "retorno": {
        "user": {
          "tipo": "Conta",
          "desc": "The person who owns the session."
        },
        "profile": {
          "tipo": "object",
          "desc": "Global profile: `name`, `locale`, `timeZone`, `theme`, `revision`."
        },
        "admin": {
          "tipo": "bool",
          "desc": "Whether this session is the platform owner's, signed in with a passkey, authenticator or recovery code."
        },
        "carga": {
          "tipo": "Carga",
          "desc": "State of the load sources; admin only.",
          "opcional": true
        }
      },
      "erros": {
        "401": "invalid_session",
        "503": "auth_unavailable"
      },
      "exemplo": "await fetch(\"$ORIGIN/api/me\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ user{id,email}, profile, admin, carga?{fontes,falhas,runs,orcamento} }",
      "url": "https://staging.agentalog.com/api/me",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/me/ui",
      "auth": "session",
      "summary": "The owner's screen preferences: search, filter, sort and theme.",
      "grupo": "Account",
      "desc": "Exists so what the person set up survives an F5 and reopening the app on another device. A refresh is not a new screen — see AGENTS-UI.md. A guest has none: without an account there is nobody to give the data back to later, so the guest stays in the browser's `localStorage` only.",
      "retorno": "PreferenciasUi",
      "erros": [
        401
      ],
      "exemplo": "await fetch(\"$ORIGIN/api/me/ui\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ prefs, api }",
      "url": "https://staging.agentalog.com/api/me/ui",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "PUT",
      "path": "/api/me/ui",
      "auth": "session",
      "summary": "Stores the owner's screen preferences, replacing the previous ones.",
      "grupo": "Account",
      "desc": "It is PUT and not PATCH on purpose: the client sends the whole screen state, not a delta. Cap of 8 KB — this is a screen preference, not a blob store.",
      "corpo": {
        "prefs": {
          "tipo": "object",
          "desc": "The interface state to keep. Opaque to the server: any JSON within the cap works.",
          "obrigatorio": true
        }
      },
      "body": {
        "prefs": {
          "q": "postgres",
          "kind": "mcp",
          "sort": "likes",
          "tema": "escuro"
        }
      },
      "retorno": "Ok",
      "erros": {
        "400": "Body that is not JSON (`bad_json`) or without the `prefs` key (`prefs`).",
        "401": null,
        "405": "Method other than GET or PUT on this route.",
        "413": "Preferences above the 8 KB cap (`grande`)."
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/me/ui\", {method: \"PUT\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({prefs: {sort: \"likes\"}})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/me/ui",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/auth/bootstrap",
      "auth": "none",
      "grupo": "Account",
      "summary": "Prepare the browser for global sign-in.",
      "desc": "Sets a host-only HttpOnly browser cookie. CSRF is bound to the current session. No CORS.",
      "retorno": {
        "csrf": {
          "tipo": "string",
          "desc": "X-CSRF-Token"
        },
        "context": {
          "tipo": "string",
          "desc": "Opaque view context, also in X-MM-Context; not a credential / contexto opaco da vista, não é credencial."
        }
      },
      "erros": {
        "400": "invalid_request",
        "403": "invalid_origin / invalid_csrf",
        "503": "auth_unavailable: a sessão anterior é preservada / the previous session is preserved"
      },
      "returns": "{ csrf, context }",
      "url": "https://staging.agentalog.com/api/auth/bootstrap",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/account/profile",
      "auth": "session",
      "grupo": "Account",
      "exemplo": "await fetch(\"$ORIGIN/api/account/profile\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "summary": "Read your global profile.",
      "desc": "Reads current preferences from the account. Edit them on your account page; products never own a separate profile.",
      "retorno": {
        "_texto": "{profile:{name,locale,timeZone,theme,revision}}"
      },
      "erros": {
        "401": "invalid_session",
        "503": "auth_unavailable"
      },
      "returns": "{profile:{name,locale,timeZone,theme,revision}}",
      "url": "https://staging.agentalog.com/api/account/profile",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/account/avatar",
      "auth": "session",
      "grupo": "Account",
      "exemplo": "await fetch(\"$ORIGIN/api/account/avatar\", {credentials: \"same-origin\"}).then(r => {if (!r.ok) throw new Error(\"HTTP \" + r.status); return r.blob();});",
      "exemploLinguagem": "js",
      "summary": "Read your global profile photo.",
      "desc": "Private WebP, up to 64 KiB, no cache. Change it on your account. No user ID or object URL accepted.",
      "retorno": {
        "_texto": "image/webp; Cache-Control: no-store"
      },
      "erros": {
        "401": "invalid_session",
        "404": "not_found: no photo / sem foto",
        "503": "auth_unavailable"
      },
      "returns": "image/webp; Cache-Control: no-store",
      "url": "https://staging.agentalog.com/api/account/avatar",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/auth/logout",
      "auth": "session",
      "grupo": "Account",
      "exemplo": "// Execute no console da página do produto / Run in the product page console.\n(async () => {\n  const origin = \"$ORIGIN\";\n  const {csrf} = await fetch(origin + \"/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(origin + \"/api/auth/logout\", {\n    method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({})\n  });\n  if (!r.ok) throw new Error(\"Auth HTTP \" + r.status);\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "summary": "Revoke this product session.",
      "desc": "Bootstrap/CSRF must belong to this browser and session. Other product sessions remain active.",
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "true"
        }
      },
      "erros": {
        "400": "invalid_request",
        "403": "invalid_origin / invalid_csrf",
        "503": "auth_unavailable: a sessão anterior é preservada / the previous session is preserved"
      },
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/auth/logout",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/auth/pwa/install",
      "auth": "session",
      "grupo": "Installed app",
      "summary": "Prepare a personal app installation.",
      "desc": "Requires recent sign-in, exact Origin and browser CSRF. Returns a private signed PIN and a no-store manifest address. At most 10 active installations per account and product.",
      "corpo": {
        "path": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Same-origin task path, up to 1600 characters."
        },
        "state": {
          "tipo": "object",
          "obrigatorio": true,
          "desc": "Up to 30 allowlisted preference keys and string values."
        },
        "manifest": {
          "tipo": "object",
          "obrigatorio": true,
          "desc": "Public app name and same-origin icons."
        }
      },
      "retorno": {
        "_texto": "{pin,path,manifest}"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const manifest = await fetch(document.querySelector('link[rel=\"manifest\"]').href).then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/auth/pwa/install\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({path: location.pathname + location.search, state: {}, manifest})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "erros": {
        "400": "invalid_installation_path / invalid_installation_state / invalid_installation_manifest",
        "401": "invalid_session / reauth_required",
        "409": "installation_not_created",
        "503": "auth_unavailable"
      },
      "returns": "{pin,path,manifest}",
      "url": "https://staging.agentalog.com/api/auth/pwa/install",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/auth/pwa/restore",
      "auth": "none",
      "grupo": "Installed app",
      "summary": "Restore an installed app.",
      "desc": "Requires the signed PIN, exact Origin and browser CSRF. Verifies host, product, account status, security version and installation revocation. Keeps the original authentication time. Sensitive actions still require recent sign-in.",
      "corpo": {
        "pin": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Private signed installation credential."
        }
      },
      "retorno": {
        "_texto": "{ok:true,state,path,manifest}; HttpOnly session cookies"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/auth/pwa/restore\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({pin: \"…\"})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "erros": {
        "401": "invalid_installation",
        "403": "invalid_origin / invalid_csrf",
        "503": "auth_unavailable"
      },
      "returns": "{ok:true,state,path,manifest}; HttpOnly session cookies",
      "url": "https://staging.agentalog.com/api/auth/pwa/restore",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/auth/pwa/manifest",
      "auth": "none",
      "grupo": "Installed app",
      "summary": "Read the private installation manifest.",
      "desc": "Requires the installation cookie and its manifest key. Private, no-store. The start URL keeps the PIN in the fragment.",
      "query": {
        "key": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Key in the manifest address that the install or restore call returned."
        }
      },
      "retorno": {
        "_texto": "application/manifest+json"
      },
      "exemplo": "await fetch(\"$ORIGIN/api/auth/pwa/manifest?key=…\", {credentials: \"same-origin\"}).then(r => r.json())",
      "exemploLinguagem": "js",
      "erros": {
        "401": "invalid_installation"
      },
      "returns": "application/manifest+json",
      "url": "https://staging.agentalog.com/api/auth/pwa/manifest",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/account/keys",
      "auth": "session",
      "grupo": "Account",
      "summary": "List your API keys in this product.",
      "desc": "Never returns the key itself: name, last 4 characters, organization, creation, last use (hourly) and whether it still works.",
      "retorno": {
        "keys": {
          "tipo": "object[]",
          "desc": "`id`, `name`, `organizationId`, `last4`, `createdAt`, `lastUsedAt`, `revokedAt`, `active` (false when revoked or stopped by a password change / ending all sessions)."
        }
      },
      "erros": {
        "401": "invalid_session",
        "503": "auth_unavailable"
      },
      "exemplo": "await fetch(\"$ORIGIN/api/account/keys\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ keys }",
      "url": "https://staging.agentalog.com/api/account/keys",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/account/keys/create",
      "auth": "session",
      "grupo": "Account",
      "summary": "Create an API key for agents and scripts.",
      "desc": "Needs a sign-in within the last 2 hours; an organization key also needs a second factor in the session and the owner/admin role with this product enabled. At most 10 live keys per account and product. The key (`secret`) is returned ONCE.",
      "corpo": {
        "name": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Up to 60 characters."
        },
        "organizationId": {
          "tipo": "string",
          "nulo": true,
          "obrigatorio": true,
          "desc": "`null` for an account key."
        }
      },
      "body": {
        "name": "agent",
        "organizationId": null
      },
      "retorno": {
        "key": {
          "tipo": "object",
          "desc": "`id`, `name`, `organizationId`, `last4`, `createdAt`."
        },
        "secret": {
          "tipo": "string",
          "desc": "`mmk_…`, shown once."
        }
      },
      "erros": {
        "400": "invalid_key_name / invalid_organization",
        "401": "invalid_session / reauth_required",
        "403": "invalid_origin / invalid_csrf / organization_forbidden / organization_mfa_required",
        "409": "key_limit_reached",
        "503": "auth_unavailable"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/account/keys/create\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({name: \"agent\", organizationId: null})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ key, secret }",
      "url": "https://staging.agentalog.com/api/account/keys/create",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/account/keys/revoke",
      "auth": "session",
      "grupo": "Account",
      "summary": "Revoke one of your API keys.",
      "desc": "Stops the key at once. Repeating is harmless.",
      "corpo": {
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "The key `id`."
        }
      },
      "body": {
        "id": "…"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "true"
        }
      },
      "erros": {
        "400": "invalid_key_id",
        "401": "invalid_session",
        "403": "invalid_origin / invalid_csrf",
        "404": "key_not_found",
        "503": "auth_unavailable"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/account/keys/revoke\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({id: \"…\"})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/account/keys/revoke",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/account/apps",
      "auth": "session",
      "grupo": "Account",
      "summary": "List the apps connected to your account in this product.",
      "desc": "The MCP clients you signed in with (OAuth), such as claude.ai or ChatGPT. Never returns a token.",
      "retorno": {
        "apps": {
          "tipo": "object[]",
          "desc": "Up to 50: `id`, `nome` (the app; its host when it identifies itself by a metadata document), `criadoEm`, `usadoEm` (hourly, or null)."
        }
      },
      "erros": {
        "401": "invalid_session",
        "503": "auth_unavailable"
      },
      "exemplo": "await fetch(\"$ORIGIN/api/account/apps\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ apps }",
      "url": "https://staging.agentalog.com/api/account/apps",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/account/apps/revoke",
      "auth": "session",
      "grupo": "Account",
      "summary": "Disconnect an app from your account.",
      "desc": "Stops the app's access at once; it asks you to sign in again. Repeating is harmless.",
      "corpo": {
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "The app `id`."
        }
      },
      "body": {
        "id": "…"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "true"
        }
      },
      "erros": {
        "400": "invalid_app_id",
        "401": "invalid_session",
        "403": "invalid_origin / invalid_csrf",
        "404": "app_not_found",
        "503": "auth_unavailable"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/account/apps/revoke\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({id: \"…\"})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/account/apps/revoke",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/account/callouts",
      "auth": "session",
      "grupo": "Account",
      "summary": "List the notices that you closed in this product.",
      "desc": "The keys of the notices that stay closed for your account, on every device, such as the explanation of an area.",
      "retorno": {
        "callouts": {
          "tipo": "string[]",
          "desc": "Up to 200 keys, in alphabetical order."
        }
      },
      "erros": {
        "401": "invalid_session",
        "403": "product_required",
        "503": "auth_unavailable"
      },
      "exemplo": "await fetch(\"$ORIGIN/api/account/callouts\", {credentials: \"same-origin\"}).then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ callouts }",
      "url": "https://staging.agentalog.com/api/account/callouts",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/account/callouts/dismiss",
      "auth": "session",
      "grupo": "Account",
      "summary": "Close a notice for good.",
      "desc": "The notice does not open again for your account in this product. Repeating is harmless.",
      "corpo": {
        "key": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "The notice key: letters, digits and `_.:-`, up to 80."
        }
      },
      "body": {
        "key": "financeiro_expense"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "true"
        }
      },
      "erros": {
        "400": "invalid_callout",
        "401": "invalid_session",
        "403": "invalid_origin / invalid_csrf",
        "409": "too_many_callouts",
        "503": "auth_unavailable"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/account/callouts/dismiss\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({key: \"financeiro_expense\"})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/account/callouts/dismiss",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/account/callouts/reopen",
      "auth": "session",
      "grupo": "Account",
      "summary": "Open a closed notice again.",
      "desc": "Undoes the close: the notice shows again for your account in this product. A product also keeps an on/off choice here, as the hidden values of Finance. Repeating is harmless.",
      "corpo": {
        "key": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "The notice key: letters, digits and `_.:-`, up to 80."
        }
      },
      "body": {
        "key": "financeiro_expense"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "true"
        }
      },
      "erros": {
        "400": "invalid_callout",
        "401": "invalid_session",
        "403": "invalid_origin / invalid_csrf",
        "503": "auth_unavailable"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/account/callouts/reopen\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: JSON.stringify({key: \"financeiro_expense\"})});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/account/callouts/reopen",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/auth/wallet/agent/start",
      "auth": "none",
      "grupo": "Account",
      "summary": "Start the wallet credential of an agent without an account.",
      "desc": "No account: the wallet proves it is hers by signing the message (EIP-4361). Signing does not pay or transfer anything. The message names this product and lasts 5 minutes. Before you sign, compare the message with the URL that you called. The domain on the first line must be the host of that URL. URI must be its origin. If one is different, do not sign. Sign it with personal_sign and send it to /api/auth/wallet/agent/token.",
      "corpo": {
        "address": {
          "tipo": "string",
          "desc": "0x…, a carteira (EOA ou contrato na Base)",
          "obrigatorio": true
        }
      },
      "body": {
        "address": "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23"
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/auth/wallet/agent/start -H 'content-type: application/json' -d '{\"address\":\"0x2c7536E3605D9C16a7a3D7b1898e529396a65c23\"}'",
      "retorno": {
        "message": {
          "tipo": "string",
          "desc": "EIP-4361"
        },
        "issuedAt": {
          "tipo": "number",
          "desc": "segundos / seconds"
        },
        "expiresIn": {
          "tipo": "number",
          "desc": "300"
        }
      },
      "erros": {
        "400": "invalid_wallet_address",
        "503": "auth_unavailable"
      },
      "returns": "{ message, issuedAt, expiresIn }",
      "url": "https://staging.agentalog.com/api/auth/wallet/agent/start",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/auth/wallet/agent/token",
      "auth": "none",
      "grupo": "Account",
      "summary": "Get the wallet credential (mmw_…) of this product.",
      "desc": "The wallet's signature of the start message, checked here (own key) or on Base (contract, EIP-1271/6492). The credential lasts 30 days: send `Authorization: Bearer mmw_…` to the routes that accept the wallet as owner (owner `x402:<address>`). Once the wallet is linked to an account, what it did here moves to the account when the person signs in.",
      "corpo": {
        "address": {
          "tipo": "string",
          "desc": "0x…, a mesma carteira do start / the same wallet as in start",
          "obrigatorio": true
        },
        "issuedAt": {
          "tipo": "number",
          "desc": "o issuedAt do start / start's issuedAt",
          "obrigatorio": true
        },
        "signature": {
          "tipo": "string",
          "desc": "personal_sign (0x…)",
          "obrigatorio": true
        }
      },
      "body": {
        "address": "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23",
        "issuedAt": 1791400000,
        "signature": "0x…"
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/auth/wallet/agent/token -H 'content-type: application/json' -d '{\"address\":\"0x2c7536E3605D9C16a7a3D7b1898e529396a65c23\",\"issuedAt\":1791400000,\"signature\":\"0x…\"}'",
      "retorno": {
        "token": {
          "tipo": "string",
          "desc": "mmw_…"
        },
        "owner": {
          "tipo": "string",
          "desc": "x402:0x…"
        },
        "expiresAt": {
          "tipo": "number",
          "desc": "segundos / seconds"
        }
      },
      "erros": {
        "400": "invalid_body",
        "401": "invalid_wallet",
        "429": "wallet_limited",
        "503": "wallet_unavailable / auth_unavailable"
      },
      "returns": "{ token, owner, expiresAt }",
      "url": "https://staging.agentalog.com/api/auth/wallet/agent/token",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/auth/claim/wallets",
      "auth": "session",
      "grupo": "Account",
      "summary": "Move to the account what its wallets did without an account.",
      "desc": "The sign-in window calls it after every sign-in. For each wallet linked to the account: the rights bought here by x402 (owner x402:<address>) and what this product keeps for that owner. Repeating moves nothing.",
      "exemplo": "await MMConta.fetch(new URL(\"$ORIGIN/api/auth/claim/wallets\").pathname, { method: \"POST\", headers: { \"content-type\": \"application/json\" }, body: \"{}\" })",
      "retorno": {
        "carteiras": {
          "tipo": "number",
          "desc": "wallets"
        },
        "direitos": {
          "tipo": "number",
          "desc": "rights moved"
        }
      },
      "erros": {
        "401": "invalid_session",
        "503": "auth_unavailable"
      },
      "returns": "{ carteiras, direitos }",
      "url": "https://staging.agentalog.com/api/auth/claim/wallets",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/auth/claim",
      "auth": "session",
      "grupo": "Account",
      "summary": "Moves what the guest created to the signed-in account: its listings, likes and comments.",
      "desc": "Bootstrap/CSRF of this browser required; the page does it right after sign-in. Only what the guest still owns moves, in one transaction, and anything that collides with what the account already has stays with the guest. What the guest bought moves too. An old unsigned token that owns nothing here is refused. Repeating it is harmless (moves zero).",
      "corpo": {
        "guest_token": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Guest `mr_…`; omitted, the `guest` cookie of this browser."
        }
      },
      "body": {},
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Whether the guest was recognized and moved."
        },
        "claimed": {
          "tipo": "object",
          "desc": "`product.movidos` (rows moved, per table), `product.apagados` (guest duplicates dropped) and `product.direitos` (purchases moved)."
        }
      },
      "erros": {
        "400": "invalid_product_claim / invalid_body",
        "401": "invalid_session",
        "403": "invalid_origin / invalid_csrf",
        "409": "unknown_guest (em `claimed.reason` / in `claimed.reason`)",
        "503": "product_claim_pending / auth_unavailable"
      },
      "exemplo": "(async () => {\n  const {csrf} = await fetch(\"$ORIGIN/api/auth/bootstrap\").then(r => r.json());\n  const r = await fetch(\"$ORIGIN/api/auth/claim\", {method: \"POST\", credentials: \"same-origin\",\n    headers: {\"Content-Type\": \"application/json\", \"X-CSRF-Token\": csrf},\n    body: \"{}\"});\n  return r.json();\n})();",
      "exemploLinguagem": "js",
      "returns": "{ ok, claimed }",
      "url": "https://staging.agentalog.com/api/auth/claim",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/billing",
      "auth": "none",
      "summary": "x402 configuration in force and the agent prices for contact and publishing.",
      "grupo": "Billing",
      "retorno": "Billing",
      "exemplo": "curl -s $ORIGIN/api/billing",
      "returns": "{ provider, mode, network, chain_id, pay_to, homolog, dev, dev_gate, alternavel, gratis?, cobrados?, facilitator, asset, asset_address, faucet, wallets, product, quota{free,paid,how_to_pay,live,free_now?,charged_now?,trial?}, pricing, billing, api_index, prices{listing_agent_usd} }",
      "url": "https://staging.agentalog.com/api/billing",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/contact",
      "auth": "none",
      "summary": "Write to the people behind the product — free, for people and agents alike.",
      "grupo": "Contact",
      "desc": "One route for a question and for a sponsorship, partnership or ad proposal (`tipo`, with the placements of `GET /api/partners`). No captcha, no account, no payment. One message every 10 seconds per network: one that arrives sooner waits its turn and then goes out — no error. The message reaches the team by e-mail, with `email` as the reply address. For voice, send multipart/form-data: `dados` is this JSON (up to 32 KiB), and `audio` is one WebM, Ogg or M4A audio file (up to 2 MB). Audio can replace message. The browser records up to two minutes. Audio is attached to the owner's e-mail.",
      "corpo": {
        "name": {
          "tipo": "string",
          "desc": "What to call the person writing.",
          "obrigatorio": true
        },
        "email": {
          "tipo": "string",
          "desc": "Where to reply.",
          "obrigatorio": true
        },
        "message": {
          "tipo": "string",
          "desc": "What you want to say.",
          "obrigatorio": true
        },
        "whatsapp": {
          "tipo": "string",
          "desc": "Optional reply number with country code, such as +5561999999999."
        },
        "prefer_whatsapp": {
          "tipo": "bool",
          "desc": "Request a WhatsApp reply. Requires whatsapp."
        },
        "tipo": {
          "tipo": "string",
          "desc": "Proposal: `patrocinio`, `parceria`, `anuncio` or `consultoria`. Turns on the fields below."
        },
        "empresa": {
          "tipo": "string",
          "desc": "Who is proposing, when it is a company."
        },
        "site": {
          "tipo": "string",
          "desc": "Website of who is proposing."
        },
        "orcamento": {
          "tipo": "string",
          "desc": "Advertising: `ate_100`, `100_500`, `500_2000`, `2000_mais` or `a_combinar`. Consulting, in US dollars: `ate_2000`, `2000_5000`, `5000_10000`, `10000_mais` or `nao_sei`."
        },
        "espaco": {
          "tipo": "string[]",
          "desc": "Placement ids from `GET /api/partners`, up to 6."
        },
        "duracao": {
          "tipo": "string",
          "desc": "Exposure in days: `30`, `90` or `365`."
        },
        "pagamento": {
          "tipo": "string",
          "desc": "`usdc`, `deposito` or `a_combinar`."
        },
        "projeto": {
          "tipo": "string",
          "desc": "Consulting: the kind of project (`llm_privado`, `voz`, `dados_sensiveis`, `gpu`, `integracao` or `outro`)."
        },
        "prazo": {
          "tipo": "string",
          "desc": "Consulting: when to start (`agora`, `1_mes`, `1_3_meses` or `explorando`)."
        },
        "formato": {
          "tipo": "string",
          "desc": "Consulting: `projeto` (per scope), `mensal` (monthly) or `assessoria` (advisory)."
        },
        "pais": {
          "tipo": "string",
          "desc": "Consulting: the country of the person asking."
        },
        "fuso": {
          "tipo": "string",
          "desc": "Consulting: the IANA time zone, such as `America/New_York`."
        },
        "horarios": {
          "tipo": "string[]",
          "desc": "Consulting: up to 3 times for the call, `YYYY-MM-DDTHH:MM` in that time zone."
        }
      },
      "body": {
        "name": "Agent",
        "email": "agent@example.com",
        "message": "hello from an agent"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true` when the message was accepted."
        }
      },
      "erros": {
        "400": "Validation: `code` names the field.",
        "503": "Contact is not configured on this server."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/contact -H 'content-type: application/json' -d '{\"name\":\"Agent\",\"email\":\"agent@example.com\",\"message\":\"hello from an agent\"}'",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/contact",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/visit",
      "auth": "none",
      "summary": "Ping from the interface that increments the day's visits. Agents need not call it.",
      "grupo": "Billing",
      "desc": "Smoke does not count: `X-MM-Smoke`, User-Agent `mm-smoke` or `smoke: true` in the body come in as `counted: false`. Only the page's own ping counts: a call from outside a browser page of the same site (robot User-Agent, or no `Sec-Fetch-Site: same-origin`) comes in as `counted: false` with `reason: \"robo\"`.",
      "corpo": {
        "p": {
          "tipo": "string",
          "desc": "Path of the visited page."
        },
        "smoke": {
          "tipo": "bool",
          "desc": "`true` marks the call as a test and it does not enter the count."
        }
      },
      "body": {
        "p": "/"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true`."
        },
        "counted": {
          "tipo": "bool",
          "desc": "Whether the visit entered the day's count."
        },
        "reason": {
          "tipo": "string",
          "desc": "Why it did not count, when `counted` is `false`.",
          "opcional": true
        }
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/visit -H 'content-type: application/json' -d '{\"p\":\"/\",\"smoke\":true}'",
      "returns": "{ ok, counted, reason? }",
      "url": "https://staging.agentalog.com/api/visit",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/erro-cliente",
      "auth": "none",
      "summary": "Browser error report, sent by the interface itself. Agents need not call it.",
      "grupo": "Operations",
      "desc": "The interface reports on its own JS errors, unhandled rejections, scripts/CSS that failed to load and CSP blocks — once per session — and the app reports handled failures through `window.mmErro.relata`. The server validates the envelope, redacts credentials, e-mails and phone numbers, merges repeats of the same failure per minute and records an operational event; nothing is written to a database. It keeps no IP, cookie, query string or full User-Agent. Always answers 204, even for an invalid report.",
      "corpo": {
        "code": {
          "tipo": "string",
          "desc": "Failure code, `UI-` + letters/digits (`UI-JS-001` global error, `UI-PROMESSA-001`, `UI-RECURSO-001`, `UI-CSP-001`, `UI-APP-001` app report).",
          "obrigatorio": true
        },
        "phase": {
          "tipo": "string",
          "desc": "Where it broke, lowercase: `global`, `promessa`, `script`, `load_list`…",
          "obrigatorio": true
        },
        "path": {
          "tipo": "string",
          "desc": "Path of the open page, without query; numbers, hashes and tokens in it are kept as `:id`."
        },
        "message": {
          "tipo": "string",
          "desc": "Error message, up to 2000 characters."
        },
        "stack": {
          "tipo": "string",
          "desc": "Stack trace, up to 12000 characters."
        },
        "source": {
          "tipo": "string",
          "desc": "Originating script; only its path is kept."
        },
        "line": {
          "tipo": "int",
          "desc": "Line in the originating script."
        },
        "column": {
          "tipo": "int",
          "desc": "Column in the originating script."
        },
        "visivel": {
          "tipo": "bool",
          "desc": "Whether the tab was visible when it broke."
        },
        "build": {
          "tipo": "string",
          "desc": "Build of the reporting page (its `<meta name=\"build\">`), up to 64 letters, digits, `.`, `_` or `-`; it dates the failure."
        }
      },
      "body": {
        "code": "UI-APP-001",
        "phase": "carregar_lista",
        "path": "/",
        "message": "lista 500"
      },
      "retorno": {
        "_texto": "204 with no body, always — an invalid, repeated or over-cap report also gets 204."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/erro-cliente -H 'content-type: application/json' -d '{\"code\":\"UI-APP-001\",\"phase\":\"carregar_lista\",\"path\":\"/\",\"message\":\"lista 500\"}'",
      "returns": "204 with no body, always — an invalid, repeated or over-cap report also gets 204.",
      "url": "https://staging.agentalog.com/api/erro-cliente",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/pagamento/aberto",
      "auth": "none",
      "statusOk": 202,
      "summary": "The interface reports a visible payment prompt. Agents must not call this route.",
      "grupo": "Operations",
      "desc": "An empty same-origin report, sent automatically when a payment prompt becomes visible. It starts no payment, grants no access and receives no identity or credentials. It writes no database row per report. Counts events, not unique people. The private operator dashboard separates API payment requests and browser payment views per UTC day; the two counts may overlap.",
      "headers": {
        "Origin": {
          "tipo": "string",
          "desc": "The page origin, identical to this route's origin.",
          "obrigatorio": true
        },
        "Sec-Fetch-Site": {
          "tipo": "string",
          "desc": "`same-origin`, set by the browser.",
          "obrigatorio": true
        },
        "X-MM-Payment-View": {
          "tipo": "string",
          "desc": "`1`, set by the shared component.",
          "obrigatorio": true
        }
      },
      "retorno": {
        "_texto": "202 with no body when accepted; 204 when ignored. Always no-store."
      },
      "returns": "202 with no body when accepted; 204 when ignored. Always no-store.",
      "url": "https://staging.agentalog.com/api/pagamento/aberto",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/funil",
      "auth": "none",
      "statusOk": 202,
      "summary": "The interface reports the steps of a visit (conversion funnel). Agents must not call this route.",
      "grupo": "Operations",
      "desc": "A same-origin batch sent by the page itself: page views, engagement, offer in view, buy click, payment window, payment sent or accepted. It keeps the browser's random id, the path without query, the referring host and the utm tags; never IP, e-mail or account. It writes no database row: one line per batch in the day's journal, with a cap. Declared robots and smoke tests are left out.",
      "headers": {
        "Origin": {
          "tipo": "string",
          "desc": "The page origin, identical to this route's origin.",
          "obrigatorio": false
        },
        "Content-Type": {
          "tipo": "string",
          "desc": "`application/json` or `text/plain`.",
          "obrigatorio": true
        }
      },
      "corpo": {
        "v": {
          "tipo": "number",
          "desc": "Batch version: `1`.",
          "obrigatorio": true
        },
        "vid": {
          "tipo": "string",
          "desc": "This browser's random id (UUID v4).",
          "obrigatorio": true
        },
        "sid": {
          "tipo": "string",
          "desc": "Session id (30 idle minutes end it).",
          "obrigatorio": true
        },
        "sn": {
          "tipo": "number",
          "desc": "This browser's session number.",
          "obrigatorio": true
        },
        "pv": {
          "tipo": "string",
          "desc": "Page view id.",
          "obrigatorio": true
        },
        "e": {
          "tipo": "object[]",
          "desc": "Up to 40 events `{ t, n, p? }` from the funnel vocabulary.",
          "obrigatorio": true
        }
      },
      "retorno": {
        "_texto": "202 with no body when stored; 204 when ignored. Always no-store."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/funil -H 'content-type: text/plain' -H 'x-mm-smoke: 1' -d '{\"v\":1,\"vid\":\"0f8b9c1e-2a3b-4c5d-8e6f-7a8b9c0d1e2f\",\"sid\":\"s1abcdefgh\",\"sn\":1,\"pv\":\"p1abcdefgh\",\"e\":[{\"t\":0,\"n\":\"pagina\"}]}'",
      "returns": "202 with no body when stored; 204 when ignored. Always no-store.",
      "url": "https://staging.agentalog.com/api/funil",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/funil/arquivos",
      "auth": "none",
      "summary": "Operator: the funnel journal days kept by this app, with the size of each.",
      "grupo": "Operations",
      "headers": {
        "Authorization": {
          "tipo": "string",
          "desc": "`Bearer <METRICS_TOKEN>`.",
          "obrigatorio": true
        }
      },
      "retorno": {
        "v": {
          "tipo": "number",
          "desc": "Stored batch version."
        },
        "produto": {
          "tipo": "string",
          "desc": "The product."
        },
        "teto": {
          "tipo": "object",
          "desc": "`bytesDia` and `dias` kept."
        },
        "dias": {
          "tipo": "object[]",
          "desc": "`{ dia, bytes }`, oldest to today."
        }
      },
      "erros": {
        "401": "Unauthorized",
        "503": "Not configured"
      },
      "exemplo": "curl -s $ORIGIN/api/funil/arquivos -H \"Authorization: Bearer $METRICS_TOKEN\"",
      "returns": "{ v, produto, teto, dias }",
      "url": "https://staging.agentalog.com/api/funil/arquivos",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/funil/arquivo",
      "auth": "none",
      "summary": "Operator: a slice of one funnel journal day, as NDJSON, from a byte offset.",
      "grupo": "Operations",
      "desc": "Up to 4 MiB per response, cut at the last whole line. `X-MM-Funil-Proximo` says where to ask for the rest; `X-MM-Funil-Tamanho`, the day's size now.",
      "headers": {
        "Authorization": {
          "tipo": "string",
          "desc": "`Bearer <METRICS_TOKEN>`.",
          "obrigatorio": true
        }
      },
      "query": {
        "dia": {
          "tipo": "string",
          "desc": "The day, `YYYY-MM-DD` (UTC).",
          "obrigatorio": true
        },
        "desde": {
          "tipo": "number",
          "desc": "The byte to read from; `0` at the start.",
          "obrigatorio": false
        }
      },
      "retorno": {
        "_texto": "JSON lines, one per stored batch."
      },
      "erros": {
        "400": "Invalid parameters",
        "401": "Unauthorized",
        "503": "Not configured"
      },
      "exemplo": "curl -s \"$ORIGIN/api/funil/arquivo?dia=2026-09-27&desde=0\" -H \"Authorization: Bearer $METRICS_TOKEN\"",
      "returns": "JSON lines, one per stored batch.",
      "url": "https://staging.agentalog.com/api/funil/arquivo",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/vitrine",
      "auth": "none",
      "grupo": "Public stats",
      "summary": "The product's public numbers: traffic, agents, usage and reliability, no money.",
      "desc": "Projection published hourly by the house collector, rounded to two significant digits; `null` is a missing measurement, never zero. 15-minute cache with ETag (`If-None-Match` → 304). There is no way to send numbers through this route: publishing belongs to the collector, with its own token.",
      "retorno": {
        "v": {
          "tipo": "int",
          "desc": "Contract version (1)."
        },
        "produto": {
          "tipo": "string",
          "desc": "Product id."
        },
        "publicado": {
          "tipo": "bool",
          "desc": "`false` before the collector's first publication; then only these five keys come."
        },
        "atualizado_em": {
          "tipo": "string",
          "desc": "When the collector published (ISO 8601).",
          "nulo": true
        },
        "stale": {
          "tipo": "bool",
          "desc": "`true` when the projection is older than 26 h."
        },
        "nome": {
          "tipo": "string",
          "desc": "Product name.",
          "opcional": true
        },
        "desde": {
          "tipo": "string",
          "desc": "First day the series covers.",
          "nulo": true,
          "opcional": true
        },
        "fuso": {
          "tipo": "string",
          "desc": "Traffic time zone. Audience periods state their time zone in `pessoas.medicao`.",
          "opcional": true
        },
        "hoje": {
          "tipo": "object",
          "desc": "Today: pages by class (human, AI, bot), API calls by class, machine-surface reads and product usage.",
          "opcional": true
        },
        "dias": {
          "tipo": "object[]",
          "desc": "Up to 31 days, oldest first: `dia`, `paginas`, `api`, `api_ia`, `maquina`, `visitantes`, `uso`.",
          "opcional": true
        },
        "janelas": {
          "tipo": "object",
          "desc": "7- and 30-day sums (`d7`, `d30`).",
          "opcional": true
        },
        "visitantes": {
          "tipo": "object",
          "desc": "Unique browsers with recorded interaction over 7 days.",
          "opcional": true
        },
        "pessoas": {
          "tipo": "object",
          "desc": "First-party measurement of browsers confirmed by interaction: unique browsers, sessions and pages over 7 and 30 days, segments and coverage. `null` means no measurement. Browsers are not verified people.",
          "nulo": true,
          "opcional": true
        },
        "agentes": {
          "tipo": "object",
          "desc": "The AI agents and bots that read the most, 7 days.",
          "opcional": true
        },
        "superficies": {
          "tipo": "object",
          "desc": "Reads of OKF, llms, well-known, OpenAPI and MCP over 7 days.",
          "opcional": true
        },
        "mcp": {
          "tipo": "object",
          "desc": "MCP calls over 7 days.",
          "opcional": true
        },
        "uso": {
          "tipo": "object",
          "desc": "Real product usage per resource: label, today, 7 and 30 days.",
          "opcional": true
        },
        "contas": {
          "tipo": "object",
          "desc": "Users and guests.",
          "nulo": true,
          "opcional": true
        },
        "confiabilidade": {
          "tipo": "object",
          "desc": "Share of requests without 5xx over 7 days, and the live build.",
          "opcional": true
        },
        "catalogo": {
          "tipo": "object",
          "desc": "Size of the catalog, when the product has one.",
          "nulo": true,
          "opcional": true
        },
        "apoio": {
          "tipo": "object",
          "desc": "Measured sponsors: 1-second exposures and native clicks per page in confirmed sessions, 7-day CTR, observed days and coverage. Empty means no history, not zero CTR.",
          "opcional": true
        }
      },
      "exemplo": "curl -s $ORIGIN/api/vitrine",
      "returns": "{ v, produto, publicado, atualizado_em, stale, nome?, desde?, fuso?, hoje?, dias?, janelas?, visitantes?, pessoas?, agentes?, superficies?, mcp?, uso?, contas?, confiabilidade?, catalogo?, apoio? }",
      "url": "https://staging.agentalog.com/api/vitrine",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/vitrine/operador",
      "auth": "none",
      "grupo": "Public stats",
      "summary": "The product's full document on the operator panel — operator token only.",
      "headers": {
        "Authorization": {
          "tipo": "string",
          "desc": "`Bearer <METRICS_TOKEN>` — the operator class.",
          "obrigatorio": true
        }
      },
      "retorno": {
        "produto": {
          "tipo": "string",
          "desc": "Product id."
        },
        "atualizado_em": {
          "tipo": "string",
          "desc": "When the collector published.",
          "nulo": true
        },
        "operador": {
          "tipo": "object",
          "desc": "The collector's full document, with what the public projection leaves out.",
          "nulo": true
        }
      },
      "erros": {
        "401": "No token, wrong token or a token of another class.",
        "503": "Worker without `METRICS_TOKEN` or without the control plane."
      },
      "exemplo": "curl -s $ORIGIN/api/vitrine/operador -H \"Authorization: Bearer $METRICS_TOKEN\"",
      "returns": "{ produto, atualizado_em, operador }",
      "url": "https://staging.agentalog.com/api/vitrine/operador",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/vitrine/painel",
      "auth": "none",
      "grupo": "Public stats",
      "summary": "The whole house panel, in the shape the gm reads — operator token only.",
      "headers": {
        "Authorization": {
          "tipo": "string",
          "desc": "`Bearer <METRICS_TOKEN>` — the operator class.",
          "obrigatorio": true
        }
      },
      "retorno": {
        "apps": {
          "tipo": "object[]",
          "desc": "One operator document per product, ordered by id."
        },
        "updated": {
          "tipo": "string",
          "desc": "When the collector closed the round.",
          "opcional": true
        },
        "totals": {
          "tipo": "object",
          "desc": "House totals.",
          "opcional": true
        }
      },
      "erros": {
        "401": "No token, wrong token or a token of another class.",
        "503": "Worker without `METRICS_TOKEN` or without the control plane."
      },
      "exemplo": "curl -s $ORIGIN/api/vitrine/painel -H \"Authorization: Bearer $METRICS_TOKEN\"",
      "returns": "{ apps, updated?, totals? }",
      "url": "https://staging.agentalog.com/api/vitrine/painel",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/vitrine/cursores",
      "auth": "none",
      "grupo": "Public stats",
      "summary": "Per-product cursors: `borda`, `borda5xx` (5xx only), and `cli`. Operator token only.",
      "headers": {
        "Authorization": {
          "tipo": "string",
          "desc": "`Bearer <METRICS_TOKEN>` — the operator class.",
          "obrigatorio": true
        }
      },
      "retorno": {
        "_texto": "JSON: `{ [product]: { borda?: ISO, borda5xx?: ISO, cli?: ISO } }`; empty is `{}`."
      },
      "erros": {
        "401": "No token, wrong token or a token of another class.",
        "503": "Worker without `METRICS_TOKEN` or without the control plane."
      },
      "exemplo": "curl -s $ORIGIN/api/vitrine/cursores -H \"Authorization: Bearer $METRICS_TOKEN\"",
      "returns": "JSON: `{ [product]: { borda?: ISO, borda5xx?: ISO, cli?: ISO } }`; empty is `{}`.",
      "url": "https://staging.agentalog.com/api/vitrine/cursores",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/partners",
      "auth": "none",
      "grupo": "Partnership",
      "summary": "Fixed-price advertising: placements, duration, public numbers and checkout. Partnerships and custom campaigns use negotiation.",
      "desc": "Four packages priced in USD per week, one-off or weekly subscription. Includes placements, sponsors and measured audience. Proposals, review, acceptance and payment at /conta/publicidade, also in the profile menu. Preview links go to the verified account email. GET modalidade=pedido requires a human session: list your proposals (after=next) or read id; relatorio_depois pages daily results. GET modalidade=pendencias requires the same session and returns acao_pendente for an approved preview that this account must accept or pay. GET modalidade=arte&id serves the private binary image, public only during a paid published campaign. Private responses never use public caching. The weekly catalogue is cached for 1 minute. Negotiation and partnerships use the contact form.",
      "retorno": {
        "status": {
          "tipo": "string",
          "desc": "`preco_fechado`: priced spaces can be purchased; other offers require negotiation."
        },
        "produto": {
          "tipo": "string",
          "desc": "Product name."
        },
        "idioma": {
          "tipo": "string",
          "desc": "Language of the texts (the product's)."
        },
        "titulo": {
          "tipo": "string",
          "desc": "Title of the offer."
        },
        "descricao": {
          "tipo": "string",
          "desc": "One sentence about the offer."
        },
        "publico": {
          "tipo": "string",
          "desc": "Who uses the product — the audience a sponsor reaches."
        },
        "modalidades": {
          "tipo": "object[]",
          "desc": "`{ id, nome }`: patrocinio, parceria, anuncio."
        },
        "placements": {
          "tipo": "object[]",
          "desc": "Package channels: id, nome, onde, formato, medicao and disponivel. Legacy monthly price is null in the weekly catalogue."
        },
        "packages": {
          "tipo": "object[]",
          "desc": "Four packages: id, nome, assinatura, preco_usd_semana, espacos, canais and allowed periods in exposicao[{dias,preco}]."
        },
        "house_bundle": {
          "tipo": "object",
          "desc": "Unavailable in the weekly catalogue: `{disponivel:false}`."
        },
        "parcerias": {
          "tipo": "string[]",
          "desc": "Partnership ideas the product is open to discuss."
        },
        "current_sponsors": {
          "tipo": "object[]",
          "desc": "Sponsors in effect: `id`, `nome`, `url`, `frase`, `espacos`, `ate`."
        },
        "stats": {
          "tipo": "object",
          "desc": "Excerpt of the public numbers (`hoje`, `janelas`, `agentes`, `confiabilidade`) and the `link` to `/api/vitrine`; `publicado: false` before the first publication."
        },
        "payment": {
          "tipo": "object",
          "desc": "Shared payment through the purchase POST. Wallet fields remain for compatibility; do not send a manual payment before the quote."
        },
        "contact": {
          "tipo": "object",
          "desc": "`email`, `form_url`, `api_url` (`POST /api/contact`, free: one message every 10 s per network), `campos` (required), `campos_proposta` (the optional proposal fields, each with its accepted values), `message_template`, `instructions`."
        },
        "politica": {
          "tipo": "object",
          "desc": "Placement label, refused sectors, prepayment, deadlines."
        },
        "_links": {
          "tipo": "object",
          "desc": "`self`, `stats`, `page` (`null` until the page exists), `contact`, `casa` (the same path on the ten products)."
        }
      },
      "exemplo": "curl -s $ORIGIN/api/partners",
      "returns": "{ status, produto, idioma, titulo, descricao, publico, modalidades, placements, packages, house_bundle, parcerias, current_sponsors, stats, payment, contact, politica, _links }",
      "url": "https://staging.agentalog.com/api/partners",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/partners",
      "auth": "session",
      "grupo": "Partnership",
      "summary": "Submit an ad for approval, then buy the approved weekly package.",
      "desc": "Human account session and same-origin CSRF required. Submit complete creative and terms with modalidade=proposta: one private binary is stored for the account, without charge or inventory reservation. The owner reviews in /adm; the verified account email receives a link to /conta/publicidade?pedido=ID. Read your proposal with GET modalidade=pedido&id=ID on any device. Review the final version, then POST modalidade=aceitar with only {id,versao,aceite:true}. Payment requires both approvals for that exact version. For one-off payment omit modalidade and send only {id,aprovacao:versao}: shared 402 quote and payment, no renewal. modalidade=assinatura adds the native assinatura body with explicit weekly renewal acceptance. Current BRL offers: /api/credito/assinaturas/ofertas. Cancel future charges in the account. modalidade=recibo reads your paid campaign receipt. The owner publishes after verified payment; the period begins on publication. Identical retries do not charge twice. Custom campaigns and free partnerships use POST /api/contact.",
      "query": [
        {
          "nome": "modalidade",
          "tipo": "string",
          "desc": "proposta submits; aceitar accepts the exact owner-approved version; omit for approved one-off payment; assinatura uses native weekly card billing; recibo reads the account's campaign receipt."
        }
      ],
      "corpo": {
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Fresh random order id: 32 lowercase hexadecimal characters. Reuse for retries."
        },
        "token": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Required only to submit a proposal: 64 random lowercase hexadecimal characters, reused for an identical retry. Account login remains mandatory for private access."
        },
        "espaco": {
          "tipo": "string[]",
          "desc": "Legacy paid-order retry only. New purchases select a package.",
          "obrigatorio": false
        },
        "pacote": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "One of the four package ids in GET /api/partners packages."
        },
        "duracao": {
          "tipo": "int",
          "obrigatorio": false,
          "desc": "Days from the package exposure list. Weekly subscriptions require 7."
        },
        "modalidade": {
          "tipo": "string",
          "valores": [
            "avulso",
            "assinatura"
          ],
          "desc": "Required in the proposal body: avulso or assinatura. The approved mode is bound to the creative hash.",
          "obrigatorio": false
        },
        "aprovacao": {
          "tipo": "string",
          "desc": "After owner approval and advertiser acceptance, send only id and this 64-character versao for one-off payment. No image is uploaded again.",
          "obrigatorio": false
        },
        "versao": {
          "tipo": "string",
          "desc": "modalidade=aceitar: exact current versao from the authenticated proposal.",
          "obrigatorio": false
        },
        "aceite": {
          "tipo": "bool",
          "desc": "modalidade=aceitar requires true after the advertiser reviews this exact version.",
          "obrigatorio": false
        },
        "assinatura": {
          "tipo": "object",
          "desc": "Only with modalidade=assinatura: the native subscription body with recurso=publicidade:ORDER_ID, simulado, cartao and explicit renewal aceite. The authenticated account must own the campaign.",
          "obrigatorio": false
        },
        "pedido": {
          "tipo": "string",
          "desc": "Only with modalidade=recibo: the campaign id owned by the signed-in account.",
          "obrigatorio": false
        },
        "nome": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Brand or product, up to 80 characters."
        },
        "email": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Contact email."
        },
        "url": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "HTTPS destination URL."
        },
        "frase": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Ad copy, up to 100 characters."
        },
        "arte": {
          "tipo": "string",
          "obrigatorio": false,
          "desc": "Base64 image bytes, without a data URL prefix. PNG, JPEG or WebP, up to 2 MB."
        },
        "direitos": {
          "tipo": "bool",
          "obrigatorio": false,
          "desc": "true confirms the right to use the image and content."
        }
      },
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "Order id."
        },
        "estado": {
          "tipo": "string",
          "desc": "proposta: private and unpaid; aprovado: owner-approved; aceite: advertiser-accepted; revisao: paid and awaiting publication; publicado: live in its paid period; recusado: declined."
        },
        "recibo": {
          "tipo": "string",
          "desc": "Verified payment receipt."
        },
        "versao": {
          "tipo": "string",
          "desc": "Current reviewed campaign fingerprint. Editing invalidates both approvals."
        },
        "arte": {
          "tipo": "string",
          "desc": "Private binary URL; access requires the owning account or factor-protected owner until publication."
        }
      },
      "erros": {
        "400": "Invalid order or artwork.",
        "401": "A human account session is required.",
        "402": "Payment required.",
        "403": "Invalid origin or CSRF.",
        "409": "Approval required, space occupied or order changed.",
        "503": "Checkout unavailable."
      },
      "exemplo": "Use $ORIGIN/conta/publicidade and the shared account SDK; API keys cannot approve or purchase a campaign.",
      "returns": "{ id, estado, recibo, versao, arte }",
      "url": "https://staging.agentalog.com/api/partners",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/api/metrics",
      "auth": "none",
      "summary": "Metrics of the last 7 days. With the operator token, includes payments.",
      "grupo": "Billing",
      "desc": "Without credentials it returns visits, usage and accounts. With `METRICS_TOKEN` as Bearer it adds `payments` — and only on Base mainnet, because staging numbers on a finance panel mislead — and `compras`, who paid in the last 30 days.",
      "headers": {
        "Authorization": {
          "tipo": "string",
          "desc": "`Bearer <METRICS_TOKEN>` to include the finance block.",
          "obrigatorio": false
        }
      },
      "retorno": "Metricas",
      "exemplo": "curl -s $ORIGIN/api/metrics -H \"Authorization: Bearer $METRICS_TOKEN\"",
      "returns": "{ app, today, today_visits, today_contacts?, days, usage, accounts, financeiro?, payments? }",
      "url": "https://staging.agentalog.com/api/metrics",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id/status",
      "auth": "none",
      "summary": "Moderation state of a listing — how the submitter polls for approval, with no credential.",
      "grupo": "Publish",
      "desc": "Every submission is born `pending`. An automatic safety check looks for concrete signs of fraud, malware or data theft. Listings without these signs can be approved. A risk finding or an unreadable source keeps the listing private for a person to review. This is the receipt you poll after `POST /api/listings` (its response carries this URL as `status_api`). Only the decision comes back, never the unreviewed content: the id (`lst_…`, unguessable) is all it takes, and the page itself keeps its rule — owner only until it is public. Answers are cached for 60 s per point of presence: poll every few minutes, not every second.",
      "params": {
        "id": {
          "desc": "Listing ID, from the `id` of the `POST /api/listings` response."
        }
      },
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "Listing ID."
        },
        "status": {
          "tipo": "string",
          "desc": "Moderation state. `pending` is waiting; `live` and `low` are approved; `hidden` and `blocked` are not published.",
          "valores": [
            "pending",
            "live",
            "low",
            "hidden",
            "blocked"
          ]
        },
        "public": {
          "tipo": "bool",
          "desc": "`true` when the listing is reachable in the catalog (`live` or `low`)."
        },
        "message": {
          "tipo": "string",
          "desc": "What the state means and what to do next."
        },
        "reason": {
          "tipo": "string",
          "desc": "Why it was hidden or blocked, when the moderator left a reason. Absent otherwise.",
          "opcional": true
        },
        "api": {
          "tipo": "string",
          "desc": "The listing's page (`GET /api/listings/:id`): the owner reads it with the token that created it; everybody else once it is public."
        },
        "status_api": {
          "tipo": "string",
          "desc": "This URL, to poll again."
        }
      },
      "erros": {
        "404": "No listing with this id."
      },
      "exemplo": "curl -s $ORIGIN/api/listings/ID/status",
      "returns": "{ id, status, public, message, reason?, api, status_api }",
      "url": "https://staging.agentalog.com/api/listings/:id/status",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/okf/ping",
      "auth": "none",
      "statusOk": 202,
      "summary": "Submits OKF bundles from a domain you control, using the IndexNow protocol.",
      "grupo": "Publish",
      "desc": "No account, no payment: ownership is proved by a key file on the host, exactly as IndexNow does it. Host `https://<host>/<key>.txt` containing the key (or point `keyLocation` at another path on the SAME host), then send the bundle URLs. We answer **202**: the key has not been checked yet. Verification and reading happen on our collector, never at the edge — so nothing is published, and no URL of yours is fetched, before the key matches. Re-sending a URL is how you say the bundle changed; it goes back in line to be re-read. At most 100 URLs per request and 200 per host per UTC day. The same queue is served by `POST https://okfindex.com/api/ping`, the index's own home — search, bundle cards and statistics live there.",
      "corpo": {
        "host": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "The host that owns the bundles."
        },
        "key": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "8 to 128 characters of [a-zA-Z0-9-]."
        },
        "keyLocation": {
          "tipo": "string",
          "desc": "Where the key file lives. Defaults to `https://<host>/<key>.txt`; must be on `host`."
        },
        "urlList": {
          "tipo": "string[]",
          "obrigatorio": true,
          "desc": "Bundle `index.md` URLs. https, on `host`, ending in .md. No fixed path: the spec defines no discovery convention."
        }
      },
      "body": {
        "host": "example.com",
        "key": "a1b2c3d4e5f60718",
        "urlList": [
          "https://example.com/okf/index.md"
        ]
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "The submission was queued."
        },
        "estado": {
          "tipo": "string",
          "desc": "Always `pendente`: the key has not been checked yet."
        },
        "recebidos": {
          "tipo": "int",
          "desc": "How many distinct URLs entered the queue."
        },
        "chave_em": {
          "tipo": "string",
          "desc": "Where we will look for the key file. Check it if you are unsure."
        }
      },
      "erros": {
        "400": "Malformed body, `host`/`key` invalid or `urlList` missing.",
        "422": "A URL is not https, is not .md, or does not belong to `host` — `keyLocation` on another host too.",
        "429": "This host reached 200 bundles for the UTC day."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/okf/ping -H 'content-type: application/json' -d '{\"host\":\"example.com\",\"key\":\"a1b2c3d4e5f60718\",\"urlList\":[\"https://example.com/okf/index.md\"]}'",
      "returns": "{ ok, estado, recebidos, chave_em }",
      "url": "https://staging.agentalog.com/api/okf/ping",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/bundles",
      "auth": "none",
      "colecao": {
        "porPagina": 24,
        "teto": 1000,
        "anda": "next_offset"
      },
      "summary": "Paginated search of the index: every live OKF bundle, from GitHub and from live domains.",
      "grupo": "Index",
      "desc": "Only `live` bundles. Free text matches the name, the tagline, the description and the origin identifier (`owner/repo:path` or the bundle URL). No `total` on purpose: `GET /api/okf/stats` has it.",
      "query": {
        "q": {
          "tipo": "string",
          "desc": "Free text over name, tagline, description and origin identifier.",
          "exemplo": "agent"
        },
        "origin": {
          "tipo": "string",
          "desc": "Provenance: found by the GitHub sweep, or submitted by a domain.",
          "valores": [
            "github",
            "domain"
          ]
        },
        "repo": {
          "tipo": "string",
          "desc": "Only bundles of one repository, `owner/repo` (case-insensitive).",
          "exemplo": "fastendpoints/fastendpoints"
        },
        "version": {
          "tipo": "string",
          "desc": "Only bundles declaring one of these `okf_version` values; comma-separated, up to 5.",
          "exemplo": "0.1,0.2"
        },
        "concept": {
          "tipo": "string",
          "desc": "Text in the indexed root content, including listed concept names and summaries (first 1000 characters); up to 80 characters."
        },
        "concepts": {
          "tipo": "string",
          "desc": "Number of entries listed by the root. Up to 5 comma-separated bands: 0,1-5,6-20,21-100,101+."
        },
        "type": {
          "tipo": "string",
          "desc": "Type declared by the root, not the types of every concept. Up to 5 comma-separated values, 40 characters each."
        },
        "license": {
          "tipo": "string",
          "desc": "Repository license. Up to 5 comma-separated values, 40 characters each."
        },
        "language": {
          "tipo": "string",
          "desc": "Only bundles whose repository language is one of these; comma-separated, up to 5 (GitHub bundles).",
          "exemplo": "TypeScript,Go"
        },
        "sort": {
          "tipo": "string",
          "desc": "Result order: arrival, last content change, name or repository stars.",
          "valores": [
            "recent",
            "updated",
            "name",
            "stars"
          ],
          "padrao": "recent"
        },
        "limit": {
          "tipo": "int",
          "desc": "Bundles per page, at most 100.",
          "padrao": 24
        },
        "offset": {
          "tipo": "int",
          "desc": "How many bundles to skip. Use `next_offset` from the previous response; the list ends at 1000.",
          "padrao": 0
        }
      },
      "retorno": "PaginaDeBundles",
      "exemplo": "curl -s '$ORIGIN/api/bundles?q=agent&sort=stars&limit=5'",
      "returns": "{ items[{id,name,tagline,description,okf_version,concepts,concept_list,type,index_url,page_url,source,repo,indexed_at,updated_at,api}], limit, offset, next_offset, next }",
      "url": "https://staging.agentalog.com/api/bundles",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/bundles/:id",
      "auth": "none",
      "summary": "One bundle's card, by id.",
      "grupo": "Index",
      "desc": "`live` and `low` (example or fixture bundles kept out of the search) both answer here.",
      "params": {
        "id": {
          "desc": "Bundle id, the `id` of every item in the list.",
          "exemplo": "okf-fastendpoints"
        }
      },
      "retorno": "Bundle",
      "erros": {
        "404": "No bundle with that id, or it is not public."
      },
      "exemplo": "curl -s $ORIGIN/api/bundles/<id>",
      "returns": "{ id, name, tagline, description, okf_version, concepts, concept_list[{name,url,summary}], type, index_url, page_url, source{origin,via,url,host,repo,dir,path}, repo{stars,forks,pushed_at,state,language,license}, indexed_at, updated_at, api }",
      "url": "https://staging.agentalog.com/api/bundles/:id",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/okf/stats",
      "auth": "none",
      "summary": "Size of the index by provenance, and when it last changed.",
      "grupo": "Index",
      "retorno": "IndexStats",
      "exemplo": "curl -s $ORIGIN/api/okf/stats",
      "returns": "{ total, by_origin, by_version[{v,n}], by_type[{v,n}], by_concepts[{v,n}], by_license[{v,n}], by_language[{v,n}], last_update }",
      "url": "https://staging.agentalog.com/api/okf/stats",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/volatil",
      "auth": "none",
      "grupo": "Catalog",
      "summary": "Fresh download, install and version counters for up to 100 listings.",
      "desc": "The catalog stores the values seen at the last real change of a listing; counters and package versions change over time. After a search, use this batch or MCP listing_updates before comparing versions. These values may be cached for up to 15 minutes; `gerado_em` is the slice generation date, not a check date for each record. Listings without a record are unknown and simply absent. `GET /api/listings/:id` already applies these values on top of the record.",
      "query": {
        "ids": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Comma-separated listing ids, at most 100."
        }
      },
      "retorno": {
        "itens": {
          "tipo": "object",
          "desc": "`{id: {downloads?, installs?, version?, pacotes?}}` — `pacotes` maps `registry:identifier` to its version."
        },
        "gerado_em": {
          "tipo": "string",
          "desc": "When the oldest slice read was generated (UTC)."
        },
        "ttl_s": {
          "tipo": "int",
          "desc": "How long a slice stays in the edge cache."
        }
      },
      "erros": {
        "400": "`ids` missing, invalid, or more than 100."
      },
      "exemplo": "curl -s '$ORIGIN/api/volatil?ids=skl_a,skl_b'",
      "returns": "{ itens, gerado_em, ttl_s }",
      "url": "https://staging.agentalog.com/api/volatil",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/admin/volatil",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Publishes one group of updated counters.",
      "desc": "CARGA_TOKEN only. One slice = 1/256 of the ids (by hash), whole; submit only slices whose content changed. Nothing here touches the catalog database — that is the point.",
      "corpo": {
        "fatia": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Two hex digits; every id in `itens` must hash to it."
        },
        "gerado_em": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "UTC instant the slice was built."
        },
        "itens": {
          "tipo": "object",
          "obrigatorio": true,
          "desc": "`{id: record}`, at most 5000 ids and 1 MB."
        }
      },
      "body": {
        "fatia": "0a",
        "gerado_em": "2026-09-08 12:00:00",
        "itens": {
          "skl_a": {
            "downloads": 138,
            "version": "1.1"
          }
        }
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Stored."
        },
        "fatia": {
          "tipo": "string",
          "desc": "The slice stored."
        },
        "itens": {
          "tipo": "int",
          "desc": "Records in it."
        }
      },
      "erros": {
        "400": "Malformed slice, id outside the slice, or above the ceilings.",
        "401": "CARGA_TOKEN required.",
        "503": "Object storage not configured."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/volatil -H \"Authorization: Bearer $CARGA_TOKEN\" -d @fatia.json",
      "returns": "{ ok, fatia, itens }",
      "url": "https://staging.agentalog.com/api/admin/volatil",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/sitemap",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Receives one shard of the listings sitemap (or its manifest) for publication.",
      "desc": "CARGA_TOKEN only. Submit catalog shards (up to 50,000 listings each, ordered by id) and sends only the shard whose content changed, then the manifest (how many shards, when). The Worker serves `/sitemap-listings.xml` (index) and `/sitemap-listings-N.xml` (shard) from that storage, with cache at the edge; the catalog database is never read for it.",
      "corpo": {
        "parte": {
          "tipo": "int",
          "desc": "Shard number, 1-based (at most 200). Omit when sending the manifest."
        },
        "gerado_em": {
          "tipo": "string",
          "desc": "UTC instant the shard was built."
        },
        "urls": {
          "tipo": "object[]",
          "desc": "`{id, lastmod?}` per listing, at most 50,000; `lastmod` is the listing's `updated_at`."
        },
        "manifesto": {
          "tipo": "object",
          "desc": "`{partes, gerado_em}` — sent once after the shards; replaces the previous manifest."
        }
      },
      "body": {
        "parte": 1,
        "gerado_em": "2026-09-13 12:00:00",
        "urls": [
          {
            "id": "mcp_x",
            "lastmod": "2026-09-10 08:00:00"
          }
        ]
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Stored."
        },
        "parte": {
          "tipo": "int",
          "desc": "The shard stored (absent for the manifest).",
          "opcional": true
        },
        "urls": {
          "tipo": "int",
          "desc": "Listings in it (absent for the manifest).",
          "opcional": true
        },
        "manifesto": {
          "tipo": "object",
          "desc": "The manifest stored (absent for a shard).",
          "opcional": true
        }
      },
      "erros": {
        "400": "Malformed shard or manifest, invalid id, or above the ceilings.",
        "401": "CARGA_TOKEN required.",
        "503": "Object storage not configured."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/sitemap -H \"Authorization: Bearer $CARGA_TOKEN\" -d @parte-1.json",
      "returns": "{ ok, parte?, urls?, manifesto? }",
      "url": "https://staging.agentalog.com/api/admin/sitemap",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/listings/:id/history",
      "auth": "none",
      "summary": "Timeline of the listing's repository: the last events (stale, gone, renamed, README or manifest changed).",
      "grupo": "Catalog",
      "desc": "The listing page carries the same available events as `historico`; updates may be cached for up to 15 minutes. An empty list means no events are available, not proof that nothing changed or that collection covered the requested period. `gerado_em` is the slice generation date, not a per-repository check date; it is empty when no slice was read. Stale means no push for 12 months. Reading does not refresh the source.",
      "params": {
        "id": {
          "desc": "Listing ID, from `Anuncio.id`."
        }
      },
      "retorno": "Historico",
      "erros": {
        "401": "Invalid MAT pass.",
        "402": "Free allowance or MAT credits exhausted; buy a package.",
        "404": "The listing does not exist or is not visible.",
        "409": "Retry conflict or pending read.",
        "413": "Basic read exceeds 1 MiB.",
        "429": "Temporary reading capacity.",
        "503": "Origin or payment verification temporarily unavailable."
      },
      "exemplo": "curl -s $ORIGIN/api/listings/ID/history",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "returns": "{ id, historico, gerado_em, ttl_s, api }",
      "url": "https://staging.agentalog.com/api/listings/:id/history",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/contadores",
      "auth": "none",
      "summary": "Likes, comments and visits of every listing that has any, read from where they are written.",
      "grupo": "Catalog",
      "desc": "Counters include visits, likes and comments. The app and catalog read the same counter table; there is no collection delay. Only listings with a counter above zero are returned. Smoke traffic never counts. Cached for 60 seconds.",
      "retorno": "Contadores",
      "exemplo": "curl -s $ORIGIN/api/contadores",
      "returns": "{ gerado_em, total, truncado, itens }",
      "url": "https://staging.agentalog.com/api/contadores",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/fila",
      "auth": "none",
      "summary": "The public snapshot of the enrichment queue: how much of the catalog has been checked.",
      "grupo": "Operation",
      "desc": "It is public because it is about the catalog's health, not about anyone: aggregate numbers only, no identifiable listing.",
      "retorno": "EstadoFila",
      "exemplo": "curl -s $ORIGIN/api/fila",
      "returns": "{ ok, fila{total,concluidos,vencidos,com_falha,processados,estados,motivos} }",
      "url": "https://staging.agentalog.com/api/fila",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/admin/fila",
      "auth": "token",
      "summary": "The enrichment robot pushes the snapshot of its own queue here.",
      "grupo": "Operation",
      "desc": "Robot credential only: this does not write to the catalog, so there is no reason to accept admin.",
      "corpo": {
        "fila": {
          "tipo": "object",
          "desc": "The queue snapshot: totals, states and reasons.",
          "obrigatorio": true
        }
      },
      "body": {
        "fila": {
          "total": 20182,
          "concluidos": 11675
        }
      },
      "retorno": "Ok",
      "erros": {
        "400": "Body without `fila`.",
        "401": null
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/fila -H \"Authorization: Bearer $TOKEN_ROBO\" -H 'content-type: application/json' -d '{\"fila\":{}}'",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/admin/fila",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/repos",
      "auth": "token",
      "summary": "The enricher writes here what it found out about a repository: stars, forks, state.",
      "grupo": "Operation",
      "desc": "Accepts the enricher's credential OR the admin's — the robot has its own, with less privilege, and the admin gets in to operate by hand without depending on the robot. The Worker collects nothing: it only stores what was already checked outside it.",
      "corpo": {
        "itens": {
          "tipo": "object[]",
          "desc": "Up to 500 checked repositories with repo_slug, stars, forks, PRs, pushed_at and state. Optional listing_ids is an array of up to 50 listing IDs (1–160 letters, digits, underscore or hyphen); only matching listings of that repository are updated. An empty array stores only the repository fact. Omit it only for legacy fanout, still subject to the daily budget.",
          "obrigatorio": true
        }
      },
      "body": {
        "itens": [
          {
            "repo_slug": "x/y",
            "stars": 120,
            "repo_estado": "ativo"
          }
        ]
      },
      "retorno": "Ok",
      "erros": {
        "400": "Body without `itens` or malformed item.",
        "401": "Neither the enricher's nor the admin's credential.",
        "429": "Daily publication budget exhausted; retain pending facts."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/repos -H \"Authorization: Bearer $TOKEN_ROBO\" -H 'content-type: application/json' -d '{\"itens\":[]}'",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/admin/repos",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/admin/listings",
      "auth": "token",
      "summary": "The moderation queue. Without a filter, brings what is pending.",
      "grupo": "Operation",
      "desc": "Accepts `ADMIN_TOKEN` as Bearer or the platform owner's session with a second factor. Each item includes the last automatic moderation reason and review time in `moderation`.",
      "query": {
        "status": {
          "tipo": "string",
          "desc": "Which state to list.",
          "valores": [
            "pending",
            "live",
            "hidden",
            "blocked"
          ],
          "padrao": "pending"
        }
      },
      "retorno": {
        "items": {
          "tipo": "Anuncio[]",
          "desc": "The listings in that state."
        }
      },
      "erros": [
        401
      ],
      "exemplo": "curl -s '$ORIGIN/api/admin/listings?status=pending' -H \"Authorization: Bearer $ADMIN_TOKEN\"",
      "returns": "{ items[{seguranca_nivel?,seguranca_estado?,seguranca_api?,moderation?,verified?,seals?,seal_checked_at?,id,kind,category,name,tagline,body,url,status,origin,origin_id,install,source,transporte,ns,versao,oficial_status,repo_host,topico,linguagem,licenca,repo_topics,repo_slug,stars,forks,prs_abertos,pushed_at,repo_estado,likes,comments,visits,created_at,updated_at,mine,api,go,comments_api,readme_api?,historico?,readme_fonte?,readme_bytes,readme_sha,readme_em,docs_url?,payload}] }",
      "url": "https://staging.agentalog.com/api/admin/listings",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/admin/listings/:id",
      "auth": "token",
      "summary": "Reads one submitted listing for moderation, even beyond the first queue page.",
      "grupo": "Operation",
      "desc": "Accepts `ADMIN_TOKEN` as Bearer or the platform owner's session with a second factor. Includes the full submitted description and URL; it never approves on GET.",
      "params": {
        "id": {
          "desc": "Listing ID, 1–160 letters, digits, underscores or hyphens."
        }
      },
      "retorno": "Anuncio",
      "erros": [
        401,
        404
      ],
      "exemplo": "curl -s $ORIGIN/api/admin/listings/ID -H \"Authorization: Bearer $ADMIN_TOKEN\"",
      "returns": "{ seguranca_nivel?, seguranca_estado?, seguranca_api?, moderation?, verified?, seals?, seal_checked_at?, id, kind, category, name, tagline, body, url, status, origin, origin_id, install, source, transporte, ns, versao, oficial_status, repo_host, topico, linguagem, licenca, repo_topics, repo_slug, stars, forks, prs_abertos, pushed_at, repo_estado, likes, comments, visits, created_at, updated_at, mine, api, go, comments_api, readme_api?, historico?, readme_fonte?, readme_bytes, readme_sha, readme_em, docs_url?, payload }",
      "url": "https://staging.agentalog.com/api/admin/listings/:id",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/listings/:id",
      "auth": "token",
      "summary": "Decides the fate of a listing in the queue: approve, hide or block.",
      "grupo": "Operation",
      "desc": "A submitter with an account gets one e-mail per decision (the decision, the reason and the page or the receipt); repeating the same state sends nothing. A guest or agent owner has no e-mail and polls `GET /api/listings/:id/status`.",
      "params": {
        "id": {
          "desc": "ID of the listing to moderate."
        }
      },
      "corpo": {
        "action": {
          "tipo": "string",
          "desc": "What to do with the listing.",
          "valores": [
            "approve",
            "hide",
            "block"
          ],
          "obrigatorio": true
        },
        "reason": {
          "tipo": "string",
          "desc": "Why, for whoever submitted: it comes back in `GET /api/listings/:id/status`. Required for `block`, optional for `hide`, ignored for `approve` (which clears an earlier reason). Up to 300 characters."
        },
        "fix": {
          "tipo": "object",
          "desc": "Corrections applied together with `approve`, any of `name`, `tagline`, `body`, `category`, with the same validation as a submission. `url` and `kind` are refused: a new URL is what sends a listing back to the queue."
        }
      },
      "body": {
        "action": "hide",
        "reason": "The URL has answered 404 since yesterday."
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always `true`."
        },
        "status": {
          "tipo": "string",
          "desc": "The state the listing ended up in."
        },
        "reason": {
          "tipo": "string",
          "desc": "The reason stored with the decision; empty when none."
        }
      },
      "erros": {
        "400": "`action` outside the list; `reason` missing on `block` or above 300 characters; `fix` outside `approve`; `fix_url` (URL or kind inside the fix); or the refused field of the fix (`name`, `tagline`, `category`, `golpe`).",
        "401": null,
        "404": null
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/listings/ID -H \"Authorization: Bearer $ADMIN_TOKEN\" -H 'content-type: application/json' -d '{\"action\":\"approve\"}'",
      "returns": "{ ok, status, reason }",
      "url": "https://staging.agentalog.com/api/admin/listings/:id",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "DELETE",
      "path": "/api/admin/listings/:id",
      "auth": "token",
      "summary": "Permanently deletes one community submission and its catalog data.",
      "grupo": "Operation",
      "desc": "Admin only. A browser session also requires the standard CSRF header. Send the current name and updated_at to confirm the exact record. Imported records are refused. The transaction removes comments, likes, visits, README and security results. Paid watch and billing history remain. No decision e-mail is sent.",
      "params": {
        "id": {
          "desc": "ID of the community submission."
        }
      },
      "corpo": {
        "name": {
          "tipo": "string",
          "desc": "Exact current name.",
          "obrigatorio": true
        },
        "updated_at": {
          "tipo": "string",
          "desc": "Exact current updated_at.",
          "obrigatorio": true
        }
      },
      "body": {
        "name": "Test submission",
        "updated_at": "2026-10-14T10:00:00.000Z"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Always true."
        },
        "deleted": {
          "tipo": "string",
          "desc": "Deleted listing ID."
        }
      },
      "erros": {
        "400": "Confirmation fields missing.",
        "401": null,
        "403": "Invalid CSRF proof.",
        "404": null,
        "409": "Imported record or record changed since it was read."
      },
      "exemplo": "curl -s -XDELETE $ORIGIN/api/admin/listings/ID -H \"Authorization: Bearer $ADMIN_TOKEN\" -H 'content-type: application/json' -d '{\"name\":\"Test submission\",\"updated_at\":\"2026-10-14T10:00:00.000Z\"}'",
      "returns": "{ ok, deleted }",
      "url": "https://staging.agentalog.com/api/admin/listings/:id",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/admin/carga",
      "auth": "token",
      "summary": "State of the catalog's load sources: last batch, count and failures.",
      "grupo": "Operation",
      "desc": "Accepts `ADMIN_TOKEN` as Bearer or the platform owner's session with a second factor.",
      "query": {
        "fonte": {
          "tipo": "string",
          "desc": "Restricts to one source, e.g. `official_mcp`."
        }
      },
      "retorno": "Carga",
      "erros": [
        401
      ],
      "exemplo": "curl -s $ORIGIN/api/admin/carga -H \"Authorization: Bearer $ADMIN_TOKEN\"",
      "returns": "{ fontes, falhas, runs, orcamento }",
      "url": "https://staging.agentalog.com/api/admin/carga",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/carga",
      "auth": "token",
      "summary": "Requests an update or marks a failure alert as seen.",
      "desc": "run/reset enqueue a request for the next scheduled operation. They do not run synchronously.",
      "grupo": "Operation",
      "corpo": {
        "action": {
          "tipo": "string",
          "desc": "What to do with the source.",
          "valores": [
            "run",
            "visto",
            "reset"
          ],
          "obrigatorio": true
        },
        "fonte": {
          "tipo": "string",
          "desc": "Which source to load or mark, e.g. `official_mcp`."
        }
      },
      "body": {
        "action": "run",
        "fonte": "official_mcp"
      },
      "retorno": "Ok",
      "erros": {
        "400": "`action` outside the list or unknown source.",
        "401": null
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/carga -H \"Authorization: Bearer $ADMIN_TOKEN\" -H 'content-type: application/json' -d '{\"action\":\"run\",\"fonte\":\"official_mcp\"}'",
      "returns": "{ ok }",
      "url": "https://staging.agentalog.com/api/admin/carga",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/internal/moderation",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Reads the community listings that wait for automatic review on c3.",
      "desc": "MODERATION_TOKEN only. Returns up to 50 pending community listings not yet analyzed, oldest first. Each one has a snapshot bound to its exact content. A listing that waits for a new attempt does not hold the others. No owner token, admin access or imported catalog.",
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Request accepted."
        },
        "items": {
          "tipo": "object[]",
          "desc": "Listings with their SHA-256 snapshots, oldest first. Empty when the queue is empty."
        },
        "item": {
          "tipo": "object",
          "desc": "The first entry of items, or null. Kept for the previous worker."
        }
      },
      "erros": {
        "401": "MODERATION_TOKEN required."
      },
      "exemplo": "curl -s $ORIGIN/api/internal/moderation -H \"Authorization: Bearer $MODERATION_TOKEN\"",
      "returns": "{ ok, items, item }",
      "url": "https://staging.agentalog.com/api/internal/moderation",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/internal/moderation",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Confirms a bounded automatic review result.",
      "desc": "MODERATION_TOKEN only. The review checks for concrete signs of fraud, malware or data theft. `approve` is confined to a pending community listing with an HTTPS URL that passes the listing rule. An `approve` outside this scope is recorded as `review`, with the reason. `review` leaves the listing private and sends the owner the reason. The URL, update time and content snapshot must still match.",
      "corpo": {
        "id": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Pending listing ID."
        },
        "url": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Exact URL read from the queue."
        },
        "updated_at": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Listing update time read from the queue."
        },
        "snapshot": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "SHA-256 content snapshot read from the queue, including installation and source fields."
        },
        "decision": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "approve or review."
        },
        "reason": {
          "tipo": "string",
          "desc": "Required for review; maximum 300 characters."
        }
      },
      "body": {
        "id": "lst_ID",
        "url": "https://example.com/tools",
        "updated_at": "2026-09-27 19:00:00",
        "snapshot": "SHA256",
        "decision": "review",
        "reason": "Cannot verify the source."
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Decision recorded."
        },
        "decision": {
          "tipo": "string",
          "desc": "The decision recorded: approve, or review when an approval was outside the scope."
        },
        "id": {
          "tipo": "string",
          "desc": "Listing ID."
        },
        "owner_notified": {
          "tipo": "bool",
          "desc": "The owner's mail server accepted the result notice."
        }
      },
      "erros": {
        "400": "Invalid result.",
        "401": "MODERATION_TOKEN required.",
        "409": "Listing changed or was already reviewed."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/internal/moderation -H \"Authorization: Bearer $MODERATION_TOKEN\" -H \"content-type: application/json\" -d @result.json",
      "returns": "{ ok, decision, id, owner_notified }",
      "url": "https://staging.agentalog.com/api/internal/moderation",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/admin/okf/pendentes",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Reads the queue of OKF bundles submitted through `POST /api/okf/ping`.",
      "desc": "CARGA_TOKEN only. Up to 50 submissions, oldest first. The edge never fetches a key file or a bundle: submissions require key verification before reading the submitter's host — otherwise a stranger could make us fetch arbitrary URLs.",
      "retorno": {
        "pendentes": {
          "tipo": "object[]",
          "desc": "{bundle_url, host, chave, chave_url} still waiting for key verification."
        },
        "lote": {
          "tipo": "int",
          "desc": "Batch ceiling; a full page may have more pending items."
        }
      },
      "erros": {
        "401": "CARGA_TOKEN required."
      },
      "exemplo": "curl -s $ORIGIN/api/admin/okf/pendentes -H \"Authorization: Bearer $CARGA_TOKEN\"",
      "returns": "{ pendentes, lote }",
      "url": "https://staging.agentalog.com/api/admin/okf/pendentes",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/okf/pendentes",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Records verification of submitted bundles.",
      "desc": "CARGA_TOKEN only. Changes the QUEUE, never the catalog: an approved bundle reaches the mosaic through the normal catalog difference, because two doors writing listings would be two truths. A network failure is not a verdict — the submission stays pending and comes back next round.",
      "corpo": {
        "resultados": {
          "tipo": "object[]",
          "obrigatorio": true,
          "desc": "{bundle_url, estado: verificado|recusado, motivo}. At most 50; `motivo` is chave|bundle|okf_version."
        }
      },
      "body": {
        "resultados": [
          {
            "bundle_url": "https://example.com/okf/index.md",
            "estado": "verificado"
          }
        ]
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "The batch was applied."
        },
        "marcados": {
          "tipo": "int",
          "desc": "How many queue rows were touched."
        }
      },
      "erros": {
        "400": "Missing `resultados`, more than 50, or an unknown state.",
        "401": "CARGA_TOKEN required."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/okf/pendentes -H \"Authorization: Bearer $CARGA_TOKEN\" -H 'content-type: application/json' -d '{\"resultados\":[]}'",
      "returns": "{ ok, marcados }",
      "url": "https://staging.agentalog.com/api/admin/okf/pendentes",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/feeds",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Applies prepared feed-index differences for publication.",
      "desc": "Requires CARGA_TOKEN. Maximum 100 items and 2 MB. A daily budget slice of its own stops publication with 429 (`alvo: \"feeds\"`) without holding the catalog back; unconfirmed items remain pending.",
      "corpo": {
        "itens": {
          "tipo": "object[]",
          "obrigatorio": true,
          "desc": "Each delta has id, novo, and either valores (changed columns only) or remove:true."
        },
        "contagens": {
          "tipo": "object[]",
          "desc": "Optional `{ chave, n }` list with the count per facet value, computed on the collector."
        }
      },
      "body": {
        "itens": []
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "The complete batch was accepted."
        },
        "aceitos": {
          "tipo": "int",
          "desc": "Accepted items, including idempotent retries."
        },
        "recusados": {
          "tipo": "int",
          "desc": "Zero on success; invalid batches fail in full."
        }
      },
      "erros": {
        "400": "Invalid delta or facet count.",
        "401": "CARGA_TOKEN required.",
        "413": "More than 100 items or a body over 2 MB.",
        "429": "Daily feed slice exhausted; retain pending items."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/feeds -H \"Authorization: Bearer $CARGA_TOKEN\" -d @lote.json",
      "returns": "{ ok, aceitos, recusados }",
      "url": "https://staging.agentalog.com/api/admin/feeds",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/catalogo",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Applies prepared catalog differences for publication.",
      "desc": "Requires CARGA_TOKEN. Imported sources only; no SQL, community records or user fields. Maximum 25 items and 2 MB. An atomic daily budget stops publication with 429; retain unconfirmed differences.",
      "corpo": {
        "itens": {
          "tipo": "object[]",
          "obrigatorio": true,
          "desc": "Each delta has id, origin, origin_id, novo, valores (changed catalog columns only), optional prepared pacotes and owner for new rows."
        }
      },
      "body": {
        "itens": []
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "The complete batch was accepted."
        },
        "aceitos": {
          "tipo": "int",
          "desc": "Accepted items, including idempotent retries."
        },
        "recusados": {
          "tipo": "int",
          "desc": "Zero on success; invalid batches fail in full."
        }
      },
      "erros": {
        "400": "Invalid delta.",
        "401": "CARGA_TOKEN required.",
        "409": "Identity differs from destination.",
        "413": "Batch or body too large.",
        "429": "Daily publication budget exhausted; `alvo` names the slice that ran out (`catalogo` or `okf`, each with its own cap)."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/catalogo -H \"Authorization: Bearer $CARGA_TOKEN\" -H 'content-type: application/json' -d '{\"itens\":[]}'",
      "returns": "{ ok, aceitos, recusados }",
      "url": "https://staging.agentalog.com/api/admin/catalogo",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/readmes",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Stores documentation for listings without a repository.",
      "desc": "Requires CARGA_TOKEN. The listing exposes the document with attribution. Unchanged text is not written again. Maximum 20 items and 2 MB.",
      "corpo": {
        "itens": {
          "tipo": "object[]",
          "obrigatorio": true,
          "desc": "{listing_id, fonte: npm|pypi, readme} — README of 1 to 200,000 characters; no repeated listing_id."
        }
      },
      "body": {
        "itens": [
          {
            "listing_id": "mcp_x",
            "fonte": "npm",
            "readme": "# X"
          }
        ]
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "The batch was processed."
        },
        "aceitos": {
          "tipo": "int",
          "desc": "READMEs stored (new or changed)."
        },
        "iguais": {
          "tipo": "int",
          "desc": "Unchanged READMEs: nothing written."
        },
        "recusados": {
          "tipo": "string[]",
          "desc": "listing_ids unknown to the catalog; the rest of the batch is applied."
        }
      },
      "erros": {
        "400": "Malformed item.",
        "401": "CARGA_TOKEN required.",
        "413": "More than 20 items or body over 2 MB.",
        "429": "Daily publication budget exhausted; retain pending documents.",
        "503": "R2 not configured: nothing indexed."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/readmes -H \"Authorization: Bearer $CARGA_TOKEN\" -H 'content-type: application/json' -d '{\"itens\":[]}'",
      "returns": "{ ok, aceitos, iguais, recusados }",
      "url": "https://staging.agentalog.com/api/admin/readmes",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/fts",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Indexes one page of live listings into the full-text search index.",
      "desc": "Requires CARGA_TOKEN. Pages by rowid: `apos` is the last rowid already indexed, `limite` the page size (≤ 500). Each page reserves 5 write units per listing in the daily catalog budget before writing; 429 means try tomorrow. An empty page marks the index ready (`fts:pronto`) and the search switches from LIKE to the index.",
      "corpo": {
        "apos": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Last rowid already indexed; 0 to start."
        },
        "limite": {
          "tipo": "int",
          "desc": "Page size, 1–500 (default 500)."
        }
      },
      "body": {
        "apos": 0,
        "limite": 500
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "The page was processed."
        },
        "indexados": {
          "tipo": "int",
          "desc": "Listings written to the index in this page."
        },
        "ultimo": {
          "tipo": "int",
          "desc": "Last rowid indexed — send it back as `apos`."
        },
        "pronto": {
          "tipo": "bool",
          "desc": "`true` when there was nothing left: the index covers the catalog."
        }
      },
      "erros": {
        "400": "Invalid page.",
        "401": "CARGA_TOKEN required.",
        "429": "Daily catalog budget exhausted."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/fts -H \"Authorization: Bearer $CARGA_TOKEN\" -H 'content-type: application/json' -d '{\"apos\":0,\"limite\":500}'",
      "returns": "{ ok, indexados, ultimo, pronto }",
      "url": "https://staging.agentalog.com/api/admin/fts",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/admin/carga/c3",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Reads pending operator commands and an indexed community delta.",
      "desc": "CARGA_TOKEN only. Up to 100 community rows ordered by (updated_at,id), older than one minute. Imported catalog rows are never read. A full page advances to its last row; a short page advances to ate with empty apos.",
      "query": {
        "desde": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "UTC cursor, YYYY-MM-DD HH:mm:ss."
        },
        "apos": {
          "tipo": "string",
          "desc": "ID after the last received row; empty for a new time boundary."
        }
      },
      "retorno": {
        "pedidos": {
          "tipo": "object[]",
          "desc": "Commands {fonte,id,acao}; restricted to the operation service."
        },
        "comunidade": {
          "tipo": "object[]",
          "desc": "Changed {id,source,status,updated_at} records."
        },
        "ate": {
          "tipo": "string",
          "desc": "Exclusive UTC upper bound of the feed."
        }
      },
      "erros": {
        "400": "Invalid cursor.",
        "401": "CARGA_TOKEN required."
      },
      "exemplo": "curl -sG $ORIGIN/api/admin/carga/c3 --data-urlencode \"desde=2026-09-06 00:00:00\" -H \"Authorization: Bearer $CARGA_TOKEN\"",
      "returns": "{ pedidos, comunidade, ate }",
      "url": "https://staging.agentalog.com/api/admin/carga/c3",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/carga/c3",
      "auth": "token",
      "grupo": "Operation",
      "summary": "Publishes source status and acknowledges operator commands completed by the operation service.",
      "desc": "CARGA_TOKEN only. Up to 12 statuses and acknowledgements. A retry with the same run ID does not rewrite status; an old acknowledgement cannot erase a newer command.",
      "corpo": {
        "estados": {
          "tipo": "object[]",
          "obrigatorio": true,
          "desc": "Source run summaries: fonte,id,status,cursor,updated_since,erro,pages,imported,skipped,more,started_at,finished_at."
        },
        "aceites": {
          "tipo": "object[]",
          "obrigatorio": true,
          "desc": "Completed command {fonte,id} pairs."
        }
      },
      "body": {
        "estados": [],
        "aceites": []
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Accepted."
        },
        "estados": {
          "tipo": "int",
          "desc": "Accepted statuses."
        },
        "aceites": {
          "tipo": "int",
          "desc": "Accepted command acknowledgements."
        }
      },
      "erros": {
        "400": "Invalid status or acknowledgement.",
        "401": "CARGA_TOKEN required.",
        "429": "Daily budget exhausted."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/carga/c3 -H \"Authorization: Bearer $CARGA_TOKEN\" -H 'content-type: application/json' -d '{\"estados\":[],\"aceites\":[]}'",
      "returns": "{ ok, estados, aceites }",
      "url": "https://staging.agentalog.com/api/admin/carga/c3",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/credito/x402/saude",
      "auth": "none",
      "exemplo": "curl -s $ORIGIN/api/credito/x402/saude",
      "grupo": "Credit",
      "summary": "x402 verifier health: pending payments, missing hashes, failed or stalled reconciliation.",
      "retorno": {
        "verificado_em": {
          "tipo": "string",
          "desc": "Reading time in UTC."
        },
        "ativo": {
          "tipo": "boolean",
          "desc": "Verifier configured in this process."
        },
        "tarefas": {
          "tipo": "object[]",
          "desc": "Failures with id and reason, without payer data. Bounded counts show +."
        }
      },
      "erros": {
        "503": "Verifier unavailable in this process."
      },
      "returns": "{ verificado_em, ativo, tarefas }",
      "url": "https://staging.agentalog.com/api/credito/x402/saude",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/credito/barrados/saude",
      "auth": "none",
      "exemplo": "curl -s $ORIGIN/api/credito/barrados/saude",
      "grupo": "Credit",
      "summary": "People who paid and were blocked on this site in the last 24 hours: the site asked for payment from someone with balance or a plan, or charged and did not deliver.",
      "retorno": {
        "verificado_em": {
          "tipo": "string",
          "desc": "Reading time in UTC."
        },
        "ativo": {
          "tipo": "boolean",
          "desc": "The reading worked."
        },
        "total": {
          "tipo": "int",
          "desc": "Number of different cases."
        },
        "tarefas": {
          "tipo": "object[]",
          "desc": "Up to 8 cases, with class, route, count and last time, without payer data."
        }
      },
      "returns": "{ verificado_em, ativo, total, tarefas }",
      "url": "https://staging.agentalog.com/api/credito/barrados/saude",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/credito/conta",
      "auth": "credito",
      "exemplo": "curl -s $ORIGIN/api/credito/conta -H 'Cookie: <sessão>'",
      "grupo": "Credit",
      "summary": "The balance of the session account: the sum of its purchases in this environment, in every product, without the code. With movimentos=1, the statement of the account.",
      "query": {
        "movimentos": {
          "tipo": "string",
          "desc": "`1`: reads only the paged statement of the account, without the balance."
        },
        "de": {
          "tipo": "string",
          "desc": "Inclusive start in UTC ISO 8601 with milliseconds. Default: 1970-01-01T00:00:00.000Z."
        },
        "ate": {
          "tipo": "string",
          "desc": "Exclusive end in UTC ISO 8601 with milliseconds. Default: now. Keep the value between pages."
        },
        "antes": {
          "tipo": "string",
          "desc": "The `proximo` cursor of the previous page. Only with movimentos=1."
        },
        "limite": {
          "tipo": "int",
          "desc": "1 to 50 entries per page; default 20. Only with movimentos=1."
        }
      },
      "retorno": {
        "saldo_micros": {
          "tipo": "int",
          "desc": "The balance in millionths of a dollar."
        },
        "saldo_usd": {
          "tipo": "string",
          "desc": "The balance in dollars, formatted."
        },
        "referencia_usd": {
          "tipo": "string",
          "desc": "The balance right after the last top-up, added across the wallets with a balance: the base of what is left."
        },
        "cotacao_brl_por_usd": {
          "tipo": "number",
          "desc": "The BRL rate the screen uses to show the balance."
        },
        "movimentos": {
          "tipo": "object[]",
          "desc": "Only with movimentos=1: id, em, valor_usd, saldo_usd, motivo, produto and recurso, newest first."
        },
        "proximo": {
          "tipo": "string",
          "desc": "Only with movimentos=1: the cursor of the next page or null."
        }
      },
      "erros": {
        "400": "Invalid period, limit or cursor.",
        "401": "No session."
      },
      "returns": "{ saldo_micros, saldo_usd, referencia_usd, cotacao_brl_por_usd, movimentos, proximo }",
      "url": "https://staging.agentalog.com/api/credito/conta",
      "auth_detail": "Credit token in `Authorization: Bearer cred_…` or `X-Credito`. For recovered x402 funds, use the wallet credential mmw_… in Bearer or X-Wallet-Token, issued through /api/auth/wallet/agent/start and /api/auth/wallet/agent/token."
    },
    {
      "method": "POST",
      "path": "/api/credito/conta",
      "auth": "credito",
      "exemplo": "curl -s -XPOST $ORIGIN/api/credito/conta -H 'Authorization: Bearer cred_…' -H 'Cookie: <sessão>'",
      "grupo": "Credit",
      "summary": "Links credit bought without an account to the account of the session, USDC included. Then the balance works in the products of the shared credit with `X-Credito: conta`, added to the other purchases of the account.",
      "retorno": {
        "ok": {
          "tipo": "boolean",
          "desc": "The link was checked."
        },
        "ligadas": {
          "tipo": "int",
          "desc": "Purchases linked now. Zero when the purchase already has an account."
        },
        "da_conta": {
          "tipo": "boolean",
          "desc": "The balance of this code is already in the account balance."
        }
      },
      "erros": {
        "401": "No session or no credit code."
      },
      "returns": "{ ok, ligadas, da_conta }",
      "url": "https://staging.agentalog.com/api/credito/conta",
      "auth_detail": "Credit token in `Authorization: Bearer cred_…` or `X-Credito`. For recovered x402 funds, use the wallet credential mmw_… in Bearer or X-Wallet-Token, issued through /api/auth/wallet/agent/start and /api/auth/wallet/agent/token."
    },
    {
      "method": "POST",
      "path": "/api/credito",
      "auth": "none",
      "summary": "Top up prepaid credit: pay once with x402 and get the token that debits on any API of the house.",
      "grupo": "Credit",
      "preco_usd_faixa": [
        0.1,
        25
      ],
      "query": {
        "usd": {
          "tipo": "number",
          "desc": "Package: 0.1, 1, 5, 10 or 25 dollars.",
          "obrigatorio": true,
          "enum": [
            0.1,
            1,
            5,
            10,
            25
          ]
        }
      },
      "retorno": {
        "token": {
          "tipo": "string",
          "desc": "Bearer token for the balance (`cred_…`). Shown ONCE — it cannot be recovered."
        },
        "saldo_usd": {
          "tipo": "string",
          "desc": "Credited balance."
        },
        "guarde": {
          "tipo": "string",
          "desc": "Warning that the token is the bearer of the credit."
        },
        "usar": {
          "tipo": "string",
          "desc": "How to present the token on paid routes."
        },
        "usar_com_outra_credencial": {
          "tipo": "string",
          "desc": "The `X-Credito` header, for when `Authorization` already carries another credential."
        },
        "saldo_em": {
          "tipo": "string",
          "desc": "Where to check balance and statement."
        },
        "onde_gastar": {
          "tipo": "object",
          "desc": "`precos`: the paid actions and prices of this product (`/api/pricing`); `produtos`: the APIs.json with our other products."
        }
      },
      "erros": {
        "400": "Package outside the list (0.1, 1, 5, 10 or 25).",
        "402": "Unpaid — the body carries the x402 `accepts[]`."
      },
      "exemplo": "curl -s -XPOST '$ORIGIN/api/credito?usd=10'",
      "returns": "{ token, saldo_usd, guarde, usar, usar_com_outra_credencial, saldo_em, onde_gastar }",
      "url": "https://staging.agentalog.com/api/credito",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/credito",
      "auth": "credito",
      "summary": "Balance and statement with cred_…; wallet balance and up to 20 recovery records with mmw_….",
      "desc": "A request without a token receives 401. The Link header points to the x402 manifest. When billing is configured, accepts[] contains the same terms as the smallest POST top-up. GET cannot charge or create credit.",
      "grupo": "Credit",
      "retorno": {
        "saldo_micros": {
          "tipo": "int",
          "desc": "Balance in micro-dollars (1e-6 USD)."
        },
        "saldo_usd": {
          "tipo": "string",
          "desc": "Formatted balance."
        },
        "criado_em": {
          "tipo": "string",
          "desc": "When the credit was opened."
        },
        "movimentos": {
          "tipo": "object[]",
          "desc": "Recent credits and debits, with product and resource."
        },
        "wallet": {
          "tipo": "string",
          "desc": "Only with mmw_…: authenticated wallet address."
        },
        "payments": {
          "tipo": "object[]",
          "desc": "Only with mmw_…: up to 20 payments with id, produto, rede, tx_hash, micros, estado and criado_ms. creditado means recovered balance."
        },
        "onde_gastar": {
          "tipo": "object",
          "desc": "`precos`: the paid actions and prices of this product; `produtos`: the APIs.json with our other products."
        }
      },
      "erros": {
        "401": "No token, or unknown token."
      },
      "exemplo": "curl -s $ORIGIN/api/credito -H 'Authorization: Bearer cred_…'",
      "returns": "{ saldo_micros, saldo_usd, criado_em, movimentos, wallet, payments, onde_gastar }",
      "url": "https://staging.agentalog.com/api/credito",
      "auth_detail": "Credit token in `Authorization: Bearer cred_…` or `X-Credito`. For recovered x402 funds, use the wallet credential mmw_… in Bearer or X-Wallet-Token, issued through /api/auth/wallet/agent/start and /api/auth/wallet/agent/token."
    },
    {
      "method": "GET",
      "path": "/api/credito/pix",
      "auth": "none",
      "summary": "Credit by Pix (Brazil): the key, today's rate, the packs in reais and what the receipt accepts.",
      "grupo": "Credit",
      "retorno": {
        "chave": {
          "tipo": "string",
          "desc": "The Pix key that receives the payment."
        },
        "brl_por_usd": {
          "tipo": "number",
          "desc": "Rate for the packs: the PTAX sale rate of the latest Central Bank of Brazil bulletin plus a 9% margin."
        },
        "pacotes": {
          "tipo": "object[]",
          "desc": "The packs (3, 5, 10 or 25 dollars), each with `brl_centavos` and `copia_e_cola` (the Pix copy-and-paste code for the amount, the same text as the QR: the bank app comes with the amount filled in)."
        },
        "comprovante": {
          "tipo": "object",
          "desc": "Accepted types (photo or PDF) and the maximum size, in bytes."
        },
        "liberacao": {
          "tipo": "string",
          "desc": "`manual`: the owner checks the Pix and releases it."
        }
      },
      "exemplo": "curl -s $ORIGIN/api/credito/pix",
      "returns": "{ chave, brl_por_usd, pacotes, comprovante, liberacao }",
      "url": "https://staging.agentalog.com/api/credito/pix",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/credito/pix",
      "auth": "none",
      "summary": "Request credit paid by Pix: multipart with `usd`, `comprovante` (photo or PDF up to 2 MB) and `email`; the rest is optional.",
      "desc": "The credit code comes back in the response and works once the owner checks the Pix and releases it (by hand, usually the same day). `email` is required: it is how the owner reaches the person. Optional: `nome`, `pagina` (the page the request came from, up to 2,000 characters) and what the person was buying when the 402 came — `recurso` (up to 2,000), `descricao` (up to 300) and `preco_usd` (decimal, e.g. `0.50`); and `navegador_id` (a UUID that links the requests from the same browser). Everything that arrives is recorded with the request — the receipt included —, with the signed-in account (checked by the session cookie), the network and browser.",
      "grupo": "Credit",
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "Request id, to follow it."
        },
        "estado": {
          "tipo": "string",
          "desc": "`pendente` until the decision."
        },
        "credito": {
          "tipo": "string",
          "desc": "The `cred_…` token, shown ONCE; it works after the release."
        },
        "estado_em": {
          "tipo": "string",
          "desc": "Where to follow the request."
        }
      },
      "erros": {
        "400": "Pack outside the list (3, 5, 10 or 25), no receipt or no valid e-mail.",
        "413": "Receipt above 2 MB.",
        "415": "Receipt that is neither a photo (JPEG, PNG, WebP) nor a PDF.",
        "429": "This network already sent today's requests.",
        "502": "The e-mail to the owner did not go out: the request is recorded as `falhou`; send it again.",
        "503": "Review queue full, or Pix not available in this app."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/credito/pix -F usd=5 -F email=you@company.com -F comprovante=@pix.pdf",
      "returns": "{ id, estado, credito, estado_em }",
      "url": "https://staging.agentalog.com/api/credito/pix",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/credito/pix/:id",
      "auth": "none",
      "summary": "Status of a Pix credit request: `pendente`, `liberado`, `recusado` or `falhou`.",
      "grupo": "Credit",
      "params": {
        "id": {
          "desc": "Request id (32 hex).",
          "exemplo": "0123456789abcdef0123456789abcdef"
        }
      },
      "retorno": {
        "estado": {
          "tipo": "string",
          "desc": "`pendente`, `liberado`, `recusado` or `falhou` (the e-mail to the owner did not go out; send again)."
        },
        "usd": {
          "tipo": "int",
          "desc": "The requested pack."
        },
        "decidido_em": {
          "tipo": "string",
          "desc": "When the owner decided, or `null`."
        }
      },
      "erros": {
        "404": "Unknown request."
      },
      "exemplo": "curl -s $ORIGIN/api/credito/pix/0123456789abcdef0123456789abcdef",
      "returns": "{ estado, usd, decidido_em }",
      "url": "https://staging.agentalog.com/api/credito/pix/:id",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/credito/asaas/:id/cancelar",
      "auth": "none",
      "grupo": "Crédito",
      "summary": "Cancels a pending charge when the payment dialog closes.",
      "desc": "Requires the `cancelamento` capability returned at creation. An older credit charge accepts its token in `credito`. The product and environment must match. This does not refund payments or remove records. 202 means cancellation is pending; the scheduled worker retries provider failures.",
      "params": {
        "id": {
          "desc": "Charge id (32 hex).",
          "exemplo": "0123456789abcdef0123456789abcdef"
        }
      },
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "Charge id."
        },
        "estado": {
          "tipo": "string",
          "desc": "`cancelando`, `vencido`, or the confirmed final state."
        }
      },
      "erros": {
        "404": "Invalid charge or capability, or a different product or environment."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/credito/asaas/0123456789abcdef0123456789abcdef/cancelar -H 'content-type: application/json' -d '{\"cancelamento\":\"<bilhete>\"}'",
      "returns": "{ id, estado }",
      "url": "https://staging.agentalog.com/api/credito/asaas/:id/cancelar",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/credito/asaas",
      "auth": "none",
      "summary": "Automatic Pix: whether it is available in this app, the packs in reais and the balance the product sells.",
      "grupo": "Crédito",
      "retorno": {
        "disponivel": {
          "tipo": "boolean",
          "desc": "`false` when the app has no Asaas configured (use the Pix with receipt)."
        },
        "pacotes": {
          "tipo": "object[]",
          "desc": "The credit packs (3, 5, 10 or 25 dollars), with `brl_centavos`."
        },
        "exatos": {
          "tipo": "object[]",
          "desc": "Prices declared by the app, with `usd` and `brl_centavos`. Amounts start at R$ 5.00 and cannot exceed R$ 10,000."
        },
        "saldo": {
          "tipo": "object",
          "desc": "When the product sells a balance in reais: the range and whether the account can buy."
        },
        "precisa_documento": {
          "tipo": "boolean",
          "desc": "Whether the payer's CPF or CNPJ is still required."
        }
      },
      "exemplo": "curl -s $ORIGIN/api/credito/asaas",
      "returns": "{ disponivel, pacotes, exatos, saldo, precisa_documento }",
      "url": "https://staging.agentalog.com/api/credito/asaas",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/credito/asaas",
      "auth": "none",
      "summary": "Creates a dynamic Pix: JSON with `oferta` (`pacote` with `usd`, or `saldo` with `centavos`) and the payer.",
      "desc": "The payment releases what was bought by itself: the pack becomes the `cred_…` token already in the response; the balance goes to the logged-in account's organization. The first purchase needs `documento` (CPF or CNPJ, sent to the gateway and not stored here) and `nome`; `email`, `pagina` and `navegador_id` are optional. With `forma: \"cartao_boleto\"` the charge is open: the response brings `pagamento_em`, the gateway page where you pay by card, boleto or Pix (due in three days). With `forma: \"cartao\"` and `cartao` (`titular`, `numero`, `mes`, `ano`, `cvv`, `documento`, `email`, `cep`, `numero_endereco`, `telefone`), the charge is paid by card in the same request: 200 with `estado: \"pago\"`, 202 with `conferir` while the issuer reviews it, 422 when the card is declined; the card is not stored. Set `usd` to an amount from `pacotes` or `exatos` in the GET response. The server sets the amount in cents and rejects amounts that the app has not declared.",
      "grupo": "Crédito",
      "retorno": {
        "id": {
          "tipo": "string",
          "desc": "Charge id, to follow up."
        },
        "credito": {
          "tipo": "string",
          "desc": "For a pack: the `cred_…` token, shown ONCE; valid when the payment arrives."
        },
        "forma": {
          "tipo": "string",
          "desc": "`pix` (the default), `cartao` or `cartao_boleto`."
        },
        "pix": {
          "tipo": "object",
          "desc": "`copia_e_cola`, `imagem` (PNG QR, data URI) and `expira_em`; `pix` form only."
        },
        "pagamento_em": {
          "tipo": "string",
          "desc": "In the `cartao_boleto` form: the gateway payment page."
        },
        "estado": {
          "tipo": "string",
          "desc": "In the `cartao` form: `pago`, or `pendente` with `conferir`."
        },
        "estado_em": {
          "tipo": "string",
          "desc": "Where to follow the payment."
        },
        "cancelamento": {
          "tipo": "string",
          "desc": "Capability to cancel a pending Pix or boleto charge."
        }
      },
      "erros": {
        "400": "Credit amount outside `pacotes` and `exatos`, amount out of range, invalid CPF/CNPJ, name or e-mail, invalid card data (`cartao_dados`, with the `campo`), or the gateway refused the payer (`pagador_recusado`, with the reason in `detalhe`).",
        "422": "Card declined (`cartao_recusado`, with the `campo` when the gateway says which); try another card with `POST /api/credito/asaas/:id/cartao`.",
        "429": "Limit of 3 attempts per minute or 10 per day, per account or network, or the card limit.",
        "502": "The gateway did not create the Pix; try again.",
        "503": "Automatic Pix unavailable in this app, the gateway is busy (`asaas_ocupado`, wait `retry_after_s`), or too many charges from people not signed in waiting for payment."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/credito/asaas -H 'content-type: application/json' -d '{\"oferta\":\"pacote\",\"usd\":5,\"documento\":\"000.000.000-00\",\"nome\":\"Ana\"}'",
      "returns": "{ id, credito, forma, pix, pagamento_em, estado, estado_em, cancelamento }",
      "url": "https://staging.agentalog.com/api/credito/asaas",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/credito/asaas/:id",
      "auth": "none",
      "summary": "State of an automatic Pix charge: `pendente`, `pago`, `vencido`, `estornado` or `falhou`.",
      "grupo": "Crédito",
      "params": {
        "id": {
          "desc": "Charge id (32 hex).",
          "exemplo": "0123456789abcdef0123456789abcdef"
        }
      },
      "retorno": {
        "estado": {
          "tipo": "string",
          "desc": "`pago` releases the pack token or the balance; a Pix paid after the due date counts."
        },
        "pago_em": {
          "tipo": "string",
          "desc": "When the payment was confirmed, or `null`."
        }
      },
      "erros": {
        "404": "Unknown charge."
      },
      "exemplo": "curl -s $ORIGIN/api/credito/asaas/0123456789abcdef0123456789abcdef",
      "returns": "{ estado, pago_em }",
      "url": "https://staging.agentalog.com/api/credito/asaas/:id",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/credito/asaas/:id/cartao",
      "auth": "none",
      "summary": "Pays a card charge whose card was declined with another card: the same charge, never charged twice.",
      "desc": "JSON with the `cartao` (the same fields as `POST /api/credito/asaas`) and, without an account, the `navegador_id` that created the charge. Only a card charge waiting for payment, by whoever created it, and up to five attempts per charge.",
      "grupo": "Crédito",
      "params": {
        "id": {
          "desc": "Id da cobrança (32 hex).",
          "exemplo": "0123456789abcdef0123456789abcdef"
        }
      },
      "retorno": {
        "estado": {
          "tipo": "string",
          "desc": "`pago`, or `pendente` with `conferir` while the issuer reviews it."
        },
        "estado_em": {
          "tipo": "string",
          "desc": "Where to follow the payment."
        }
      },
      "erros": {
        "400": "Invalid card data (`cartao_dados`, with the `campo`).",
        "404": "Unknown charge, someone else's charge, or not a card charge.",
        "409": "The charge expired or was closed; start the payment again.",
        "422": "Card declined (`cartao_recusado`).",
        "429": "Used up the card attempts for this charge or for today."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/credito/asaas/0123456789abcdef0123456789abcdef/cartao -H 'content-type: application/json' -d '{\"cartao\":{…}}'",
      "returns": "{ estado, estado_em }",
      "url": "https://staging.agentalog.com/api/credito/asaas/:id/cartao",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/credito/asaas/saude",
      "auth": "none",
      "summary": "Health of this app's Pix and enabled subscriptions: failures and reasons for the dashboard.",
      "grupo": "Crédito",
      "retorno": {
        "ativo": {
          "tipo": "boolean",
          "desc": "`false` when Asaas and subscriptions are disabled."
        },
        "tarefas": {
          "tipo": "object[]",
          "desc": "Each problem has `id`, `falhando`, and `motivo`. Includes Pix and, when enabled, subscription recovery, queue, and budget. Does not call the provider."
        }
      },
      "exemplo": "curl -s $ORIGIN/api/credito/asaas/saude",
      "returns": "{ ativo, tarefas }",
      "url": "https://staging.agentalog.com/api/credito/asaas/saude",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/boletim/config",
      "auth": "none",
      "grupo": "Newsletter",
      "summary": "Available newsletter topics, account support and delivery interval.",
      "retorno": {
        "disponivel": {
          "tipo": "bool",
          "desc": "Subscription service is configured."
        },
        "conta": {
          "tipo": "bool",
          "desc": "Verified accounts can manage their own subscription."
        },
        "topicos": {
          "tipo": "object[]",
          "desc": "Published topic slugs and translated names."
        },
        "canais": {
          "tipo": "string[]",
          "desc": "Delivery channels: news, and site updates where the site has them."
        },
        "intervaloDias": {
          "tipo": "int",
          "desc": "Minimum delivery interval in days."
        }
      },
      "exemplo": "curl -s $ORIGIN/api/boletim/config",
      "returns": "{ disponivel, conta, topicos, canais, intervaloDias }",
      "url": "https://staging.agentalog.com/api/boletim/config",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/boletim/assinatura",
      "auth": "session",
      "grupo": "Newsletter",
      "summary": "The subscription for the account's verified email.",
      "desc": "Private response. No email parameter. Returns email, state, revision, topics, channels and language.",
      "retorno": {
        "assinatura": {
          "tipo": "object",
          "desc": "Current account subscription."
        }
      },
      "erros": {
        "401": "Sign in first.",
        "503": "Subscription service unavailable."
      },
      "exemplo": "await MMConta.fetch(\"$ORIGIN/api/boletim/assinatura\").then(r => r.json());",
      "exemploLinguagem": "js",
      "returns": "{ assinatura }",
      "url": "https://staging.agentalog.com/api/boletim/assinatura",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "POST",
      "path": "/api/boletim/assinatura",
      "auth": "session",
      "grupo": "Newsletter",
      "summary": "Subscribe, save preferences or unsubscribe from the account.",
      "desc": "The verified account supplies the email. Requires same-origin CSRF and the current revision. News and site updates require separate choices. Existing subscribers keep news only.",
      "corpo": {
        "ativo": {
          "tipo": "bool",
          "obrigatorio": true,
          "desc": "False unsubscribes in one request."
        },
        "revisao": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Revision from the private GET."
        },
        "topicos": {
          "tipo": "string[]",
          "desc": "Up to 40 published topic slugs. Empty selects all news topics."
        },
        "canais": {
          "tipo": "string[]",
          "desc": "noticias and/or novidades. Defaults to noticias when omitted."
        },
        "lingua": {
          "tipo": "string",
          "valores": [
            "en",
            "pt"
          ],
          "desc": "Language used in newsletter messages."
        }
      },
      "body": {
        "ativo": false,
        "revisao": 1
      },
      "retorno": {
        "assinatura": {
          "tipo": "object",
          "desc": "Saved subscription with the next revision."
        }
      },
      "erros": {
        "400": "Invalid preferences.",
        "401": "Sign in first.",
        "403": "Origin or CSRF rejected.",
        "409": "Reload the subscription; its revision changed or delivery is suppressed.",
        "429": "Try later."
      },
      "exemplo": "await MMConta.fetch(\"$ORIGIN/api/boletim/assinatura\", {method:\"POST\",headers:{\"Content-Type\":\"application/json\"},body:JSON.stringify({ativo:false,revisao:1})});",
      "exemploLinguagem": "js",
      "returns": "{ assinatura }",
      "url": "https://staging.agentalog.com/api/boletim/assinatura",
      "auth_detail": "Global account: the HttpOnly session cookie of this domain, set when you sign in at `/conta/global`. Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. A write with the cookie of an ended session answers 401 `session_ended` — sign in again; it never turns into the guest. No bearer token is issued to humans."
    },
    {
      "method": "GET",
      "path": "/briefings/feed.xml",
      "auth": "none",
      "grupo": "Briefings",
      "summary": "The latest 30 engineering links as RSS.",
      "retorno": {
        "_texto": "application/rss+xml — titles, summaries, source links and topics."
      },
      "exemplo": "curl -s $ORIGIN/briefings/feed.xml",
      "returns": "application/rss+xml — titles, summaries, source links and topics.",
      "url": "https://staging.agentalog.com/briefings/feed.xml",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/briefings/feed.json",
      "auth": "none",
      "grupo": "Briefings",
      "summary": "The latest 30 engineering links as JSON Feed.",
      "retorno": {
        "_texto": "application/feed+json — JSON Feed 1.1 with source links and topics."
      },
      "exemplo": "curl -s $ORIGIN/briefings/feed.json",
      "returns": "application/feed+json — JSON Feed 1.1 with source links and topics.",
      "url": "https://staging.agentalog.com/briefings/feed.json",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/briefings",
      "auth": "none",
      "summary": "Every briefing topic with its count, the newest items across all of them and the subscription state.",
      "grupo": "Briefings",
      "desc": "Topics are public bookmark folders (CUDA, inference, RAG, agents…). Each item is a post someone saved, its main source, the source type and a two-line summary in English and Portuguese. `?resumo=1` returns only `total` and each topic's `slug` and `total`. 404 until the first publication.",
      "query": {
        "resumo": {
          "tipo": "string",
          "desc": "`1` returns only the counts.",
          "valores": [
            "1"
          ]
        }
      },
      "retorno": "IndiceDosBriefings",
      "erros": {
        "404": "Briefings are not published yet."
      },
      "exemplo": "curl -s $ORIGIN/api/briefings",
      "returns": "{ total, atualizado_em, topicos[{slug,nome,descricao,total,atualizado_em,tipos,api?,pagina?}], recentes[{id,slug,topicos?,data,entrou?,autor,post,fonte,tipo,previa?,titulo,resumo,importa}], inscricao, _links }",
      "url": "https://staging.agentalog.com/api/briefings",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/briefings/itens",
      "auth": "none",
      "colecao": {
        "porPagina": 20,
        "anda": "next"
      },
      "summary": "Every published item, filtered by topic and source type, with the count of each filter value.",
      "grupo": "Briefings",
      "desc": "Values inside one parameter are OR'd; the two parameters are AND'd. Unknown values are ignored. Follow `_links.next` to walk everything.",
      "query": {
        "topico": {
          "tipo": "string",
          "desc": "Topic slugs, comma-separated.",
          "exemplo": "rag,inference"
        },
        "tipo": {
          "tipo": "string",
          "desc": "Source types, comma-separated.",
          "valores": [
            "paper",
            "repo",
            "model",
            "dataset",
            "demo",
            "video",
            "docs",
            "article",
            "post"
          ],
          "exemplo": "paper,repo"
        },
        "page": {
          "tipo": "int",
          "desc": "Page, 1–999; 20 items per page.",
          "padrao": 1
        }
      },
      "retorno": "PaginaDeBriefings",
      "erros": {
        "404": "Briefings are not published yet."
      },
      "exemplo": "curl -s '$ORIGIN/api/briefings/itens?topico=rag&tipo=paper'",
      "returns": "{ total, pagina, paginas, filtros, facetas, itens[{id,slug,topicos?,data,entrou?,autor,post,fonte,tipo,previa?,titulo,resumo,importa}], _links }",
      "url": "https://staging.agentalog.com/api/briefings/itens",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/briefings/:slug",
      "auth": "none",
      "summary": "One topic, newest first, 20 items per page.",
      "grupo": "Briefings",
      "desc": "The same list the HTML page at `/briefings/<slug>/` shows.",
      "params": {
        "slug": {
          "tipo": "string",
          "desc": "Topic slug from `/api/briefings`.",
          "exemplo": "rag"
        }
      },
      "query": {
        "page": {
          "tipo": "int",
          "desc": "Page, 1–999; 20 items per page.",
          "padrao": 1
        }
      },
      "retorno": "TopicoDoBriefing",
      "erros": {
        "404": "Unknown briefing topic."
      },
      "exemplo": "curl -s '$ORIGIN/api/briefings/rag?page=2'",
      "returns": "{ slug, nome, descricao, total, atualizado_em, pagina, paginas, itens[{id,slug,topicos?,data,entrou?,autor,post,fonte,tipo,previa?,titulo,resumo,importa}], _links }",
      "url": "https://staging.agentalog.com/api/briefings/:slug",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/briefings/subscribe",
      "auth": "none",
      "summary": "Requests email confirmation for the weekly briefing list.",
      "grupo": "Briefings",
      "desc": "Alias of `/api/boletim/assinar`. Accepts JSON or an HTML form. Only email confirmation activates the subscription or changes its topics and language. An empty topic list selects all topics. Confirmation expires after 48 hours. Five requests per network per hour; address limits return the same 202 response. Updates include one-click unsubscribe. `GET /api/boletim/config` lists available topics and availability.",
      "corpo": {
        "email": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "Email address, up to 254 characters."
        },
        "topics": {
          "tipo": "string[]",
          "desc": "Topic slugs from `/api/briefings`, up to 40. Empty selects all."
        },
        "canais": {
          "tipo": "string[]",
          "desc": "noticias and/or novidades. Defaults to news only."
        },
        "lang": {
          "tipo": "string",
          "desc": "Language of the emails.",
          "valores": [
            "en",
            "pt"
          ],
          "padrao": "en"
        },
        "website": {
          "tipo": "string",
          "desc": "Leave empty. Anything here is treated as a bot and nothing is stored."
        }
      },
      "body": {
        "email": "you@company.com",
        "topics": [
          "rag",
          "inference"
        ],
        "lang": "en"
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Request accepted."
        },
        "status": {
          "tipo": "string",
          "desc": "`on_list`."
        },
        "message": {
          "tipo": "string",
          "desc": "What happens next, for a person."
        }
      },
      "erros": {
        "400": "Invalid email, body or topic.",
        "429": "Network request limit. Respect Retry-After.",
        "503": "Newsletter or email transport unavailable."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/briefings/subscribe -H 'content-type: application/json' -d '{\"email\":\"you@company.com\",\"topics\":[\"rag\"]}'",
      "returns": "{ ok, status, message }",
      "url": "https://staging.agentalog.com/api/briefings/subscribe",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "POST",
      "path": "/api/admin/briefings",
      "auth": "token",
      "grupo": "Operation",
      "summary": "The Briefings publisher delivers one document: the index or a topic.",
      "desc": "`BRIEFINGS_TOKEN` only (the publisher's credential; it opens nothing else). The document is checked against the key it will live under — shape, sizes, addresses — before it is stored. Idempotent.",
      "corpo": {
        "chave": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "`briefings/v1/indice.json` or `briefings/v1/topicos/<slug>.json`."
        },
        "doc": {
          "tipo": "object",
          "obrigatorio": true,
          "desc": "The document, `versao: 1`, up to 2 MB."
        }
      },
      "body": {
        "chave": "briefings/v1/topicos/rag.json",
        "doc": {
          "versao": 1,
          "slug": "rag"
        }
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Stored."
        },
        "chave": {
          "tipo": "string",
          "desc": "Where it was stored."
        },
        "indice": {
          "tipo": "bool",
          "desc": "`true` when the document is the index."
        }
      },
      "erros": {
        "400": "Invalid JSON or document.",
        "401": "BRIEFINGS_TOKEN required.",
        "413": "Body over 2 MB.",
        "503": "App files are not configured."
      },
      "exemplo": "curl -s -XPOST $ORIGIN/api/admin/briefings -H \"Authorization: Bearer $BRIEFINGS_TOKEN\" -H \"content-type: application/json\" -d @topic.json",
      "returns": "{ ok, chave, indice }",
      "url": "https://staging.agentalog.com/api/admin/briefings",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "PUT",
      "path": "/api/admin/briefings/img/:arquivo",
      "auth": "token",
      "grupo": "Operation",
      "summary": "The Briefings publisher delivers one preview image.",
      "desc": "`BRIEFINGS_TOKEN` only. WebP up to 512 KB, checked by its bytes; the name is the content's hash. Idempotent.",
      "params": {
        "arquivo": {
          "tipo": "string",
          "desc": "`<32 hex>.webp`.",
          "exemplo": "25738326cb17586e5c84da2734ccc65c.webp"
        }
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Stored."
        },
        "arquivo": {
          "tipo": "string",
          "desc": "The file name, served at `/briefings/img/<arquivo>`."
        }
      },
      "erros": {
        "401": "BRIEFINGS_TOKEN required.",
        "404": "Not an image address: the name is `<32 hex>.webp`.",
        "413": "The body exceeds 512 KB.",
        "422": "Invalid WebP bytes or content hash.",
        "503": "App files are not configured."
      },
      "exemplo": "curl -s -XPUT $ORIGIN/api/admin/briefings/img/$FILE -H \"Authorization: Bearer $BRIEFINGS_TOKEN\" --data-binary @$FILE",
      "returns": "{ ok, arquivo }",
      "url": "https://staging.agentalog.com/api/admin/briefings/img/:arquivo",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "POST",
      "path": "/api/admin/briefings/exportacao",
      "auth": "token",
      "grupo": "Operation",
      "summary": "The desktop delivers the export of the public bookmark folders.",
      "desc": "`BRIEFINGS_EXPORT_TOKEN` only (it opens nothing else). JSON up to 8 MB, checked before it is stored: `versao: 1`, the topics (slug → post ids) and the items (post, author, date, text, up to eight web links). Send it gzip-compressed: a request carries at most 2 MiB. Kept in the app's files, outside every public route; the publisher on c3 fetches it when it changes.",
      "headers": {
        "Content-Encoding": {
          "tipo": "string",
          "desc": "`gzip` when the body is compressed; the 8 MB cap applies after it."
        }
      },
      "corpo": {
        "versao": {
          "tipo": "int",
          "obrigatorio": true,
          "desc": "Format version; only `1` is accepted."
        },
        "gerado_em": {
          "tipo": "string",
          "obrigatorio": true,
          "desc": "When the export was made (ISO 8601)."
        },
        "topicos": {
          "tipo": "object",
          "obrigatorio": true,
          "desc": "Topic slug → post ids, newest first."
        },
        "itens": {
          "tipo": "object",
          "obrigatorio": true,
          "desc": "Post id → the post: author, date, text, quoted post, links."
        }
      },
      "body": {
        "versao": 1,
        "gerado_em": "2026-09-28T08:00:00Z",
        "topicos": {
          "rag": [
            "1"
          ]
        },
        "itens": {
          "1": {
            "id": "1"
          }
        }
      },
      "retorno": {
        "ok": {
          "tipo": "bool",
          "desc": "Stored."
        },
        "topicos": {
          "tipo": "int",
          "desc": "Topics in the export."
        },
        "itens": {
          "tipo": "int",
          "desc": "Items in the export."
        },
        "etag": {
          "tipo": "string",
          "desc": "The content's hash, as the publisher sees it in `ETag`."
        }
      },
      "erros": {
        "400": "Invalid gzip, JSON or export.",
        "401": "BRIEFINGS_EXPORT_TOKEN required.",
        "413": "Over 2 MiB on the wire or 8 MB of JSON.",
        "503": "App files are not configured."
      },
      "exemplo": "gzip -c exportacao.json | curl -s -XPOST $ORIGIN/api/admin/briefings/exportacao -H \"Authorization: Bearer $BRIEFINGS_EXPORT_TOKEN\" -H \"content-type: application/json\" -H \"content-encoding: gzip\" --data-binary @-",
      "returns": "{ ok, topicos, itens, etag }",
      "url": "https://staging.agentalog.com/api/admin/briefings/exportacao",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "method": "GET",
      "path": "/api/admin/briefings/exportacao",
      "auth": "token",
      "grupo": "Operation",
      "summary": "The publisher on c3 fetches the latest export, only when it changed.",
      "desc": "`BRIEFINGS_TOKEN` only. `ETag` is the content's hash: with `If-None-Match` equal to it, 304 and no body.",
      "headers": {
        "If-None-Match": {
          "tipo": "string",
          "desc": "The `ETag` of the export already held; 304 when unchanged."
        }
      },
      "retorno": {
        "_texto": "application/json — the export exactly as the desktop delivered it."
      },
      "erros": {
        "401": "BRIEFINGS_TOKEN required.",
        "404": "No export delivered yet."
      },
      "exemplo": "curl -s $ORIGIN/api/admin/briefings/exportacao -H \"Authorization: Bearer $BRIEFINGS_TOKEN\" -H 'If-None-Match: \"…\"'",
      "returns": "application/json — the export exactly as the desktop delivered it.",
      "url": "https://staging.agentalog.com/api/admin/briefings/exportacao",
      "auth_detail": "Operator token `ADMIN_TOKEN` or `METRICS_TOKEN` as Bearer. The load routes also accept the enricher's credential; automatic moderation uses its own `MODERATION_TOKEN` and the Briefings publisher its own `BRIEFINGS_TOKEN` — see each endpoint."
    },
    {
      "path": "/api/acesso",
      "auth": "none",
      "grupo": "API access",
      "retorno": "ApiAccess",
      "method": "GET",
      "summary": "Discover the monthly data package or inspect a private purchase.",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        }
      },
      "erros": {
        "400": "Invalid pass.",
        "404": "Unknown purchase or wrong owner.",
        "503": "Purchases disabled."
      },
      "exemplo": "curl -s $ORIGIN/api/acesso",
      "desc": "Catalog discovery and ordinary browsing are free. GPTBot, ClaudeBot, CCBot, Meta-ExternalAgent, Amazonbot, AhrefsBot and MJ12bot share a daily allowance of 1,000 reads per crawler family; over it the answer is 402 with the MAT reads package: US$ 1 for 1,000 reads for 30 days, with no automatic renewal. Buy it at POST /api/acesso and send its pass in X-API-Pass. The MAT allowance is separate from the company, address and procurement indexes.",
      "returns": "{ offer{id,price_usd,credits,days,auto_renew,unit,products,purchase,method,status,header,payment_methods,prepaid_credit,instructions,generate_pass,client,guide,workflow,evaluation}, enabled?, id?, status?, granted_credits?, expires_at?, receipt?, via?, message? }",
      "url": "https://staging.agentalog.com/api/acesso",
      "auth_detail": "Public, no credential."
    },
    {
      "path": "/api/acesso",
      "auth": "none",
      "grupo": "API access",
      "retorno": "ApiAccess",
      "method": "POST",
      "summary": "Buy 1000 basic data reads for US$1, valid for 30 days.",
      "preco_usd": 1,
      "desc": "Catalog discovery and ordinary browsing are free. GPTBot, ClaudeBot, CCBot, Meta-ExternalAgent, Amazonbot, AhrefsBot and MJ12bot share a daily allowance of 1,000 reads per crawler family; over it the answer is 402 with the MAT reads package: US$ 1 for 1,000 reads for 30 days, with no automatic renewal. Buy it at POST /api/acesso and send its pass in X-API-Pass. The MAT allowance is separate from the company, address and procurement indexes.",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying.",
          "obrigatorio": true
        },
        "X-Credito": {
          "tipo": "string",
          "desc": "Existing prepaid credit token; alternative to x402."
        },
        "Authorization": {
          "tipo": "string",
          "desc": "Bearer cred_… alternative to X-Credito."
        },
        "X-PAYMENT": {
          "tipo": "string",
          "desc": "Signed x402 authorization from the 402 quote, maximum 16 KiB."
        },
        "PAYMENT-SIGNATURE": {
          "tipo": "string",
          "desc": "Alternative name for X-PAYMENT."
        },
        "X-API-Transaction": {
          "tipo": "string",
          "desc": "Confirmed Base transaction hash for reconciliation with the original pass and signed payment. Never creates another charge."
        }
      },
      "erros": {
        "400": "Missing or invalid pass/payment.",
        "401": "Invalid prepaid credit.",
        "402": "Payment required: x402 accepts[] and prepaid-credit instructions.",
        "409": "Payment pending; retain the same pass and do not pay again.",
        "429": "Purchase attempt limit; respect Retry-After.",
        "503": "Payment unavailable or pending reconciliation."
      },
      "exemplo": "curl -s -X POST \"$ORIGIN/api/acesso\" -H \"X-API-Pass: $API_PASS\"",
      "returns": "{ offer{id,price_usd,credits,days,auto_renew,unit,products,purchase,method,status,header,payment_methods,prepaid_credit,instructions,generate_pass,client,guide,workflow,evaluation}, enabled?, id?, status?, granted_credits?, expires_at?, receipt?, via?, message? }",
      "url": "https://staging.agentalog.com/api/acesso",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/coleta/readme/:arquivo",
      "grupo": "Catalog",
      "auth": "none",
      "summary": "Read a collected README as Markdown by its published object path.",
      "desc": "Same MAT read allowance and pass. Prefer /api/listings/:id/readme (also available through MCP) for metadata and the historical R2 fallback. This raw route only serves objects already present on the catalog origin.",
      "params": {
        "arquivo": {
          "tipo": "string",
          "desc": "Published relative README path, e.g. owner/repository.md.",
          "obrigatorio": true
        }
      },
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying."
        },
        "Idempotency-Key": {
          "tipo": "string",
          "desc": "Optional retry key, up to 80 ASCII characters; same read for five minutes."
        }
      },
      "retorno": {
        "_texto": "README Markdown (text/markdown); a successful basic read is at most 1 MiB."
      },
      "erros": {
        "401": "Invalid pass.",
        "402": "Read allowance or credit exhausted.",
        "404": "README absent.",
        "413": "Read too large.",
        "503": "Origin unavailable."
      },
      "exemplo": "curl -s \"$ORIGIN/coleta/readme/owner/repository.md\" -H \"X-API-Pass: $API_PASS\"",
      "returns": "README Markdown (text/markdown); a successful basic read is at most 1 MiB.",
      "url": "https://staging.agentalog.com/coleta/readme/:arquivo",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/uso",
      "grupo": "API access",
      "auth": "none",
      "summary": "Read the remaining MAT balance without consuming credit.",
      "retorno": "MatUsage",
      "headers": {
        "X-API-Pass": {
          "tipo": "string",
          "desc": "MAT-only private pass: mat_<32 random hex>_<64 random hex>. Generate and save before buying.",
          "obrigatorio": true
        }
      },
      "erros": {
        "401": "Missing or invalid pass.",
        "402": "Purchase pending or expired.",
        "503": "Origin unavailable."
      },
      "exemplo": "curl -s \"$ORIGIN/api/uso\" -H \"X-API-Pass: $API_PASS\"",
      "returns": "{ id, credits, used, remaining, expires_at, active }",
      "url": "https://staging.agentalog.com/api/uso",
      "auth_detail": "Public, no credential."
    },
    {
      "method": "GET",
      "path": "/api/pricing",
      "auth": "none",
      "grupo": "Discovery",
      "summary": "Current prices and free allowances.",
      "retorno": {
        "product": {
          "tipo": "string",
          "desc": "Product name."
        },
        "quota": {
          "tipo": "PaymentQuota",
          "desc": "Public allowances and current list prices; not personal usage."
        },
        "pricing": {
          "tipo": "string",
          "desc": "Absolute URL of the current price list."
        },
        "billing": {
          "tipo": "string",
          "desc": "Absolute URL of payment discovery or the existing billing summary."
        },
        "api_index": {
          "tipo": "string",
          "desc": "Absolute URL of the API catalog."
        }
      },
      "erros": {
        "405": "Use GET or HEAD."
      },
      "exemplo": "curl -s $ORIGIN/api/pricing",
      "returns": "{ product, quota{free,paid,how_to_pay,live,free_now?,charged_now?,trial?}, pricing, billing, api_index }",
      "url": "https://staging.agentalog.com/api/pricing",
      "auth_detail": "Public, no credential."
    }
  ],
  "quota": {
    "free": [
      {
        "o_que": "ordinary catalog browsing and discovery",
        "limite": "identified crawlers: 1,000 reads/day per family",
        "janela": null
      },
      {
        "o_que": "like, comment and hop with a guest token",
        "limite": "no quota",
        "janela": null
      },
      {
        "o_que": "register with an e-mail account",
        "limite": "1 per day, max. 3 in the queue",
        "janela": null
      },
      {
        "o_que": "watch remote MCP servers and skills with an account or an agent wallet (mmw_… or prepaid credit cred_…): daily check, changes by e-mail (account) or GET /api/me/vigia/avisos; /api/me/vigia",
        "limite": "3 tools per owner",
        "janela": null
      }
    ],
    "paid": [
      {
        "o_que": "1,000 MAT catalog reads for 30 days; separate balance; GET/POST /api/acesso",
        "price_usd": 1
      },
      {
        "o_que": "register as an agent (with or without a guest token)",
        "price_usd": 0.1
      },
      {
        "o_que": "watch 1 more MCP server for 30 days, no auto-renewal; POST /api/me/vigia",
        "price_usd": 0.1
      },
      {
        "o_que": "Team watch: 50 MCP servers for 30 days, no auto-renewal; POST /api/plans/equipe",
        "price_usd": 2.49
      },
      {
        "o_que": "Business watch: 500 MCP servers for 30 days, no auto-renewal; POST /api/plans/empresa",
        "price_usd": 4.99
      },
      {
        "o_que": "Project seal pass: selected checks for one MCP listing for 30 days, no automatic renewal",
        "price_usd": 10
      },
      {
        "o_que": "Protection pass: 10 protected MCP servers for 30 days, no automatic renewal",
        "price_usd": 1
      },
      {
        "o_que": "One additional protected MCP server for 30 days",
        "price_usd": 0.1
      },
      {
        "o_que": "GET /api/x402/check — Checks an MCP server address for an agent, paid per call: what we measured, the catalog listings and the domain facts.",
        "price_usd": 0.01
      }
    ],
    "how_to_pay": "Catalog discovery and ordinary browsing are free. GPTBot, ClaudeBot, CCBot, Meta-ExternalAgent, Amazonbot, AhrefsBot and MJ12bot share a daily allowance of 1,000 reads per crawler family; over it the answer is 402 with the MAT reads package: US$ 1 for 1,000 reads for 30 days, with no automatic renewal. Buy it at POST /api/acesso and send its pass in X-API-Pass. The MAT allowance is separate from the company, address and procurement indexes. A submission without an account costs US$ 0.10; the daily submission limit still applies. An agent receives 402 with `accepts[]` before payment. Pay through x402 or prepaid credit, then repeat the same request.",
    "live": "https://staging.agentalog.com/api/billing"
  },
  "mcp": {
    "endpoint": "https://staging.agentalog.com/mcp",
    "transport": "streamable-http",
    "tools": 49,
    "note": "Plugs straight into the MCP client; nothing to install. Tools = the operations below."
  },
  "quickstart": [
    "GET https://staging.agentalog.com/api/listings — live mosaic (each item carries the destination URL)",
    "GET https://staging.agentalog.com/v0.1/servers — MCP subregistry (official spec)",
    "POST https://staging.agentalog.com/api/guest — mr_… token for like/comment",
    "POST https://staging.agentalog.com/api/listings with a session (human, free) or as an agent, with or without guest ($0.10 through x402 or prepaid credit)",
    "GET https://staging.agentalog.com/api/listings/ID/status — poll the review (no credential; the 201 carries it as status_api)",
    "POST https://staging.agentalog.com/mcp — the same operations as MCP tools, nothing to install"
  ]
}