vek1-api — integrações externas
Integrações externas
vek1-api é o único lugar onde APIs externas vivem. Regra travada: frontend (vek1) nunca chama LLM/embedding/email/payment direto — sempre via vek1-api. Isolamento de credenciais.
| Integração | Onde | Para quê |
|---|---|---|
| DeepSeek | SDK openai com base_url=https://api.deepseek.com. Modelo deepseek-chat |
LLM principal — /chat (function calling), /extract-lead (JSON mode) |
| Ollama bge-m3 | services/embeddings.py → httpx POST ${OLLAMA_BASE_URL}/api/embed |
Embeddings 1024 dim — vetorização de documents (catálogo + KB) + leads (profile_embedding) |
| Resend | services/email_service.py |
Transactional email (reset password) — PR #21 |
| AbacatePay (inbound) | routers/orders.py:webhook_router |
Recebe webhook payment.paid quando cliente paga PIX, atualiza order para confirmed |
| AbacatePay (outbound) | lib/abacate-pay.ts no vek1 (não no vek1-api atualmente — vek1 chama direto via API key da store) |
Cria charge PIX no checkout. Resposta com BR Code + payment_link_url salva via POST /internal/orders/{id}/checkout-state |
| ERP customer-owned (outbound) | services/stock_service.py outbound HMAC POST |
Notifica ERP de decrement/restore de estoque em order events |
| ERP customer-owned (inbound) | routers/stock.py webhook POST /webhooks/stock-sync/{store_id} |
ERP envia sync de inventário; valida HMAC com inbound_secret da store |
| Evolution API | NÃO direto no vek1-api — vek1 (Next) recebe webhooks; vek1-api só fornece endpoints internos pro lookup (/webhooks/agents/by-evolution-instance/{instance_id}) |
Loose coupling — vek1-api não conhece Evolution |
| Postgres | services/db.py psycopg2 pool sync |
DB primário |
Envs
# LLM
DEEPSEEK_API_KEY=sk-...
OPENAI_API_KEY= # vazio — fallback se DEEPSEEK_API_KEY ausente
OPENAI_BASE_URL=https://api.deepseek.com
# Ollama
OLLAMA_BASE_URL=http://vault-ollama:11434
EMBEDDING_MODEL=bge-m3
# Postgres (interno container)
DATABASE_URL=postgresql://vek1:${POSTGRES_PASSWORD}@postgres:5432/vek1
POSTGRES_PASSWORD=...
# Email
RESEND_API_KEY=re_...
RESEND_FROM_EMAIL=noreply@vek1.app
# Tokens internos (3 escopos)
INTERNAL_API_TOKEN=...
INTERNAL_AUTH_TOKEN=...
INTERNAL_WEBHOOK_TOKEN=...
# Misc
ENVIRONMENT=production
DEBUG=False
LOG_LEVEL=INFO
MAX_FILE_SIZE_MB=10
ALLOWED_EXTENSIONS=pdf,csv
HOST=0.0.0.0
PORT=8000
Networks (docker-compose)
vek1-net— interno (postgres + vek1-api)vault-site_default— external, pra alcançarvault-ollama(container de Ollama compartilhado com vault site)
Outbound HTTP
Todo outbound usa httpx com timeout default 30s. Não tem retry global; cada serviço decide:
- Ollama: 1 retry single (model load cold start tolerância)
- DeepSeek: SDK openai já retry built-in (3x exponential)
- Resend: 1 retry — se falhar, 502 pro caller (Better Auth re-emite no próximo reset)
- ERP outbound (stock): sem retry — opt-in pelo customer (variável de qualidade)
Inbound webhooks
| Endpoint | Validação |
|---|---|
/webhooks/abacate-pay |
X-Webhook-Token + HMAC signature com abacate_pay_webhook_secret da store |
/webhooks/stock-sync/{store_id} |
HMAC SHA256 com inbound_secret da store (sem X-Webhook-Token — ERP customer-owned não tem nosso token) |
/internal/email/send-reset-password |
X-Webhook-Token (origem: Better Auth no vek1) |
DeepSeek custos (referência pricing spec)
- Input: ~$0.27 / 1M tokens
- Output: ~$1.10 / 1M tokens
- Mix médio (~70% input, 30% output): ~$0.52 / 1M tokens efetivos
- Em BRL (~5.50 USD): ~R$ 2.86 / 1M tokens. Conservador pro pricing: R$ 1.15 / 1M (média otimista de cache hit, prompt caching DeepSeek).
Ollama (self-hosted)
- Container
vault-ollamareaproveitado da infra Vault - Modelo
bge-m3pinned (1024 dim, multilingual com força em PT-BR) - Zero custo recorrente (CPU do VPS Hermes)
- Cold start ~10s, subsequente 0.4–1.7s
- Sem rate limit interno (cuidado em bursts — pool de conexões httpx default 100)
Resend (PR #21)
- API:
https://api.resend.com/emails - Template HTML inline em
services/email_service.py(PT-BR, vek1 branding) - Falha → 502 pro Better Auth; user vê toast "tente novamente"
- Dev: pode setar
RESEND_API_KEYvazio + flag debug pra log do email sem enviar
AbacatePay
- API:
https://api.abacatepay.com - Token por store (
store_payment_settings.abacate_pay_api_key) — não global - Webhook: vek1 expõe
/api/webhooks/abacate-pay, valida signature HMAC comabacate_pay_webhook_secretda store, relay comX-Webhook-Tokenpro vek1-api confirmar - Dev mode toggle por store (
abacate_pay_dev_mode) — sandbox vs prod
ERP/PDV bidirectional sync (PR #5/#62)
Outbound (vek1 → ERP)
- Triggered em order transitions (
confirmed,cancelled) - POST pro
outbound_urlcom HMAC SHA256 headerX-Vek1-Signaturederivado deoutbound_secret - Payload:
{event, order_id, product_id, delta, reason, store_id, timestamp} - Sem retry — best-effort
Inbound (ERP → vek1)
- POST
/webhooks/stock-sync/{store_id} - HMAC validation com
inbound_secretda store - Payload aceito: array de
{product_integration_id|product_id, stock, ...} - Update
products.stock+ insertstock_movementscomreason='inbound_sync' - Idempotente via
external_idno payload (se cliente enviar)