Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add APIPASS-Integrations/apipass-headless --skill apipass-gotchasgit clone --depth 1 https://github.com/APIPASS-Integrations/apipass-headlessWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/apipass-integrations/apipass-headless/apipass-gotchas)<a href="https://agentmods.dev/skills/apipass-integrations/apipass-headless/apipass-gotchas"><img src="https://agentmods.dev/badge/skills/apipass-integrations/apipass-headless/apipass-gotchas/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/apipass-integrations/apipass-headless/apipass-gotchas"><img src="https://agentmods.dev/badge/skills/apipass-integrations/apipass-headless/apipass-gotchas.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00054 | $0.06917 |
| Opus 5 | $0.00027 | $0.03459 |
| Sonnet 5 | $0.00011 | $0.01383 |
| Haiku 4.5 | $0.00005 | $0.00692 |
Grade A, and why
apipass-gotchas scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 10d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 138 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Gotchas da APIPASS
Construcao de fluxo
| Sintoma | Causa provavel | Correcao |
|---|---|---|
| "Validacao do fluxo falhou — nada foi salvo" | id/type vazios, ids duplicados, ou lastGeneratedStepId incorreto |
Leia a lista de erros do retorno e corrija; ajuste os contadores (= ultimo id gerado + 1; o stop a999 e sentinela e nao conta) |
| JSON Schema da trigger REST nao aparece na UI | Usou requestBodySchema (campo invalido) ou passou o schema como objeto JSON |
O campo correto e jsonSchema com valor como string serializada (com \r\n). Exemplo: "jsonSchema": "{\r\n \"type\": \"object\"...\r\n}\r\n". Nunca use requestBodySchema. |
JSON Schema de response no StopV2Step nao aparece no Swagger gerado (generate_oas_documentation), mesmo com jsonSchema presente no item de responses[] |
Colocou jsonSchema solto como irmao de responseData/groups/description (fora do objeto oas) -- save_flow_development/publish_flow aceitam sem erro, mas o gerador de OAS ignora silenciosamente esse campo |
O schema de response so e lido dentro do envelope oas: "oas": { "mediaType": "application/json", "headers": [], "jsonSchema": "<string>" } (shape completo em /apipass-integrations:apipass-patterns, secao "Documentacao OpenAPI (OAS)"). Confirme rodando generate_oas_documentation apos publicar e conferindo que responses.<status>.content vem preenchido |
| Switch apos HTTP roteia errado (vai para sucesso mesmo em erro da API) | Usou INPUT_IS_NOT_NULL no body como proxy de sucesso |
Use $.aN.headers.responseStatusCode com NUMBER_DOES_NOT_MATCH "200" para detectar erro; sucesso vai para o default. |
| Passo nao executa / config "some" no save | Campos no nivel errado. Regra: acao fixed (http, triggers, stop, utility.*) → campos no TOPO do step; connector catalog (.service.actions.Action) → campos em inputData. mappingAttributes fica {} nos dois |
fixed: copie o stepSkeleton de list_actions. catalog: monte inputData pelo schema de get_action_struct |
| Interpolacao nao resolve (vem literal) | Sintaxe errada ${...} |
Use mustache {{$.<id>}} — ex. {{$.trigger.body}}, {{$.a0}} |
save_flow_development "retornou vazio" |
Sucesso NAO traz payload | Nao e erro; confirme relendo com get_flow_development |
"Method and URL are required, check your flow configuration." no step de acao (MEMORY_STORE_SET/GET, PROJECT_STORE_SET/GET, LOGGER etc.) — mesmo com actionId/coreRouteType corretos no step |
Faltou coreRouteType no objeto de link dentro do array nextSteps do step anterior. O engine usa esse campo para resolver a URL do microsservico — sem ele nao roteie e lanca o erro. Causa silenciosa: get_flow_development e save/publish aceitam sem reclamar, mas a execucao falha |
Em cada item de nextSteps que aponta para um .service.actions.Action, inclua "coreRouteType" com o mesmo valor do step de destino. Ex: {"id":"a0","type":".service.actions.Action","coreRouteType":"MEMORY_STORE_GET","sourceUUID":"...","targetUUID":"..."}. Vale para TODOS os acoes de catalogo. Leia um fluxo funcional com get_flow_development para confirmar o shape correto do link. |
Header de um step .service.http.HttpRequest (ex. Authorization) nunca chega no destino, sem erro em lugar nenhum |
Item de headers/params montado com {"key": "...", "value": "..."} em vez de {"label": "...", "value": "..."} |
O shape correto e SEMPRE label/value. key e aceito silenciosamente pelo save_flow_development e pela execucao, mas o header e descartado — confirme reabrindo o step na UI ou lendo get_flow_development |
Preencheu bearerToken/contentType (campos de nivel raiz do .service.http.HttpRequest, presentes no stepSkeleton) mas o header Authorization nao chega e o Content-Type real da chamada e sempre text/plain |
Esses dois campos existem no skeleton mas NAO sao aplicados de fato a requisicao pelo engine (confirmado com teste de eco via httpbin.org) | Nao use bearerToken/contentType para autenticacao/content-type — configure via headers: [{"label": "Content-Type", "value": "..."}, {"label": "Authorization", "value": "Bearer {{$.authorization.access_token}}"}] (ver /apipass-integrations:build-flow, secao "Step HTTP") |
| Acao exige credencial mas falha | authId vazio numa acao que autentica |
Defina o authId correto da conta |
| Nao sei os campos de uma acao | Tentou adivinhar | NUNCA invente — pesquise via /apipass-integrations:research-action |
login_necessario no meio de uma acao |
Sem token valido | Mostre a authorizeUrl ao usuario. NAO espere ele avisar que autorizou — faca poll voce mesmo em apipass_auth_status a cada poucos segundos ate authenticated: true (ou timeout de alguns minutos), depois refaca a acao original automaticamente |
| Operacao recusada pedindo confirm | Efeito colateral sem confirm: true |
Confirme com o usuario e reenvie com confirm: true |
Bearer token OAuth nao resolve num step HTTP generico (.service.http.HttpRequest) que ja tem authId/authProvider no topo |
Usou {{$.authorization.<authId>.access_token}} (com o id embutido no caminho) |
Use {{$.authorization.access_token}} (sem id) — o authId/authProvider do proprio step ja escopa qual autorizacao esta em uso; campos disponiveis via get_authorization_interpolation_fields(authId) |
publish_flow da HTTP 400 IER001: Cannot read properties of undefined (reading 'map') |
O step de stop (.StopV2Step, ex. a999) nao tem o array responses. O save_flow_development/create_version aceitam o stop sem responses, mas a publicacao mapeia responses para montar o contrato da API |
Adicione responses ao stop (ao menos a Default 200; ideal Default + Error 400). Copie o shape exato de um fluxo publicavel via get_flow_development (ver /apipass-integrations:apipass-patterns) |
run_test_flow executa OK mas {{$.trigger.body.*}} vem null (e o body de resposta do stop que dependa dele) |
Modo TEST nao popula o body do trigger como um POST HTTP real — vale para QUALQUER tipo de fluxo, nao so agentes | Nao e defeito do fluxo: o caminho funciona em requisicao real. Para validar a interpolacao do trigger, publique e chame o endpoint de verdade; use run_test_flow para validar wiring/passos com valores literais ou que nao dependam do shape do body do trigger |
run_test_flow "nao faz nada" — nenhuma execucao aparece em list_flow_execution_logs |
O run_test_flow roda a versao publicada no environment; sem create_version + publish_flow antes, nada executa. Alem disso a ferramenta retorna vazio (undefined), sem executionId |
Cicle a cada edicao: save_flow_development → create_version → publish_flow → run_test_flow; depois consulte list_flow_execution_logs (com startDate/endDate/page) para pegar o resultado |
Em modo TEST o payload chega em $.trigger (campos no topo), nao em $.trigger.body; webhook real as vezes usa $.trigger.body |
Diferenca de shape entre TEST e POST real | Coloque um NodeJS normalizador como 1o passo apos a trigger e leia tudo dele: `let t=$.trigger |
Uma edicao manual feita pelo usuario direto na UI (ex. ajustou um header/valor no canvas) desaparece depois do proximo save_flow_development que voce chamar |
save_flow_development reenvia o array de steps INTEIRO — nao e um patch/diff. Se voce montar o payload a partir de um get_flow_development antigo (lido antes do ajuste do usuario, ou de memoria da conversa), o save sobrescreve e apaga a mudanca manual sem aviso |
Antes de QUALQUER save_flow_development de edicao (mesmo que voce ja tenha lido o fluxo antes na mesma conversa), rode get_flow_development(flowId) de novo imediatamente antes de montar o payload, para partir do estado mais recente |
Step NodeJS (.utility.nodejs.NodeJSUtility) trava e expira em ~2min ("Execution timeout"), sem nenhum erro no save |
Codigo colocado em rawData em vez de code — rawData e o campo do .service.http.HttpRequest, mas e aceito silenciosamente no NodeJS tambem |
Use SEMPRE code para o JS do NodeJS. usedSteps nao precisa ser preenchido a mao — o engine deriva automaticamente das referencias $.aN dentro do code |
.StopV2Step devolve Content-Type: application/json mesmo com responseData.contentType: "text/html" setado (dashboard/HTML renderiza como texto bruto no navegador) |
responseData.contentType e ignorado pela resposta HTTP real — mesmo padrao do bearerToken/contentType do HTTP generico |
Adicione responseData.headers: [{"label": "Content-Type", "value": "text/html; charset=utf-8"}] — so isso reflete no header real. Ver /apipass-integrations:build-flow, secao "Step de fim" |
Filtro num dashboard/relatorio via <form method="GET"> nunca da match quando o valor tem espaco (ex. filtro de cliente/categoria some com "0 resultados" mesmo o dado existindo) |
{{$.trigger.queryParams.*}} preserva + literal em vez de decodificar como espaco — convencao de formulario GET codifica espaco como + na query string (?cliente=Contoso+Seguros), mas o RestTrigger nao desfaz isso |
Decodifique manualmente antes de comparar/filtrar: `(v |
Precisa proteger um RestTrigger publico mas o link parou de abrir direto no navegador apos configurar auth |
authProvider: "ENDPOINT" + authIds: ["<authId>"] no trigger exige header Authorization real — funciona pra chamada programatica, mas navegador nao anexa header numa navegacao simples (clique em link) |
Para link clicavel por humano (dashboard/relatorio), use protecao por query param (?key=...) checada no .StopV2Step via groups/TEXT_DOES_NOT_MATCH em vez de authIds[]. Pergunte ao usuario qual e o consumidor (humano vs. sistema) antes de escolher |
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 10d ago First seen · 138 lines · 54 tokens per session scan A 53cf41213100
apipass-gotchas is a skill published in the GitHub repository APIPASS-Integrations/apipass-headless (2 stars, last pushed 1mo ago), licensed Apache-2.0. It adds 54 tokens to every session and 6,917 once invoked, about $0.0003 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
debug-optimize-lcp
Guides debugging and optimizing Largest Contentful Paint (LCP) using Chrome DevTools MCP tools. Use this skill whenever the user asks about LCP performance, slow page loads, Core Web Vitals optimization, or wants to understand why their page's main content takes too long to appear. Also use when the user mentions…
systematic-debugging
Use when debugging a failing test, build error, or runtime issue that isn't immediately obvious. Guides a 4-phase root cause analysis instead of random fix attempts.
diagnose
Trace from a reproduced symptom to the source code that causes it. Pin the specific file and approximate line, rate confidence in the cause and clarity of the fix independently, and always propose a concrete fix.
repro-admin
Reproduce an EmDash admin UI bug. Attach a container, start the demo dev server, drive the admin with agent-browser using the dev-bypass session, and capture the reproduction as screenshots plus a replayable transcript.
log-error-digest
Analyze log files to troubleshoot errors, identify peak error periods, and produce error clustering, frequency statistics, and time distribution reports. Supports JSON, syslog, and Nginx formats with automatic detection. Use when a user uploads a .log file and asks to analyze errors, find patterns, debug issues, or…
byted-util-volcengine-detect-retry
An orchestration workflow for Volcengine Cloud Detect, a service that checks websites or network endpoints from test locations.