Iniciar upload: obtener signed URL
Paso 1 del patrón 2-step. Valida mime_type + size_bytes + cuota del business, reserva una fila pending en business_files y devuelve un signed URL con TTL de 5 minutos.
Flujo completo
Paso 1 — Este endpoint
Declara la metadata del archivo y recibe el signed URL.
Paso 2 — PUT directo a Supabase (NO es un endpoint nuestro)
El cliente sube el binario directo a Storage. El server nunca ve el binario. El Content-Type del PUT debe estar en el catálogo permitido del bucket (si no, Storage responde 400). En /confirm el server lee los magic bytes del blob ya subido y los compara contra el mime_type declarado en el paso 1 (persistido en DB): si los magic bytes no corresponden a ese mime_type, la confirmación falla con MIME_MISMATCH.
curl:
curl -X PUT "<upload_url del paso 1>" \
-H "Content-Type: application/pdf" \
--data-binary "@./invoice.pdf"
JavaScript (Node 20+ / browser):
await fetch(uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'application/pdf' },
body: file, // File object del input o ReadStream
})
n8n: nodo HTTP Request con method PUT, URL del paso 1, Body Type “Binary”, field del nodo “Read Binary File” anterior.
Paso 3 — POST /files/confirm
Tras completar el PUT, llama a /files/confirm con el file_uuid para validar el binario y recibir un signed URL de descarga usable en mensajes.
Cómo obtener mime_type y size_bytes
La metadata debe declararse antes de subir. Si la herramienta no la expone:
- JS File API:
file.typeyfile.sizevienen gratis en un objetoFile. - Node fs:
fs.statSync(path).sizepara bytes;mime-typespackage para el MIME. - curl:
stat -c%s file(Linux) /stat -f%z file(macOS) /(Get-Item file).Length(PowerShell) para bytes.file --mime-type -b filepara MIME. - n8n: el nodo “Read Binary File” expone
binary.data.mimeTypeybinary.data.fileSize.
Autorizaciones
API token emitido desde Settings → API Token del dashboard 1TO1 AI. Enviar en header Authorization: Bearer sk_1to1_...
Parámetros de ruta
Slug del business, case-insensitive. Debe coincidir con el business del token.
"acme"
Cuerpo
Nombre original del archivo. Se preserva para mostrar al receptor final.
1 - 255"invoice.pdf"
MIME type del archivo. Stickers (image/webp) no se soportan en la API v1 — WhatsApp los maneja como tipo de mensaje aparte.
image/jpeg, image/png, video/mp4, video/3gpp, audio/ogg, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, text/plain "application/pdf"
Tamaño declarado en bytes. Se re-valida en /confirm.
1 <= x <= 104857600524288
Respuesta
Upload URL emitido. Continúa con PUT a upload_url y luego POST /files/confirm.
UUID generado por el server. Se usa en /confirm y al adjuntar en mensajes.
"550e8400-e29b-41d4-a716-446655440000"
Signed URL para hacer PUT con el binario directo a Supabase Storage. Expira en 5 minutos.
Token firmado opcional si el cliente usa el SDK de Supabase en vez de un PUT raw.
Path interno en el bucket. Informativo — el cliente solo debe usar upload_url.
Instante (UTC) en que upload_url deja de ser válido.
"2026-04-19T12:05:00.000Z"