Diseño de API · REST AgentFlow SaaS

API Design Guide
AgentFlow v1

Referencia de diseño para la API pública de AgentFlow. Principios, patrones, contratos de endpoints y mejores prácticas para un developer experience de primer nivel.

18endpoints
4recursos principales
RESTparadigma
OpenAPI 3.1especificación
Base URL https://api.agentflow.io / v1
🔑

Autenticación

API Key via header — sin cookies, sin sesiones
ℹ️ Todas las peticiones deben incluir el header Authorization: Bearer <API_KEY>. Las API Keys se generan en Settings → API Keys del dashboard.

Ejemplo de petición autenticada

bash — cURL
# Listar tus agentes
curl -X GET "https://api.agentflow.io/v1/agents" \
  -H "Authorization: Bearer af_live_sk_xxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json"

Scopes de API Key

ScopeAccesoUso recomendado
read:allLectura de todos los recursosDashboards, integraciones de solo consulta
write:agentsCrear y modificar agentesCI/CD, deployment pipelines
write:runsCrear y cancelar ejecucionesIntegraciones Zapier/Make
adminAcceso total (incluyendo billing)Solo backend — nunca en frontend
⚠️

Errores

Formato estándar RFC 7807 — consistente en toda la API
❌ NO hacer
// Respuesta caótica — sin estructura
{
  "error": "not found",
  "msg": "el agente no existe",
  "code": 404,
  "ok": false
}
✅ SÍ hacer
// RFC 7807 — predecible y accionable
{
  "type": "https://api.agentflow.io/errors/not-found",
  "title": "Resource not found",
  "status": 404,
  "detail": "Agent ag_abc123 not found",
  "instance": "/v1/agents/ag_abc123",
  "request_id": "req_7f3ab82c"
}

Códigos de estado HTTP

200
OK
Petición exitosa con cuerpo
201
Created
Recurso creado; incluye Location header
204
No Content
DELETE exitoso, sin cuerpo
400
Bad Request
Payload inválido o parámetros erróneos
401
Unauthorized
API Key ausente o inválida
403
Forbidden
Scope insuficiente
404
Not Found
Recurso inexistente
409
Conflict
Nombre duplicado u otro conflicto de estado
422
Unprocessable Entity
Validación semántica fallida
429
Too Many Requests
Rate limit excedido
500
Internal Server Error
Error interno — reportar con request_id
503
Service Unavailable
Mantenimiento; usar Retry-After
📄

Paginación

Cursor-based — eficiente y estable para grandes colecciones
💡 Se usa cursor-based pagination (no offset) para garantizar consistencia en colecciones que cambian en tiempo real (nuevas ejecuciones se insertan constantemente).

Request

# Primera página
GET /v1/agents/ag_abc123/runs?limit=20

# Página siguiente (cursor del response anterior)
GET /v1/agents/ag_abc123/runs?limit=20&after=run_xyz789

Response

{
  "data": [ /* array de runs */ ],
  "meta": {
    "total_count": 1847,
    "returned_count": 20,
    "has_more": true
  },
  "pagination": {
    "cursor_next": "run_xyz789",
    "cursor_prev": "run_abc001"
  }
}
Flujo de paginación
GET /runs?limit=20
cursor_next: "run_xyz789"
GET /runs?after=run_xyz789
has_more: false
FIN
🚦

Rate Limiting

Headers de control incluidos en cada respuesta
Starter
60
req / minuto
Pro
600
req / minuto
Enterprise
Custom
SLA dedicado

Headers de rate limit en response

HTTP/1.1 200 OK
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 547
X-RateLimit-Reset: 1718531460   # Unix timestamp
X-RateLimit-Window: 60s
Retry-After: 12                   # Solo en 429
🤖

Agentes

Recurso principal — gestión completa de agentes de IA
POST /v1/agents Crear un nuevo agente

Request body

{
  "name": "SEO Content Writer",
  "model": "claude-sonnet-4-5",
  "instructions": "Eres un experto en SEO...",
  "tools": [
    { "type": "web_search" },
    { "type": "code_interpreter" }
  ],
  "workspace_id": "ws_7ab23cd",
  "metadata": {
    "department": "marketing"
  }
}
CampoTipoReq.
namestringrequerido
modelstringrequerido
instructionsstringopcional
toolsarrayopcional
metadataobjectopcional

Response 201 Created

