API Reference

REST API v2 — Bearer auth, idempotent, audit-logged. Base URL https://ws.espartan.net/api/external.

Auth

Authorization: Bearer nx_<your-key>

Idempotency

Idempotency-Key: <your-uuid>   # opcional, 7d TTL

Errors

{ "error": "code", "detail": "human-readable" }

Scopes

La bootstrap key del signup viene con todos los scopes. Mintea keys más estrechas con POST /api-keys.

me:readapi-keys:readapi-keys:writenumbers:readnumbers:writeai:readai:writekb:readkb:writecontacts:readcontacts:writecontacts:enrichmessages:readwhatsapp:send-textwhatsapp:send-templatewebhooks:readwebhooks:writeusers:readusers:writeusage:read

Auth & cuenta

POST/api/external/v2/signup
Crea tenant + API key inicial. Rate limit 5/h por IP.

Body

{ "company_name": "Acme", "admin_email": "you@acme.com", "admin_name": "Jane" }

Example

→ 201 { tenant_id, slug, api_key: { raw, prefix, scopes }, trial_ends_at }
GET/api/external/v2/me
Identidad + plan + usage_snapshot.
GET/api/external/v2/api-keys
Lista keys del tenant (sin valor raw).
POST/api/external/v2/api-keys
Mintea key adicional con subset de scopes.

Body

{ "label": "Webhook worker", "scopes": ["messages:read","contacts:read"] }
DELETE/api/external/v2/api-keys/:id
Soft revoke. No podés revocar la key con la que estás llamando.

Números & canales

GET/api/external/v2/numbers
Lista todos los números (WhatsApp Cloud + Telnyx).
POST/api/external/v2/numbers/whatsapp-cloud
Conecta un número Cloud API. Suscribe la WABA + ejecuta /register si pasás `pin`.

Body

{ "phone_number": "+12405036699", "cloud_api_phone_number_id": "1103…", "waba_id": "989…", "label": "World Cup 2026", "pin": "224092" }
PATCH/api/external/v2/numbers/:id
Update label, brain_type, brain_chat_url, forward_phone, bot_enabled.
DELETE/api/external/v2/numbers/:id
Soft-disconnect (status=disconnected; row queda para FK integrity).

Bot — IA & Knowledge Base

GET/api/external/v2/ai-config
Lista todas las configs del tenant (puede haber una por canal).
PATCH/api/external/v2/ai-config
Update system_prompt, model, temperature, channels, etc.

Body

{ "system_prompt": "Sos Mundialito…", "model": "gemini-flash-latest", "auto_reply_always": true }
GET/api/external/v2/knowledge-base
Lista KB entries.
POST/api/external/v2/knowledge-base
Add KB entry (max 20k chars).

Body

{ "title": "Horarios", "content": "Atendemos L-V 9-17 ET." }
PATCH/api/external/v2/knowledge-base/:id
Update title/content.
DELETE/api/external/v2/knowledge-base/:id
Hard delete.

Contactos & conversaciones

GET/api/external/v2/contacts
Lista contactos (paginated). Filtros: escalated, channel, phone, account_id.

Query

?escalated=true&channel=whatsapp&limit=50&cursor=<iso>
GET/api/external/v2/contacts/:id
Full row + messages_count.
GET/api/external/v2/contacts/:id/messages
History paginated (newest first).

Query

?limit=50&cursor=<iso>
POST/api/external/v2/contacts/:id/escalate
Pausa bot + manda email de escalation.

Body

{ "reason": "Cliente quiere precio especial" }
POST/api/external/v2/contacts/:id/resolve
Clear escalated flag, resume bot.
POST/api/external/contacts/enrich
(v1) PATCH semántico — origin_state, destination_country, notes, etc.

Enviar mensajes

POST/api/external/whatsapp/send-text
(v1) Texto dentro del 24h window. Soporta media adjunta.

Body

{ "account_id": "uuid", "to_phone": "+15551234567", "text": "Hola!" }
POST/api/external/whatsapp/send-template
(v1) Template aprobada por Meta. Funciona fuera del 24h window.

Body

{ "account_id": "uuid", "to_phone": "+1…", "template_name": "saludo", "language": "es" }

Webhooks outbound

GET/api/external/v2/webhooks
Lista webhooks configurados.
POST/api/external/v2/webhooks
Suscribir URL HTTPS a eventos. Devuelve `secret` UNA vez (para HMAC).

Body

{ "url": "https://yours.com/nexus", "events": ["message.inbound","contact.escalated"] }
PATCH/api/external/v2/webhooks/:id
Toggle is_active, update url o events[].
DELETE/api/external/v2/webhooks/:id
Hard delete + cancel pending deliveries.

Users / agents

GET/api/external/v2/users
Lista agentes y admins.
POST/api/external/v2/users
Crea user + manda invite email con temp password.

Body

{ "email": "agent@acme.com", "full_name": "Jane Doe", "role": "agent" }
PATCH/api/external/v2/users/:id
Update full_name, role.
DELETE/api/external/v2/users/:id
Borra auth.users + wmp_users.

Reports & usage

GET/api/external/v2/usage
Mensajes in/out, contactos nuevos, créditos campañas, breakdown por canal.

Query

?from=2026-05-01&to=2026-05-15

Webhook events

Cuando suscribís un webhook, NEXUS hace POST con header X-NEXUS-Signature-256: sha256=<hmac> firmado con tu secret. Retry exponencial: 1m, 5m, 30m, 2h, 12h, 24h.

message.inboundCliente mandó mensaje (cualquier canal). Payload: contact_id, phone_number, channel, text, media_url, media_type.
message.outboundNEXUS envió mensaje (humano o bot). Payload: contact_id, channel, text, sender_type (agent | ai).
contact.escalatedBot detectó [SOLICITA_AGENTE] o admin escalateó. Payload: contact_id, reason.
contact.resolvedEscalation marcada resuelta. Payload: contact_id.
lead.createdPRD/Lead extraído de conversación. Payload: lead_id, prd_title, prd_price.
number.connectedNuevo número Cloud API conectado. Payload: account_id, phone_number, waba_id.
template.approvedMeta aprobó una template. Payload: template_id, name, language.
payment.failedStripe rechazó renovación. Payload: invoice_id, amount, attempt.

MCP server

Wrap completo de los endpoints REST como tools MCP. Conectá Claude Code / Desktop:

# ~/.claude/mcp.json
{
  "mcpServers": {
    "nexus": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://nexus-mcp.espartan.net/api/mcp"],
      "env": { "AUTHORIZATION_HEADER": "Bearer nx_<your-key>" }
    }
  }
}

16 tools disponibles. Source: github.com/spartan-media/nexus-mcp