API HTTP
El binario del gateway sirve dos listeners:
- la API, en
SYNAPSE_ADDR(por defecto0.0.0.0:8080), con todos los endpoints de esta página salvo el de métricas; - el endpoint de métricas, en
SYNAPSE_METRICS_ADDR(por defecto0.0.0.0:9090).
Ambos hablan HTTP sin cifrar y ninguno autentica a los clientes; consulta Seguridad.
Endpoints
| Método | Path | Propósito |
|---|---|---|
GET | /health | Comprobación de actividad (liveness). |
GET | /v1/models | Lista los alias de las rutas de chat. |
POST | /v1/chat/completions | Chat completions compatibles con OpenAI, con o sin streaming. |
POST | /v1/embeddings | Embeddings compatibles con OpenAI. |
POST | /v1beta/models/{model}:{action} | Passthrough nativo de Gemini a Vertex AI. |
POST | /v1/models/{model}:{action} | Passthrough nativo de Gemini a Vertex AI. |
POST | /google/models/{model}:{action} | Passthrough nativo de Gemini a Vertex AI. |
POST | /typesafe/v1/systemone | Passthrough de Jev a TypeSafe System One. |
POST | /internal/a2a/agents | Registra un agente A2A. |
DELETE | /internal/a2a/agents/{id} | Elimina un agente A2A. |
GET | /.well-known/a2a-agent-catalog.json | Lista los agentes A2A registrados. |
GET | /a2a/agents/{id}/.well-known/agent-card.json | La agent card A2A de un agente. |
GET | /a2a/agents/{id}/resolve | El endpoint y la agent card de un agente. |
GET | /metrics y / (puerto de métricas) | Métricas de Prometheus. |
Cualquier otro path devuelve 404 con el cuerpo vacío, y un path conocido con el método
equivocado devuelve 405.
Encabezados de petición
Todos los endpoints salvo los de salud, modelos, A2A y métricas leen estos encabezados de atribución opcionales y los anotan en las filas del registro de costes de la petición. Atribución por tenant explica cada uno.
| Encabezado | Efecto |
|---|---|
x-synapse-tenant | Tenant. Sin él, SYNAPSE_DEFAULT_TENANT (por defecto unattributed). |
x-synapse-workspace | Workspace dentro del tenant. |
x-synapse-user | Usuario final. |
x-synapse-thread | Conversación o hilo de agente. |
x-synapse-message | Id de mensaje. En los chat completions y en los passthroughs también se convierte en el id de la petición. |
x-synapse-user-task-type | Tu propia etiqueta para el trabajo, registrada tal como se envía. |
x-synapse-ai-task-type | Sustituye el tipo de tarea de IA. |
Encabezados de respuesta
Las respuestas de los chat completions llevan el informe de enrutamiento. Router Jev describe cuándo aparece cada encabezado.
| Encabezado | Valores |
|---|---|
x-synapse-routing | static, jev o static-override. Siempre presente en los chat completions. |
x-synapse-tier | El nivel cuyo tramo sirvió la petición. |
x-synapse-tier-decided | El nivel que eligió Jev, cuando sirvió otro nivel. |
x-synapse-reasoning-effort | El esfuerzo del tramo que sirvió, o client cuando la petición fijó el suyo. |
x-synapse-routing-degraded | timeout, error, low_confidence o jev_unavailable. |
Errores
Los errores del gateway son JSON con la forma de OpenAI:
{
"error": {
"type": "model_not_found",
"message": "unknown model alias 'chat-typo'",
"code": "model_not_found"
}
}
| Estado | code | Cuándo |
|---|---|---|
400 | invalid_request_error | La petición no es válida para su ruta, por ejemplo un routing_strategy desconocido, un bloque jev en el tipo de ruta equivocado, un dimensions de embeddings que no coincide, o un 4xx de Vertex nativo que detiene la cadena. También lo devuelve un passthrough cuyo proveedor no está configurado. |
400 | native_feature_unsupported | La petición usa funcionalidades de Vertex nativo y la ruta no tiene ningún tramo vertex. |
400 | content_blocked | Una política de guardrails bloqueó la petición. type es content_policy_violation y un array scanners nombra los escáneres. Consulta Respuesta de bloqueo. |
404 | model_not_found | El model no es un alias de ruta de chat (chat) ni un alias de embeddings (embeddings). |
502 | all_legs_failed | Fallaron todos los tramos. Un array failures lista el provider, el model y el message de cada tramo. Consulta Cuando fallan todos los tramos. |
502 | upstream_error | Un proveedor falló donde no era posible ningún fallback más, como el último tramo de Vertex nativo o un tramo de embeddings. |
El message es legible para personas y puede cambiar entre versiones; para distinguir errores,
usa code. Un cuerpo que no es JSON válido, o que no encaja con el esquema del endpoint, se
rechaza antes de llegar al gateway, con un mensaje de texto plano en lugar de esta forma: 400
para JSON mal formado, 415 sin un encabezado Content-Type: application/json, y 422 para un
campo que falta o tiene un tipo incorrecto. Los cuerpos de más de 2 MB se rechazan con 413.
Los endpoints passthrough devuelven el estado y el cuerpo del proveedor sin cambios cuando el proveedor responde. Consulta Passthrough de Gemini y Passthrough de Jev.
GET /health
Devuelve 200 con el cuerpo ok. No comprueba los proveedores ni el registro de costes; solo
muestra que el proceso está sirviendo HTTP.
GET /v1/models
Lista los alias de las rutas de chat de routes.toml, ordenados por nombre:
{
"object": "list",
"data": [
{ "id": "auto", "object": "model", "owned_by": "synapse" },
{ "id": "chat", "object": "model", "owned_by": "synapse" }
]
}
Los alias de embeddings no se listan.
POST /v1/chat/completions
Una petición de chat completion de OpenAI. model es un alias de ruta; la ruta decide qué
proveedores y modelos la sirven.
| Campo | Tipo | Descripción |
|---|---|---|
model | string | Obligatorio. Un alias de ruta de routes.toml. |
messages | array | Obligatorio. Mensajes de OpenAI: role, content (una cadena, un array de partes de contenido, o null en un turno del asistente con llamadas a herramientas) y, opcionalmente, tool_calls, tool_call_id y name. |
stream | boolean | true para server-sent events. Consulta Streaming. |
temperature | number | Temperatura de muestreo. |
max_tokens | integer | Límite de tokens de salida. Solo se respeta en el carril Vertex nativo. |
response_format | object | {"type": "text" | "json_object" | "json_schema", "json_schema": {...}}. Solo en el carril estándar; en el carril Vertex nativo usa vertex.response_schema. |
tools | array | Herramientas de función de OpenAI. Consulta Llamadas a herramientas. |
tool_choice | string or object | Solo se respeta en el carril Vertex nativo. |
routing_strategy | string | static o jev. Consulta Anular la decisión por petición. |
vertex | object | Funcionalidades de Vertex nativo: cached_content, media_uris, response_schema, thinking_config. Selecciona el carril Vertex nativo; consulta Detección de carril y la guía de Vertex nativo. |
jev | object | Preguntas tipadas para el carril Jev: questions, state opcional, extract opcional. Consulta la guía del carril Jev. |
El gateway acepta cualquier otro campo sin error, pero reenvía muy pocos:
- El carril estándar envía al proveedor
messages,tools,temperature,response_formaty unreasoning_effortde OpenAI. Descartamax_tokens,tool_choicey cualquier otro campo, comotop_p,stoposeed. - El carril Vertex nativo envía
messages,tools,tool_choice,temperature,max_tokensy el bloquevertex. Consulta Otros campos de la petición.
Limitaciones lista lo que falta.
Respuesta
Una petición sin streaming devuelve un chat.completion:
{
"id": "chatcmpl-3f1c9a52-7d4e-4b8a-9c1e-2a6b0f9d8e71",
"object": "chat.completion",
"created": 1790620000,
"model": "gemini-3.5-flash-lite",
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "Hello!" },
"finish_reason": "stop"
}],
"usage": { "prompt_tokens": 9, "completion_tokens": 3, "total_tokens": 12 }
}
ideschatcmpl-seguido del id de la petición: el encabezadox-synapse-message, o un UUID generado.modeles el modelo del tramo que sirvió la petición, no el alias de la ruta.finish_reasonesstop,lengthotool_calls. Una llamada a herramienta tienecontent: nully un arraytool_calls.- Una respuesta de extracción híbrida añade un objeto
jevconanswers,survivorsydegraded.
Respuesta con streaming
Con "stream": true, la respuesta es text/event-stream. Cada evento es un
chat.completion.chunk en una línea data:, y el stream termina con data: [DONE]:
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":0,"model":"gemini-3.5-flash-lite","choices":[{"index":0,"delta":{"content":"Hel"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":0,"model":"gemini-3.5-flash-lite","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
Los fragmentos no llevan usage y created siempre es 0. Un fallo después del primer
fragmento llega como un evento cuyo cuerpo es un objeto de error, seguido de [DONE]; consulta
Fallback durante el streaming.
POST /v1/embeddings
| Campo | Tipo | Descripción |
|---|---|---|
model | string | Obligatorio. Un alias de embeddings de la tabla embeddings de routes.toml. |
input | string or array of strings | Obligatorio. Los textos que se van a convertir en embeddings. |
dimensions | integer | Opcional. Debe ser igual al dimensions del alias. |
La respuesta es una list de OpenAI de objetos embedding, en el orden de la entrada, con
usage.prompt_tokens y usage.total_tokens. El model de la respuesta es el alias. Consulta
Enviar una petición.
Passthrough de Gemini
POST /v1beta/models/{model}:{action}, POST /v1/models/{model}:{action} y
POST /google/models/{model}:{action} se comportan igual; los tres prefijos corresponden a las
versiones de la API que usan los SDK de Gemini de Google. El cuerpo es una petición de Gemini,
que se reenvía tal cual a Vertex AI con las credenciales del gateway.
{model}es un nombre de modelo de Vertex AI, no un alias de ruta, y{action}es la parte que va tras los últimos dos puntos, comogenerateContent,streamGenerateContentocountTokens.streamGenerateContentcon?alt=ssetransmite la respuesta en streaming.generateContentystreamGenerateContentescriben una fila en el registro de costes con el carrilpassthrough. Ante una respuesta5xx,429o408o un error de conexión, prueban los siguientes tramosvertexde la ruta que lista el modelo; consulta Clientes del SDK de Gemini.- Las demás acciones se reenvían una sola vez, sin fila en el registro de costes.
- Un modelo que ninguna ruta lista se reenvía igualmente, en un único intento.
- Las llamadas con streaming (
?alt=sse) pueden durar hasta una hora. Todas las demás están acotadas porSYNAPSE_REQUEST_TIMEOUT_SECS. - El estado y el cuerpo de Vertex AI se devuelven sin cambios. Un error de conexión en el último
intento devuelve
502con el códigoupstream_error. Si el gateway no tiene ningún proyecto de Vertex AI configurado, el endpoint devuelve400.
Los guardrails no escanean las peticiones passthrough.
Passthrough de Jev
POST /typesafe/v1/systemone reenvía tal cual un cuerpo {state, questions} de TypeSafe System
One con la TYPESAFE_API_KEY del gateway. El cuerpo debe ser un objeto JSON; si no tiene
model, el gateway fija jev-latest. El estado y el cuerpo de TypeSafe se devuelven sin
cambios, y el uso se anota en el registro de costes con el carril passthrough. Sin
TYPESAFE_API_KEY, el endpoint devuelve 400. Consulta
Passthrough de Jev.
Registro de agentes A2A
El binario del gateway sirve un registro en memoria de agentes A2A, cargado al arrancar desde
a2a.toml (consulta Claves de configuración). Cada instancia
del gateway tiene su propio registro.
POST /internal/a2a/agents
Registra un agente. Todos los campos salvo ttl_seconds son obligatorios:
{
"id": "invoice-agent",
"name": "Invoice agent",
"description": "Extracts line items from invoices",
"endpoint_url": "https://agents.example.com/invoice",
"card_url": "https://agents.example.com/invoice/.well-known/agent-card.json",
"tags": ["finance"],
"card": { "name": "Invoice agent", "skills": [] },
"ttl_seconds": 3600
}
Devuelve 204. Si el id ya está registrado, se conserva la entrada existente y la petición
devuelve igualmente 204. Con ttl_seconds, el agente desaparece del catálogo ese número de
segundos después del registro.
DELETE /internal/a2a/agents/{id}
Elimina el agente. Devuelve 204, exista o no el id.
Los endpoints /internal/ no tienen autenticación. Bloquéalos en tu proxy; consulta
Los endpoints de administración de A2A están abiertos.
GET /.well-known/a2a-agent-catalog.json
{
"version": "1.0",
"agents": [{
"id": "invoice-agent",
"name": "Invoice agent",
"description": "Extracts line items from invoices",
"card_url": "https://agents.example.com/invoice/.well-known/agent-card.json",
"endpoint_url": "https://agents.example.com/invoice",
"tags": ["finance"]
}]
}
GET /a2a/agents/{id}/.well-known/agent-card.json
Devuelve la agent card del agente tal como se registró, o 404 con el cuerpo vacío.
GET /a2a/agents/{id}/resolve
Devuelve {"id", "endpoint_url", "card_url", "card"} para el agente, o 404 con el cuerpo
vacío.
Métricas
GET /metrics y GET / en el puerto de métricas devuelven el formato de texto de Prometheus.
Consulta Métricas y el catálogo de métricas.