{
  "id": "ag_9f23bc1d",
  "object": "agent",
  "name": "SEO Content Writer",
  "model": "claude-sonnet-4-5",
  "status": "active",
  "tools": [
    { "type": "web_search" },
    { "type": "code_interpreter" }
  ],
  "workspace_id": "ws_7ab23cd",
  "created_at": "2026-06-15T09:41:00Z",
  "updated_at": "2026-06-15T09:41:00Z",
  "metadata": {
    "department": "marketing"
  }
}
GET /v1/agents Listar agentes del workspace
Query paramTipoDefaultDescripción
limitinteger20Máx 100
afterstringCursor para paginación
statusstringactive | inactive | archived
workspace_idstringFiltrar por workspace
▶️

Ejecuciones (Runs)

Lanzar y monitorizar ejecuciones de agentes
POST /v1/agents/{agent_id}/runs Iniciar una nueva ejecución

Request body

{
  "input": {
    "messages": [
      {
        "role": "user",
        "content": "Escribe un artículo SEO sobre
IA en marketing, 1200 palabras"
      }
    ]
  },
  "config": {
    "max_tokens": 4096,
    "temperature": 0.7,
    "timeout_seconds": 120
  },
  "webhook_url": "https://yourapp.io/hook",
  "idempotency_key": "run_idem_20260615_001"
}

Response 201 — Run creado

{
  "id": "run_cc2f9a41",
  "object": "run",
  "agent_id": "ag_9f23bc1d",
  "status": "queued",
  "created_at": "2026-06-15T09:42:00Z",
  "started_at": null,
  "completed_at": null,
  "output": null,
  "usage": null,
  "webhook_url": "https://yourapp.io/hook"
}

Ciclo de vida de un Run

queued
in_progress
completed
/
failed
/
cancelled
⚠️ Usar siempre idempotency_key para evitar ejecuciones duplicadas en reintentos de red. La clave expira a las 24h.
🔔

Webhooks

Notificaciones push para integraciones Zapier / Make / custom
▶️
Run lanzado
POST /runs
⚙️
Ejecución
in_progress
Completado
completed
🔔
Webhook POST
tu endpoint

Payload de evento webhook

JSON — POST a tu endpoint
{
  "id": "evt_d4f8a1b3",
  "type": "run.completed",
  "created_at": "2026-06-15T09:44:12Z",
  "data": {
    "run_id": "run_cc2f9a41",
    "agent_id": "ag_9f23bc1d",
    "status": "completed",
    "duration_ms": 8421,
    "usage": {
      "input_tokens": 312,
      "output_tokens": 2847,
      "total_tokens": 3159
    }
  },
  "signature": "sha256=abc123..."  # HMAC-SHA256
}
🔐 Verificar siempre la firma HMAC-SHA256 del header X-AgentFlow-Signature antes de procesar el evento. Rechazar con 400 si no coincide.
📐

Convenciones de Naming

Reglas que aplican a toda la API de AgentFlow v1
Principio 01
Recursos en plural
Siempre /agents, /runs, /workspaces. Nunca /agent, /getAgent.
Principio 02
Kebab-case en URLs
Paths en minúsculas con guiones: /api-keys, no /apiKeys ni /api_keys.
Principio 03
Snake_case en JSON
Body y respuestas JSON usan snake_case: created_at, agent_id, workspace_id.
Principio 04
IDs con prefijo tipado
ag_ para agentes, run_ para ejecuciones, ws_ para workspaces. Siempre detectables a simple vista.
Principio 05
ISO 8601 para fechas
Todos los timestamps en UTC con sufijo Z: "2026-06-15T09:41:00Z". Nunca Unix epoch en body (solo en rate-limit headers).
Principio 06
Versión en URL
/v1/ como primer segmento. Mantener v1 activa mínimo 12 meses tras publicar v2. Deprecation via header Sunset.
Principio 07
PATCH para updates parciales
PATCH actualiza solo los campos enviados. PUT reemplaza el recurso completo. AgentFlow expone PATCH por defecto.
Principio 08
Envelope data consistente
Listas: {"data":[], "meta":{}, "pagination":{}}. Objetos únicos: devueltos directamente (sin wrapper).

Checklist de diseño — AgentFlow v1

Validar antes de cada release de endpoint
Recursos en plural y sustantivos
Verbos HTTP correctos (no GET para creates)
Status codes semánticos (201 en create, 204 en delete)
Errores en formato RFC 7807 con request_id
Paginación cursor-based en todas las listas
Rate limit headers en todas las respuestas
Timestamps en ISO 8601 UTC
IDs con prefijo tipado (ag_, run_...)
Autenticación via Bearer token (no query param)
Soporte de idempotency_key en POSTs
Webhooks con firma HMAC-SHA256
Header Location en respuestas 201
Versión en URL (/v1/)
Especificación OpenAPI 3.1 actualizada
Sin secrets en URLs — solo en headers
CORS configurado para clientes web