Documentación para desarrolladores / REST API
Tu automatización. Una conversación.
Envía un mensaje, recibe una respuesta y sigue el trabajo aprobado hasta su resultado con la API REST de Pushyou.
Configurar tu conexión01Antes de empezar
Crea una cuenta y una conversación en la app de pruebas internas de Pushyou a la que te invitaron. El acceso web requiere aprobar un QR en esa app. La guía de conexión permite elegir la conversación y comprobar la entrega.
Crea una conexión por programa en Ajustes → Conexiones. Autoriza solo las conversaciones y operaciones necesarias. Las claves se muestran una sola vez. El acceso a salas seleccionadas no permite crear otras; se requiere acceso a todas y conversations:write.
02Autenticación
Ejecuta estos comandos en Bash o zsh, en tu ordenador o servidor. Guarda la clave en la configuración de secretos de tu entorno. No la incluyas en código del navegador, URL ni vistas publicadas. Los tokens OAuth de MCP no autentican solicitudes REST.
export PUSHYOU_API_URL='https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouApi'
export PUSHYOU_MEDIA_URL='https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouMedia'printf 'Pushyou API key: ' >&2
IFS= read -r -s PUSHYOU_API_KEY
printf '\n' >&2
export PUSHYOU_API_KEYcurl --fail-with-body --silent --show-error \
-X GET "$PUSHYOU_API_URL/v1/me" \
-H "Authorization: Bearer $PUSHYOU_API_KEY"03Envía tu primer mensaje
Elegir una conversación existente
Comprueba id, permissions y conversation_ids en la respuesta de la cuenta. Si conversation_ids es null, el acceso incluye todas las conversaciones. Lista las salas permitidas y sustituye YOUR_CONVERSATION_ID por un ID real. Esta consulta requiere conversations:read.
curl --fail-with-body --silent --show-error \
-X GET "$PUSHYOU_API_URL/v1/conversations?limit=20" \
-H "Authorization: Bearer $PUSHYOU_API_KEY"export PUSHYOU_CONVERSATION_ID='YOUR_CONVERSATION_ID'curl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/messages" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"id":"docs-message-01","text":"Pushyou connection verified.","notify":true}'{
"conversation_id": "YOUR_CONVERSATION_ID",
"message_id": "docs-message-01",
"duplicate": false
}Usa un ID estable para cada mensaje lógico. Repetir el mismo ID y contenido devuelve HTTP 200 con duplicate: true. Un contenido distinto con el mismo ID devuelve 409. Usa un ID nuevo para un mensaje nuevo.
Campos del mensaje
| Campo | Contrato |
|---|---|
id | Obligatorio. Entre 1 y 80 letras, números, guiones o guiones bajos. |
text | Hasta 8.000 caracteres. Se requiere texto no vacío o al menos un archivo adjunto. |
attachment_ids | Hasta cuatro IDs de archivos ya subidos a esta conversación. |
card | Opcional: tarjeta report, actions o html. Una tarjeta sola no sustituye al texto o al archivo adjunto. |
notify | Booleano, true por defecto. Solicita una notificación; su entrega también depende de los permisos del dispositivo y los ajustes. |
Las listas de conversaciones, mensajes e historial usan limit (1–100, 50 por defecto) y before=next_cursor. Conserva los filtros y detente cuando next_cursor sea null. Los eventos usan un cursor numérico after en orden ascendente. Las consultas no marcan los mensajes como leídos en la app.
04Respuestas y ejecución
Responde en la app y consulta los eventos. Tras procesar realmente una respuesta o acción ordinaria, guarda el resultado, envía su ACK y conserva next_cursor en almacenamiento persistente. El ACK no elimina el evento ni concede ejecución exclusiva. Usa un único programa de respuesta por sala o coordina los consumidores.
curl --fail-with-body --silent --show-error \
-X GET "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/events?after=0" \
-H "Authorization: Bearer $PUSHYOU_API_KEY"curl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/events/YOUR_EVENT_ID/ack" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{}'Solicitar aprobación
curl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/tasks" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"id":"docs-report-01","title":"Review the weekly report","category_id":"reports","fields":[{"id":"notes","label":"Review notes","type":"multiline","required":false}]}'Las tareas reúnen aprobación y resultado. Tras la aprobación del propietario, un proceso consulta eventos con task_protocol=1, guarda su token de ejecución y reclama el intento. Mantiene la concesión con heartbeat y guarda el resultado real antes de complete. Completar también confirma el evento; un ACK independiente no termina una tarea pendiente.
Campos, reclamaciones y resultados de tareas (inglés) ↗Response receiver
Para respuestas continuas, ejecuta el receptor en Node 22 o posterior con una clave REST. Guarda los resultados antes de enviar y confirmar. Mantén el proceso activo: no funciona con el ordenador suspendido. Su modo Codex inicia una sesión dedicada; no se conecta a un chat existente.
Webhooks
También hay webhooks de respuesta firmados. Configúralos en los ajustes de Webhooks de respuesta de la app móvil. Verifica la firma del cuerpo original y evita duplicados por ID de entrega. HTTP 2xx confirma recepción, no finalización de la tarea. La guía de flujos detalla firmas y reintentos.
05Archivos y vistas
Los archivos usan un endpoint de medios separado y la misma clave REST con media:write o media:read. Sube primero los bytes originales y adjunta el ID a un mensaje de la misma sala. Las URL son privadas y requieren autorización. El límite es 10 MiB por imagen y 25 MiB por vídeo.
curl --fail-with-body --silent --show-error \
"$PUSHYOU_MEDIA_URL/v1/media/docs-image-01?conversation_id=$PUSHYOU_CONVERSATION_ID" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/octet-stream' \
-H 'X-Pushyou-Filename: review.png' \
--data-binary @review.pngcurl --fail-with-body --silent --show-error \
-X POST "$PUSHYOU_API_URL/v1/conversations/$PUSHYOU_CONVERSATION_ID/messages" \
-H "Authorization: Bearer $PUSHYOU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"id":"docs-attachment-01","text":"Please review this image.","attachment_ids":["docs-image-01"]}'En MCP, llama a pushyou_prepare_media_upload con media_id, filename, content_type, tamaño en bytes y SHA-256. Envía los bytes originales mediante POST a upload.url, con los encabezados específicos devueltos, en cinco minutos. Después envía attachment_ids. REST ofrece la misma preparación. No sustituyas la autorización de carga por una clave de cuenta o token OAuth MCP.
Publica una vista opcional report, actions o html con PATCH …/view y {"view": CARD}; {"view": null} la retira. Se abre desde su conversación. El HTML está aislado: sin red externa, credenciales de la app ni almacenamiento del navegador. Declara las acciones; generarán eventos en la misma sala.
Card / Field
Card =
{ type: "report", title: string, items: { title: string, body?: string, label?: string }[] }
| { type: "actions", title: string, body?: string, actions: { id: ID, label: string }[] }
| { type: "html", title: string, html: string, height?: integer, actions?: { id: ID, label: string }[] }
Field = { id: ID, label: string, type: "text" | "multiline" | "number" | "date" | "select" | "checkbox", required?: boolean, options?: string[], min?: number, max?: number }06Referencia de endpoints
Añade cada ruta a la base de su grupo. Usa una clave Bearer del programa, salvo en cargas con autorización específica. Abre una fila para ver la estructura de la solicitud y sustituye los IDs de ejemplo.
API JSON
https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouApiPOST/v1/conversations/{id}/media/uploads
Preparar la carga de un archivo
Proporciona ID, nombre, tipo, tamaño en bytes y SHA-256 para obtener un permiso de carga de cinco minutos para ese archivo. Requiere media:write.
{ media_id: ID, filename: string, content_type: string, size: integer, sha256: string }GET/v1/me
Comprobar cuenta
Comprueba la cuenta y los permisos asociados a esta clave API.
GET /v1/me
→ { id, key_scope, permissions, conversation_ids }POST/v1/conversations
Crear conversación
Crea una conversación con id y name. Reintentar con el mismo ID y contenido no crea duplicados.
{ id: ID, name: string, description?: string, kind?: string, view?: Card }GET/v1/conversations
Listar conversaciones
Lista las conversaciones de tu cuenta.
?limit=20&before=CURSOR
→ { conversations, next_cursor }GET/v1/conversations/{id}
Obtener conversación
Obtén el nombre, la descripción, el estado y la vista publicada de la conversación.
GET /v1/conversations/ROOM_ID
→ { conversation }PATCH/v1/conversations/{id}
Actualizar conversación
Actualiza el nombre, la descripción y el estado fijado. Usa active para pausar o reanudar la conversación.
{ name?: string, description?: string, pinned?: boolean, active?: boolean, view?: Card | null }POST/v1/conversations/{id}/messages
Enviar mensaje
Envía texto, tarjetas y adjuntos. Incluye los IDs de archivos subidos en attachment_ids y usa notify para controlar las notificaciones.
{ id: ID, text?: string, attachment_ids?: ID[], card?: Card | null, notify?: boolean }GET/v1/conversations/{id}/messages
Leer conversación
Lista los mensajes recibidos y respuestas del usuario, del más reciente al más antiguo.
?limit=20&before=CURSOR
→ { messages, next_cursor }GET/v1/conversations/{id}/messages/{message_id}
Obtener mensaje
Lee el contenido y la tarjeta de un mensaje.
GET /v1/conversations/ROOM_ID/messages/MESSAGE_ID
→ { message }GET/v1/conversations/{id}/events/head
Secuencia actual de respuestas
Lee la última secuencia antes de iniciar un nuevo receptor. No marca mensajes como leídos ni eventos como procesados.
GET /v1/conversations/ROOM_ID/events/head
→ { cursor }GET/v1/conversations/{id}/receiver-status
Obtener estado del receptor
Consulta el último estado y hora informados por el receptor. No confirma que la tarea haya terminado ni que el receptor tenga su reserva de ejecución.
GET /v1/conversations/ROOM_ID/receiver-status
→ { receivers, checked_at }PUT/v1/conversations/{id}/receiver-status/{instance_id}
Informar del estado del receptor
Informa de cada ejecución con un nuevo UUID y una sequence creciente. Requiere permisos de lectura de conversaciones y eventos, ACK y escritura de mensajes.
{ sequence: positive_integer, state: "starting" | "receiving" | "processing" | "retrying" | "paused" | "stopped" | "needs_review" | "delivery_pending" }
instance_id: UUID v4GET/v1/conversations/{id}/events
Obtener respuestas del usuario
Lee respuestas y acciones de botón enviadas después de la secuencia indicada.
?after=0
?after=0&task_protocol=1
→ { events, next_cursor }POST/v1/conversations/{id}/events/{event_id}/ack
Confirmar una respuesta
Marca un evento como procesado por tu agente o servidor.
{}
→ { ok: true }GET/v1/conversations/{id}/view
Obtener vista de conversación
Lee la vista HTML o de componentes publicada en una conversación.
GET /v1/conversations/ROOM_ID/view
→ { view: Card | null }PATCH/v1/conversations/{id}/view
Publicar vista de conversación
Envía una tarjeta como view para añadir Abrir vista a la cabecera de la conversación. Envía null para eliminarla.
{ view: Card | null }GET/v1/history
Obtener historial
Consulta el historial por páginas combinando category_id, kind, status_group y conversation_id.
?limit=20&before=CURSOR
&category_id=reports&conversation_id=ROOM_ID
&kind=received&status_group=attention
&result_pending=true
kind: received | action | saved
status_group: attention | progress | problems | complete
→ { history, next_cursor }POST/v1/conversations/{id}/tasks
Solicitar aprobación de tarea
Envía un ID estable, título, cuerpo y formulario de tarea. El evento de ejecución se crea solo después de la aprobación del usuario.
{ id: ID, title: string, body?: string, category_id?: ID, fields?: Field[], inputs?: object, expires_at?: integer, result_requires_review?: boolean }GET/v1/conversations/{id}/tasks/{task_id}
Obtener estado de tarea
Consulta el estado, intento, datos y resultado actuales.
GET /v1/conversations/ROOM_ID/tasks/TASK_ID
→ { task }GET/v1/conversations/{id}/tasks/{task_id}/versions
Consultar versiones de la solicitud
Consulta las versiones anteriores de la misma solicitud.
GET /v1/conversations/ROOM_ID/tasks/TASK_ID/versions
→ { versions: [{revision, title, body, fields, inputs, created_at, change_request}] }POST/v1/conversations/{id}/tasks/{task_id}/revise
Actualizar solicitud
Envía una solicitud actualizada para que la apruebe su propietario.
{ request_id: ID, expected_revision: integer, change_request_id?: ID, body: string, title?: string, fields?: Field[], inputs?: object }
Only pending or changes_requested tasks can be revised. Approval is required for every new version.POST/v1/conversations/{id}/tasks/{task_id}/claim
Reclamar ejecución de tarea
Guarda el token de ejecución antes de reservar el intento. Inicia el trabajo externo solo cuando la reserva se complete.
{ request_id: ID, attempt: integer, execution_token: string }POST/v1/conversations/{id}/tasks/{task_id}/heartbeat
Mantener la reserva de ejecución
Renueva el plazo de diez minutos de la reserva actual. Si se pierde, la tarea queda pendiente de revisión.
{ request_id: ID, attempt: integer, execution_token: string }POST/v1/conversations/{id}/tasks/{task_id}/complete
Informar del resultado de la tarea
Guarda el resultado localmente antes de informar de succeeded, failed o needs_review. También se confirma el evento correspondiente.
{ request_id: ID, attempt: integer, execution_token: string, status: "succeeded" | "failed" | "needs_review", result: string, result_links?: [{label: string, url: HTTPS_URL}] }GET/v1/conversations/{id}/actions
Listar acciones de conversación
Lee los formularios de la conversación y sus revisiones actuales.
GET /v1/conversations/ROOM_ID/actions
→ { actions }PUT/v1/conversations/{id}/actions/{action_id}
Publicar acción de conversación
Crea o actualiza un formulario. Las actualizaciones requieren expected_revision. El usuario lo envía de forma explícita.
{ title: string, description?: string, fields: Field[], category_id?: ID, active?: boolean, expected_revision?: ID }API de medios
https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouMediaPOST/v1/uploads/{id}
Subir un archivo preparado
Envía los bytes originales con la URL y cabecera de autorización específicas del archivo obtenidas al preparar la carga MCP. No las sustituyas por una clave de cuenta o token OAuth de MCP.
POST upload.url
Headers: upload.headers
Body: original file bytesPOST/v1/media/{id}?conversation_id={room}
Subir fotos o vídeos
Envía los bytes originales con la cabecera X-Pushyou-Filename codificada como URI. Reintenta con el mismo ID y archivo.
Content-Type: application/octet-stream
X-Pushyou-Filename: URI_ENCODED_FILENAME
Body: original file bytesGET/v1/media/{id}
Obtener archivo
Obtén fotos o vídeos con una cabecera de autorización. El vídeo admite una única solicitud Range.
Range: bytes=0-65535 (optional)
→ original file bytesHEAD/v1/media/{id}
Información del archivo
Consulta el tipo MIME, el tamaño y las cabeceras Range sin descargar el cuerpo del archivo.
HEAD /v1/media/MEDIA_ID
→ Content-Type, Content-Length, Accept-RangesDELETE/v1/media/{id}
Eliminar carga sin usar
Elimina un archivo que aún no esté adjunto a un mensaje. Los IDs eliminados no se pueden reutilizar.
DELETE /v1/media/UNATTACHED_MEDIA_ID07Solución de problemas
Los errores REST devuelven un estado distinto de 2xx y {"error": "…"}. El cliente muestra los errores MCP; revisa el error estructurado y los permisos de la conexión.
400 | Comprueba IDs, campos obligatorios, tipos, cursor y tamaño de la solicitud. |
|---|---|
401 | Vuelve a autenticarte o comprueba si la clave caducó, se renovó o se revocó. |
403 | Comprueba permisos, salas autorizadas y si la conversación está pausada. |
404 | Comprueba el ID y la base del endpoint. /mcp es un endpoint de protocolo, no una página web. |
409 | Revisa el conflicto: ID reutilizado con otro contenido, revisión antigua, reclamación de tarea o archivo ya adjunto. No repitas trabajo externo sin comprobarlo. |
410 | La conversación se está eliminando o el recurso ya no está disponible. Comprueba su estado. |
413 | Reduce el cuerpo JSON o el archivo y comprueba los límites de carga. |
415 | Usa un formato de imagen o vídeo compatible con bytes válidos. |
416 | Comprueba que el rango de bytes solicitado esté dentro del archivo. |
429 | Espacia las solicitudes si alcanzaste el límite. Si falta espacio para medios, elimina archivos sin adjuntar antes de reintentar. Se permiten 60 mensajes nuevos por minuto y sala. |
500 | Reintenta fallos temporales con espera progresiva e IDs estables. Si el trabajo externo pudo ejecutarse, comprueba el resultado antes de repetirlo. |
¿Listo para conectar tu conversación?
Elige la sala, aprueba el acceso y comprueba el primer mensaje y su respuesta en la guía.
Configurar tu conexión