Catálogo das APIs internas dos serviços jetblip (jet-scan, jet-ask, labs). Atualmente Phase 1 — directório estático para referência. Phase 2 (planeada): self-service API keys + signup + trial credits.
← infra portal · mockups · icons library
📷 jet-scan
port 8093
https://my.jetblip.com/blip-scan/
Wallet de cartões de fidelização, scan de códigos de barras/QR, sistema de preferências por pessoa, registo de faturas. Backend Flask + SQLite. Reutilizável: produtos, lojas, pessoas, cartões.
POST/blip-scan/api/scanpublic*
Regista um scan. Auto-classifica em kind (barcode/qr/fatura/etc). Para barcodes, auto-seed prefs dont_know por pessoa. Auto-attach loja prior se mesmo código já tenha sido scaneado.
Body
{ "value": "1850380231797", "format": "EAN_13", "note"?: "..." }
Response
{ "ok": true, "id": 42, "value": "...", "format": "...", "kind": "barcode", "session_id": "...", "store_id": null }
GET/blip-scan/api/cardspublic*
Lista todos os cartões de fidelização (joined com store + person). Optional ?store_id=.
Response
{ "ok": true, "cards": [{ "id", "store_id", "store_name", "person_id", "person_name", "card_value", "card_format", "label", "created_at" }] }
GET/blip-scan/api/storespublic*
Lista todas as lojas. Cada uma: id, name, country.
POST/blip-scan/api/storespublic*
Cria nova loja. Case-insensitive dedup: se já existir com esse nome, devolve o ID existente.
Body
{ "name": "Auchan PT" }
Response
{ "ok": true, "store_id": 7, "name": "Auchan PT" }
GET/blip-scan/api/stores/<id>/cardspublic*
Cartões de uma loja específica.
POST/blip-scan/api/stores/<id>/cardspublic*
Cria um novo cartão de fidelização para uma loja. Cria pessoa nova se person_name não existir.
Body
{ "card_value": "...", "card_format"?: "EAN_13", "label"?: "...", "person_id"?: 1, "person_name"?: "Jeremy" }
POST/blip-scan/api/cards/<id>/deletepublic*
Soft delete de um cartão (marca deleted_at).
POST/blip-scan/api/scans/<id>/storepublic*
Atribui (ou remove) uma loja a um scan.
Body
{ "store_id": 7 } ou { "store_id": null }
GET/blip-scan/api/preferences/<code>public*
Preferências (sentiments por pessoa) para um dado código de barras.
POST/blip-scan/api/preferences/setpublic*
Atualiza sentiment de uma pessoa para um código. Sentiments: dont_know · dislike · neutral · like · favorite · style_favorite · worth_heartburn.
Body
{ "code": "1850380231797", "person_name": "Jeremy", "sentiment": "favorite" }
GET/blip-scan/api/pricespublic*
Lista preços registados por loja/produto.
POST/blip-scan/api/pricespublic*
Regista um preço.
POST/blip-scan/api/products/manualpublic*
Adiciona um produto manual (sem código de barras).
GET/blip-scan/api/products/searchpublic*
Pesquisa de produtos. Query param ?q=.
GET/blip-scan/api/products/<code>/enrichpublic*
Enriquece um produto via lookup externo (Open Food Facts).
GET/blip-scan/api/session/<sid>public*
Detalhes de uma sessão de scan.
POST/blip-scan/api/session/endpublic*
Termina a sessão atual de scan.
GET/blip-scan/healthzpublic
Health check. Retorna 200 OK + JSON simples.
* public = endpoint público hoje (decorator @login_required é no-op). Phase 2 vai introduzir auth real via API keys.
❓ jet-ask
port 8082
https://my.jetblip.com/blip-ask/
Sistema de captura de pedidos/bugs/ideias. Queue priorizada, decisões, follow-ups. Backend Flask + SQLite. APIs em /api/jet-ask/*.
POST/api/jet-ask/logpublic*
Regista um novo pedido/bug/ideia. Aceita texto, prioridade, anexos, contexto da página de origem.
Body
{ "text": "...", "priority"?: -2..5, "source"?: "ask-quick|ask-full|bug", "page_url"?: "..." }
GET/api/jet-ask/pendingpublic*
Lista pedidos pendentes na queue.
GET/api/jet-ask/decisions/readypublic*
Decisões prontas a serem feitas.
POST/api/jet-ask/<id>/claimpublic*
Reclama um todo (lock até completar/release).
POST/api/jet-ask/<id>/releasepublic*
Liberta um todo previamente claimed.
POST/api/jet-ask/<id>/draft-responsepublic*
Gera draft de resposta para um todo (LLM-assisted).
POST/api/jet-ask/<id>/updatepublic*
Atualiza um todo (texto, prioridade, status).
GET/api/jet-ask/tips/randompublic
Tip aleatório (frontend ticker).
GET/jet-ask/healthzpublic
Health check.
Os endpoints /jet-ask/<id>/... (sem prefix /api) são form-based e retornam HTML. Os /api/jet-ask/* são JSON.
🔬 blip-research
port 5050
https://my.jetblip.com/blip-research/
Price tracker e histórico de pesquisas. Operador escreve pedidos via dashboard; Claude lê via /api/state no início de cada sessão de pesquisa. Backend Flask + SQLite. ⚠ Cloudflare Bot Fight Mode activo — acesso externo requer User-Agent de browser real; acesso interno via SSH: curl -s http://127.0.0.1:5050/blip-research/api/state.
GET/blip-research/api/statepublic (CF-protected)
Snapshot JSON completo do estado actual. Usado pelo dashboard (auto-refresh 30s) e por Claude no início de cada sessão de pesquisa. Inclui contagens, 20 observações recentes, 10 sessões, 30 notas, 10 descidas de preço, itens esgotados.
Response
{ "counts": { "items": N, "obs": N, "sessions": N, "sources": N, "notes": N }, "recent": [{ "br_id", "item_id", "item_name", "source", "url", "price_fmt", "currency", "availability", "observed_at", "session_slug" }], "sessions": [{ "slug", "title", "context", "item_count", "obs_count", "last_obs" }], "notes": [{ "id", "content", "session_slug", "created_at" }], "drops": [...], "oos": [...], "ts": "ISO8601" }
Fetch interno (SSH)
ssh rpi "curl -s http://127.0.0.1:5050/blip-research/api/state"
Fetch externo (com UA)
curl -s -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" https://my.jetblip.com/blip-research/api/state
POST/blip-research/api/observepublic (CF-protected)
Regista uma observação de preço/disponibilidade. Cria item se não existir (item_id ou item_name obrigatório). Cria/actualiza sessão se session_slug for fornecido. Preço aceita formato europeu (vírgula como decimal).
Body
{ "item_id"?: 1, "item_name"?: "Crucial DDR5 8GB", "item_category"?: "ram", "item_spec"?: "DDR5-5600 SODIMM", "source": "Amazon.fr", "condition"?: "new|business|private|service", "price"?: "161,59", "currency"?: "EUR", "url"?: "https://...", "availability"?: "in_stock|oos|unknown", "notes"?: "...", "session_slug"?: "thierry-laptop-fw", "session_title"?: "...", "session_context"?: "..." }
Response
{ "ok": true, "obs_id": 42, "item_id": 7, "br_id": "BR-260524-13" }
Nota
Requer User-Agent de browser (CF Bot Fight Mode). Usar SSH + curl interno para acesso programático.
POST/blip-research/api/notepublic (CF-protected)
Operador submete nota/pedido de pesquisa. Claude lê via /api/state ao início de cada sessão. Histórico permanente.
Body
{ "content": "pesquisa RAM DDR5 SO-DIMM 16GB para Thierry", "session_slug"?: "thierry-laptop-fw" }
Response
{ "id": 5, "created_at": "2026-05-24T09:50:00Z" } · HTTP 201
GET/blip-research/api/notespublic (CF-protected)
Lista de notas do operador. Suporta ?limit=30 e ?session_slug=thierry-laptop-fw para filtrar por sessão.
Response
{ "notes": [{ "id", "content", "session_slug", "created_at" }] }
🧪 labs
multi-port (gunicorn)
https://my.jetblip.com/labs/
Host aggregator: roteia /blip-scan/* → jet-scan, /blip-ask/* → jet-ask. nginx config em labs/deploy/nginx-b-ab.conf. Variantes A/B/C/D/E/F/G/H/I/J/K/L via prefix /b/ /c/ /d/ ... /l/ com X-UI-Version header.
GET/admin/operator
Dashboard admin (apenas operador com cookie).
GET/labs/healthzpublic
Health check do labs aggregator.
Lista parcial — labs tem rotas adicionais para A/B testing dashboard, métricas, etc. Ver labs/app.py para enumeração completa.