En esta página

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ón

01Antes 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.

Endpoints de producción
export PUSHYOU_API_URL='https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouApi'
export PUSHYOU_MEDIA_URL='https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouMedia'
Cargar la clave del programa
printf 'Pushyou API key: ' >&2
IFS= read -r -s PUSHYOU_API_KEY
printf '\n' >&2
export PUSHYOU_API_KEY
Comprobar cuenta y permisos
curl --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.

Elegir una conversación existente
curl --fail-with-body --silent --show-error \
  -X GET "$PUSHYOU_API_URL/v1/conversations?limit=20" \
  -H "Authorization: Bearer $PUSHYOU_API_KEY"
PUSHYOU_CONVERSATION_ID
export PUSHYOU_CONVERSATION_ID='YOUR_CONVERSATION_ID'
Enviar mensaje
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}'
Respuesta de ejemplo · HTTP 201
{
  "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

CampoContrato
idObligatorio. Entre 1 y 80 letras, números, guiones o guiones bajos.
textHasta 8.000 caracteres. Se requiere texto no vacío o al menos un archivo adjunto.
attachment_idsHasta cuatro IDs de archivos ya subidos a esta conversación.
cardOpcional: tarjeta report, actions o html. Una tarjeta sola no sustituye al texto o al archivo adjunto.
notifyBooleano, 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.

Consultar respuestas
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"
ACK · YOUR_EVENT_ID
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

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.

Subir un PNG local y adjuntarlo
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.png
Enviar mensaje
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-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
Estructura de la solicitud
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/pushyouApi
POST/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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
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.

Estructura de la solicitud
{ id: ID, name: string, description?: string, kind?: string, view?: Card }
GET/v1/conversations

Listar conversaciones

Lista las conversaciones de tu cuenta.

Estructura de la solicitud
?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.

Estructura de la solicitud
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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
?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.

Estructura de la solicitud
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.

Estructura de la solicitud
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.

Estructura de la solicitud
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.

Estructura de la solicitud
{ sequence: positive_integer, state: "starting" | "receiving" | "processing" | "retrying" | "paused" | "stopped" | "needs_review" | "delivery_pending" }
instance_id: UUID v4
GET/v1/conversations/{id}/events

Obtener respuestas del usuario

Lee respuestas y acciones de botón enviadas después de la secuencia indicada.

Estructura de la solicitud
?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.

Estructura de la solicitud
{}
→ { ok: true }
GET/v1/conversations/{id}/view

Obtener vista de conversación

Lee la vista HTML o de componentes publicada en una conversación.

Estructura de la solicitud
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.

Estructura de la solicitud
{ view: Card | null }
GET/v1/history

Obtener historial

Consulta el historial por páginas combinando category_id, kind, status_group y conversation_id.

Estructura de la solicitud
?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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
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.

Estructura de la 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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
{ 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.

Estructura de la solicitud
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.

Estructura de la solicitud
{ title: string, description?: string, fields: Field[], category_id?: ID, active?: boolean, expected_revision?: ID }

API de medios

https://asia-northeast3-pushyou-prod.cloudfunctions.net/pushyouMedia
POST/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.

Estructura de la solicitud
POST upload.url
Headers: upload.headers
Body: original file bytes
POST/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.

Estructura de la solicitud
Content-Type: application/octet-stream
X-Pushyou-Filename: URI_ENCODED_FILENAME
Body: original file bytes
GET/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.

Estructura de la solicitud
Range: bytes=0-65535 (optional)
→ original file bytes
HEAD/v1/media/{id}

Información del archivo

Consulta el tipo MIME, el tamaño y las cabeceras Range sin descargar el cuerpo del archivo.

Estructura de la solicitud
HEAD /v1/media/MEDIA_ID
→ Content-Type, Content-Length, Accept-Ranges
DELETE/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.

Estructura de la solicitud
DELETE /v1/media/UNATTACHED_MEDIA_ID

07Solució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.

400Comprueba IDs, campos obligatorios, tipos, cursor y tamaño de la solicitud.
401Vuelve a autenticarte o comprueba si la clave caducó, se renovó o se revocó.
403Comprueba permisos, salas autorizadas y si la conversación está pausada.
404Comprueba el ID y la base del endpoint. /mcp es un endpoint de protocolo, no una página web.
409Revisa el conflicto: ID reutilizado con otro contenido, revisión antigua, reclamación de tarea o archivo ya adjunto. No repitas trabajo externo sin comprobarlo.
410La conversación se está eliminando o el recurso ya no está disponible. Comprueba su estado.
413Reduce el cuerpo JSON o el archivo y comprueba los límites de carga.
415Usa un formato de imagen o vídeo compatible con bytes válidos.
416Comprueba que el rango de bytes solicitado esté dentro del archivo.
429Espacia 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.
500Reintenta 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