Valorado con 5,0 sobre 5 en G2
Referencia de API
HummingDeck expone una API REST para socios de integración y plataformas de automatización. Los endpoints se autentican con un Bearer token y devuelven respuestas JSON.
https://app.hummingdeck.com/api/v1Autenticación
Cada petición a la API lleva un Bearer token en la cabecera Authorization. Se aceptan dos tipos de credencial, y se comportan de forma distinta.
Método
Bearer token
Formato del encabezado
Authorization: Bearer {access_token}
Tipos de credencial
Token de API del espacio de trabajo
Authorization: Bearer hd_api_...
El acceso a la API REST está disponible previa solicitud con el plan Business y se habilita por espacio de trabajo tras una revisión. Después, los propietarios y administradores crean claves de API con nombres independientes en Configuración del espacio, Integraciones, HummingDeck API. Selecciona solo los permisos que necesita cada integración. La clave se muestra una sola vez al crearla y después no se puede recuperar. Caduca al año y permanece vinculada a su espacio de trabajo, por lo que una petición no puede elegir ni cambiar el espacio.
Un espacio de trabajo puede tener hasta 20 claves de API activas. Al reemplazar una clave, solo su secreto anterior deja de funcionar de inmediato; las demás claves siguen funcionando. Los propietarios y administradores pueden desactivar una clave o todas en cualquier momento. La revocación de ese secreto es permanente.
Una clave de API del espacio de trabajo solo puede ejecutar las operaciones permitidas por los permisos seleccionados. Los endpoints de suscripción a webhooks no están disponibles para estas claves.
Zapier OAuth
Authorization: Bearer {access_token}
Se emite mediante el flujo de autorización OAuth cuando un espacio de trabajo conecta la integración de Zapier. Los tokens de acceso caducan a los 30 días. Usa el token de actualización, que dura 90 días, para obtener uno nuevo sin volver a autorizar.
Es la única credencial que puede crear o eliminar suscripciones a webhooks.
Permisos
Elige al menos un permiso. Los permisos de escritura también incluyen el acceso de lectura correspondiente. Puedes cambiar los permisos cuando reemplaces la clave.
rooms:readVer salas, pestañas, elementos, enlaces y etiquetas.
rooms:writeCrear y gestionar salas, pestañas, elementos, enlaces y etiquetas.
plan:readVer fases y tareas del plan de acción mutuo.
plan:writeCrear y gestionar fases y tareas del plan de acción mutuo.
analytics:readVer análisis de interacción, actividad y correos capturados.
crm:readBuscar empresas y contactos del espacio de trabajo.
crm:writeCrear o actualizar empresas, contactos y públicos de enlaces.
documents:readBuscar documentos y consultar sus metadatos.
documents:writeSubir documentos y adjuntar documentos o URL a salas.
Las etiquetas de permisos en las filas de endpoints se aplican a las claves de API del espacio de trabajo. Los permisos requeridos se aplican siempre, los adicionales se necesitan a la vez y los condicionales solo cuando la solicitud usa los filtros o campos relacionados. GET /me no necesita permisos. Zapier OAuth usa su acceso fijo de integración.
Cuando una petición devuelve 401
Una petición devuelve 401 si la clave es desconocida o incorrecta, ha caducado, se ha desactivado, pertenece a un espacio de trabajo cuyo acceso a la API se desactivó o fue emitida por alguien que ya no es propietario ni administrador de ese espacio.
Prueba tu conexión
Verifica que tu token es válido y consulta el perfil del usuario autenticado.
/meDevuelve el nombre, el correo electrónico y la información del equipo del usuario actual.
No requiere permisos de clave de API
Documentos
Sube, busca y gestiona documentos (PDFs, presentaciones, propuestas y otros archivos).
/decksSube un nuevo documento. Envíalo como multipart/form-data con un campo file (PDF, PPTX, DOCX, XLSX, XLS, HTML) y un campo title. El límite de carga de la API es de 30 MB. El procesamiento continúa después de la carga; la respuesta incluye processingStatus.
documents:write/decksLista hasta 20 documentos, primero los más recientes. Usa el parámetro de consulta opcional title para filtrar por una parte del título sin distinguir mayúsculas de minúsculas.
documents:readGET /decks Campos de respuesta
| Field | Type | Description |
|---|---|---|
| id | string | ID del documento |
| title | string | Título del documento |
| fileType | string | Tipo MIME del documento |
| pageCount | integer | null | Número de páginas |
| thumbnailUrl | string | null | URL de la imagen en miniatura |
| processingStatus | string | pending, processing, completed o failed. Un documento puede añadirse a una sala mientras se procesa; envía un enlace a él cuando indique completed. |
| processingErrorCode | string | null | Motivo por el que falló el procesamiento, si falló |
| createdAt | string | Marca de tiempo ISO 8601 |
POST /decks Campos de respuesta
| Field | Type | Description |
|---|---|---|
| id | string | ID del documento |
| title | string | Título del documento |
| fileType | string | Tipo MIME del documento |
| processingStatus | string | pending, processing, completed o failed. Un documento puede añadirse a una sala mientras se procesa; envía un enlace a él cuando indique completed. |
| processingErrorCode | string | null | Motivo por el que falló el procesamiento, si falló |
Salas
Crea salas de negociación con sus documentos y su enlace de audiencia en una sola llamada, busca salas, cambia su configuración, archívalas y restáuralas, y organiza sus pestañas y elementos. Solo está disponible con tokens de API del espacio de trabajo; las credenciales OAuth de Zapier se rechazan.
/roomsLista las salas, de la más reciente a la más antigua. Filtra con search, status (active, archived o all) y companyId. Cada página contiene 25 salas (hasta 100 con limit); pasa el nextCursor de una página como cursor para obtener la siguiente.
rooms:readcrm:read(Required when the companyId filter is present.)/roomsCrea una sala con sus documentos y su primer enlace de audiencia en una sola llamada.
rooms:writedocuments:write(Required when documentIds contains one or more document IDs.)crm:write(Required when the request supplies contactId, recipientName, recipientEmail, companyId, companyName, or when either primaryLink.allowedEmails or primaryLink.allowedDomains is non-empty.)/rooms/{roomId}Devuelve la configuración de la sala, sus pestañas y elementos en el orden de visualización, y el número de enlaces.
rooms:read/rooms/{roomId}Cambia el nombre, el mensaje de bienvenida, la persona de contacto, la empresa o el contacto.
rooms:writecrm:write(Required when companyId or contactId is present, including null to detach the association.)/rooms/{roomId}/archiveArchiva la sala. Sus enlaces dejan de funcionar.
rooms:write/rooms/{roomId}/restoreRestaura una sala archivada. Sus enlaces vuelven a funcionar.
rooms:write/rooms/{roomId}/tabsAñade una pestaña, en una posición concreta o al final.
rooms:write/rooms/{roomId}/tabs/{tabId}Cambia el nombre de una pestaña.
rooms:write/rooms/{roomId}/tabs/orderCambia el orden de todas las pestañas.
rooms:write/rooms/{roomId}/tabs/{tabId}Elimina una pestaña que no muestra elementos.
rooms:write/rooms/{roomId}/itemsAñade a una pestaña un documento, una URL, un contenido incrustado o un separador de sección.
rooms:writedocuments:write(Required when type is document or url.)/rooms/{roomId}/items/{itemId}/moveMueve un elemento al final de otra pestaña.
rooms:write/rooms/{roomId}/items/orderCambia el orden de los elementos de una pestaña.
rooms:write/rooms/{roomId}/items/{itemId}Saca un elemento de la sala. Sigue en tu biblioteca.
rooms:write/rooms/{roomId}/linksLista los enlaces de audiencia de la sala, los más recientes primero, con los invitados activos de cada enlace restringido.
rooms:read/rooms/{roomId}/linksCrea un enlace abierto con atribución para una sala activa.
rooms:writecrm:write/rooms/{roomId}/links/{linkId}Activa o desactiva un enlace, define o borra su caducidad, o reemplaza su lista de acceso.
rooms:writecrm:write(Required when allowedEmails or allowedDomains is present, including an empty array that clears the audience.)/rooms/{roomId}/action-planDevuelve el plan de acción de la sala: sus ajustes, fases, tareas (incluidas las internas), dependencias y progreso.
plan:read/rooms/{roomId}/action-planCambia los ajustes del plan, incluido si quienes abren la sala pueden marcar sus propias tareas.
plan:write/rooms/{roomId}/action-plan/phasesAñade un hito. Si omites color, las fases alternan turquesa, melocotón y azul por orden.
plan:write/rooms/{roomId}/action-plan/phases/{phaseId}Renombra una fase, la mueve, cambia su fecha o define su color. Enviar color null restaura la rotación.
plan:write/rooms/{roomId}/action-plan/phases/{phaseId}Elimina una fase. mode es obligatorio: delete_tasks o move_to_unphased, para que ninguna tarea desaparezca por accidente.
plan:write/rooms/{roomId}/action-plan/tasksAñade una tarea. assignee es null, un side solo para la empresa responsable, o un side con email para una persona concreta.
plan:write/rooms/{roomId}/action-plan/tasks/{taskId}Actualiza una tarea. Si omites assignee, la responsabilidad no cambia; enviar null la borra.
plan:write/rooms/{roomId}/action-plan/tasks/{taskId}Elimina una tarea. Sus subtareas se van con ella.
plan:write/rooms/{roomId}/action-plan/tasks/{taskId}/statusCompleta o reabre una tarea en nombre del espacio de trabajo. Una tarea con una dependencia sin terminar devuelve 409 TASK_BLOCKED.
plan:write/rooms/{roomId}/analyticsVisitas a la sala, espectadores únicos, tiempo medio, documentos abiertos del total y finalización media. Sin bots.
analytics:read/rooms/{roomId}/activityLo que ocurrió en la sala, lo más reciente primero. Las entradas de conversación nombran a quien escribió y nunca incluyen el mensaje. Acota con since.
analytics:read/rooms/{roomId}/captured-emailsDirecciones que recogió la sala. source es verify si la persona la confirmó con un enlace de un solo uso, y ask si solo la escribió.
analytics:read/room-viewsEntradas a salas en todo el espacio de trabajo, las más recientes primero. No hay otra fuente para saber que alguien entró; /views solo cubre vistas de documentos.
analytics:read/room-labelsLista las etiquetas de sala del espacio de trabajo con cuántas salas usa cada una. Aquí encuentras los IDs antes de etiquetar una sala.
rooms:read/room-labelsCrea una etiqueta. Los nombres son únicos por espacio de trabajo, sin distinguir mayúsculas; color es un valor hexadecimal #RRGGBB.
rooms:write/room-labels/{labelId}Renombra una etiqueta, cambia su color o edita su descripción.
rooms:write/room-labels/{labelId}Elimina una etiqueta y sus asignaciones. Las salas que la llevaban no cambian; la respuesta indica cuántas la perdieron.
rooms:writeCrear una sala en una sola llamada
Sube cada archivo con POST /decks y luego crea la sala para la empresa del destinatario con un enlace restringido para las personas que deben verla. La empresa, los contactos, la sala, los documentos y el enlace se crean a la vez: si se rechaza la llamada, no se crea nada. Los documentos pueden añadirse a la sala mientras se siguen procesando. Los elementos de la sala indican processingStatus, así que envía el enlace cuando todos los documentos indiquen completed.
{
"name": "Acme renewal",
"companyName": "Acme Inc",
"recipientName": "Pat Buyer",
"recipientEmail": "pat@acme.example",
"documentIds": [
"{documentId}",
"{documentId}"
],
"primaryLink": {
"accessMode": "verified-allowlist",
"allowedEmails": [
"pat@acme.example",
{
"email": "cfo@acme.example",
"name": "Sam Rivera"
}
],
"allowedDomains": [
"acme.example"
]
}
}accessMode es open (cualquiera con la URL), verify-any (los visitantes confirman su correo con un enlace de un solo uso) o verified-allowlist (solo las direcciones de allowedEmails y cualquier persona de los dominios de allowedDomains). La API no añade a nadie por su cuenta a un enlace restringido, así que incluye tu propia dirección si quieres ver la sala antes. Una opción que tu plan no incluye devuelve 403 FEATURE_NOT_AVAILABLE, y un campo desconocido devuelve 400, de modo que una sala nunca se abre a una audiencia distinta de la que pediste.
Organizar pestañas y elementos
Parte del estado actual de la sala: al leer una sala se obtienen sus pestañas y elementos en el orden de visualización, y cada elemento indica su pestaña y su posición en ella, empezando por 0. Añade pestañas y elementos en una posición, mueve elementos entre pestañas y envía el nuevo orden completo de una pestaña. Un orden debe incluir cada elemento de la pestaña exactamente una vez, así que vuelve a leer la sala si mientras tanto se produjo otro cambio. Una pestaña se puede eliminar cuando ya no muestra elementos.
{
"type": "section",
"label": "Commercials",
"tabId": "{tabId}",
"position": 0
}Proveedores de inserción admitidos
Los embeds aceptan un enlace para compartir o un enlace de inserción y lo normalizan a la forma de inserción del proveedor. Cualquier cosa fuera de este conjunto devuelve 400 EMBED_PROVIDER_NOT_SUPPORTED.
| Field | Type | Description |
|---|---|---|
| Vídeo | Loom, YouTube, Vimeo, Wistia, Vidyard | |
| Agendamiento | Calendly, Cal.com, SavvyCal, Google Calendar | |
| Formularios | Typeform, Tally, Google Forms, Jotform, Fillout | |
| Diseño | Figma, Miro, Canva, Whimsical | |
| Documentos y tablas | Google Docs, Google Sheets, Notion, Coda, Airtable | |
| Presentaciones | Google Slides, Pitch, Gamma, Guideflow, Flipsnack, Prezi | |
| Audio | Spotify, SoundCloud |
Añadir otro enlace de audiencia
Cada sala ya tiene un enlace creado por POST /rooms; añade más para audiencias que necesiten otra atribución u otro acceso. Indica al menos uno de recipientName, recipientEmail, contactId, companyId o companyName. accessMode admite los mismos valores open, verify-any o verified-allowlist que primaryLink, con los mismos campos (requireEmail, allowedEmails, allowedDomains, label, expiresAt, allowDownloads). Una llamada rechazada, incluso por un límite del plan, no deja ningún enlace, empresa ni contacto.
{
"companyName": "Analytical Engines",
"accessMode": "verified-allowlist",
"allowedEmails": [
{
"email": "cfo@analytical.example",
"name": "Sam Rivera"
}
]
}Actualizar un enlace
Cuatro campos: isActive, expiresAt, allowedEmails y allowedDomains (los dos últimos solo en enlaces verified-allowlist). accessMode y el slug nunca cambian; crea un enlace nuevo en su lugar. Reactivar un enlace vuelve a comprobar el límite de enlaces activos del plan.
{
"isActive": false
}Construir el plan de acción
Cada sala tiene exactamente un plan, así que cuelga de la sala sin identificador propio. La mayoría de las tareas pertenecen a una empresa y no a una persona: si envías solo un side, el plan lo interpreta como la empresa, que es lo que quieres cuando no sabes quién hará el trabajo al otro lado. Añade un email solo cuando conozcas a la persona. Una tarea interna nunca se ve en la sala, así que no puede pertenecer al destinatario.
{
"title": "Sign the NDA",
"assignee": {
"side": "buyer"
},
"dueDate": "2026-10-02"
}recipientCompletionEnabled en el plan decide si quienes abren la sala pueden marcar las tareas de su lado. Por defecto es true y es la única barrera: la API nunca pide la dirección de un destinatario para completar una tarea. Quién marcó cada una se registra con la certeza que dé el modo de acceso de la sala.
Etiquetar salas
Las etiquetas son de todo el espacio de trabajo: créalas una vez y reutilízalas. Envía labelIds en POST /rooms para etiquetar una sala al crearla, o en PATCH /rooms/{roomId} para reemplazar el conjunto completo; un array vacío quita todas las etiquetas y omitir el campo las deja intactas. Una sala lleva como máximo cinco, algo estructural y no una preferencia. Al leer una sala se devuelven sus etiquetas.
{
"labelIds": [
"{labelId}"
]
}Saber qué ocurrió
Consulta /room-views para ver las entradas de todo el espacio de trabajo y luego lee las analíticas, la actividad y las direcciones capturadas de una sala. Pasa el nextCursor de una página como cursor para continuar; un cursor que esta API no emitió devuelve 400 en lugar de empezar de nuevo, así un consultor periódico no repite trabajo. Usa since para acotar el periodo de actividad y cursor para recorrer sus páginas. /room-views es una ventana, no un archivo histórico: sin since obtienes los últimos 30 días, y más de 90 días atrás se rechaza. La ventana aplicada vuelve como since; envíala junto a cursor para seguir paginando el mismo conjunto.
Empresas y contactos
Busca registros de cuenta existentes o créalos con coincidencias deterministas. Los nombres de empresa y los correos de contacto no distinguen mayúsculas de minúsculas.
/companies?name={name}&domain={domain}Busca hasta 10 empresas por nombre exacto, dominio o ambos.
crm:read/companiesBusca una empresa por nombre sin distinguir mayúsculas de minúsculas o la crea. Un dominio explícito solo completa el registro. El campo created identifica el resultado.
crm:write/contacts?email={query}Busca contactos por dirección de correo electrónico. Devuelve contactos coincidentes con su empresa asociada.
crm:read/contactsBusca un contacto por correo o lo crea, con una empresa existente o nueva opcional.
crm:writeSolicitud POST /companies
| Field | Type | Description | |
|---|---|---|---|
| name | string | obligatorio | Nombre de la empresa |
| domain | string | opcional | Dominio de la empresa para completar datos. Nunca se usa para buscar una empresa existente |
Solicitud POST /contacts
| Field | Type | Description | |
|---|---|---|---|
| name | string | condicional | Nombre completo. Usa este campo o firstName y lastName |
| firstName | string | condicional | Nombre cuando no se proporciona name |
| lastName | string | opcional | Apellido cuando se usa firstName |
| string | obligatorio | Correo usado para buscar sin distinguir mayúsculas de minúsculas | |
| title | string | opcional | Cargo |
| companyId | UUID | opcional | Empresa existente en el espacio de trabajo autenticado |
| companyName | string | opcional | Empresa que se buscará o creará si no se proporciona companyId |
| companyDomain | string | opcional | Dominio opcional para completar datos con companyName. No se usa como criterio de búsqueda |
Respuesta de empresa
| Field | Type | Description |
|---|---|---|
| company.id | UUID | ID de la empresa |
| company.name | string | Nombre de la empresa |
| company.domain | string | null | Dominio normalizado de la empresa |
| created | boolean | Indica si esta solicitud ha creado la empresa |
Respuesta de contacto
| Field | Type | Description |
|---|---|---|
| contact.id | UUID | ID del contacto |
| contact.firstName | string | Nombre |
| contact.lastName | string | Apellido |
| contact.email | string | Dirección de correo electrónico |
| contact.title | string | null | Cargo |
| contact.companyId | UUID | null | ID de la empresa asociada |
| contact.companyName | string | null | Nombre de la empresa asociada |
| created | boolean | Indica si esta solicitud ha creado el contacto |
| company | object | null | Empresa resuelta, si está disponible |
| companyCreated | boolean | Indica si esta solicitud ha creado la empresa |
Webhooks
Suscríbete a eventos en tiempo real mediante REST Hooks. Cuando ocurre un evento, HummingDeck envía una solicitud POST a tu URL HTTPS registrada con el payload del evento. Las entregas fallidas se reintentan hasta 3 veces (a intervalos de 1 s, 5 s y 30 s). Las suscripciones a webhooks las gestiona la integración de Zapier y no están disponibles para los tokens de API del espacio de trabajo.
/hooksSuscribirse a un evento. Requiere una URL HTTPS de destino y un tipo de evento. Devuelve un ID de suscripción.
Solo Zapier OAuth
/hooks/{id}Cancelar la suscripción a un evento por ID de suscripción.
Solo Zapier OAuth
Tipos de eventos
| Event | Description |
|---|---|
| view.created | Una persona real vio un documento compartido. El tráfico de bots (escáneres de seguridad de correo electrónico, rastreadores) se filtra automáticamente. |
| decision.made | Un prospecto respondió a una propuesta: aceptada, rechazada o con cambios solicitados. |
| email_captured | Un visitante introdujo su dirección de correo electrónico para acceder a contenido protegido. |
Ejemplos de payloads
view.created
{
"event": "view.created",
"data": {
"id": "view_abc123",
"deck_id": "deck_xyz789",
"deck_title": "Q4 Enterprise Proposal",
"viewer_email": "sarah@acme.com",
"viewer_name": "Sarah Wood",
"viewer_company": "Acme Corp",
"location": "San Francisco, CA",
"device": "Desktop",
"browser": "Chrome",
"pages_viewed": 8,
"total_pages": 12,
"duration_seconds": 272,
"completion_percent": 67,
"created_at": "2026-03-29T14:32:00Z"
}
}decision.made
{
"event": "decision.made",
"data": {
"share_slug": "proposal-2024",
"decision": "accepted",
"deck_title": "Q4 Enterprise Proposal",
"viewer_email": "sarah@acme.com",
"viewer_name": "Sarah Wood",
"decision_note": "Approved pending final review",
"decided_at": "2026-03-29T15:30:00Z"
}
}email_captured
{
"event": "email_captured",
"data": {
"email": "prospect@company.com",
"share_slug": "proposal-2024",
"deck_title": "Q4 Enterprise Proposal",
"view_id": "view_xyz789",
"captured_at": "2026-03-29T14:35:00Z"
}
}Vistas y eventos
Endpoints de sondeo para recuperar datos de interacción recientes. Devuelven los mismos datos que entregan los webhooks en tiempo real. Úsalos para rellenar histórico, hacer pruebas o como alternativa.
/viewsListar las 100 visualizaciones de documentos más recientes. Las sesiones de bots están excluidas.
analytics:read/decisionsListar las decisiones recientes sobre propuestas (aceptadas, rechazadas, cambios solicitados).
analytics:read/emailsListar las capturas de correo electrónico recientes de contenido protegido.
analytics:readManejo de errores
Cada error devuelve un objeto JSON con un campo error que describe qué ha fallado. La mayoría de las respuestas incluyen además un campo code para el tratamiento programático, como PLAN_LIMIT_REACHED, FEATURE_NOT_AVAILABLE, ROOM_NOT_ACTIVE, TAB_NOT_EMPTY, INVALID_FORMAT o FILE_TOO_LARGE. Los códigos de estado HTTP siguen las convenciones habituales.
| Status | Meaning |
|---|---|
| 400 | Solicitud incorrecta: parámetros faltantes o inválidos |
| 401 | No autorizado: Bearer token inválido o expirado |
| 403 | Prohibido: la credencial no tiene un scope necesario, se ha alcanzado un límite del plan, el plan no incluye una opción necesaria, o este tipo de credencial no está permitido en este endpoint |
| 404 | No encontrado: el recurso no existe o no pertenece a tu equipo |
| 409 | Conflicto: los identificadores proporcionados no coinciden, la sala está archivada, o las pestañas de la sala no permiten el cambio |
| 413 | Carga demasiado grande: el cuerpo de la solicitud o el archivo supera el límite de este endpoint |
| 429 | Demasiadas solicitudes: la clave o la IP cliente superó su límite actual; reinténtalo tras el plazo indicado en Retry-After |
| 500 | Error del servidor: reintenta la solicitud |
Límites de velocidad
Las claves manuales del espacio y las conexiones OAuth de Zapier tienen límites por credencial: 600 lecturas cada 5 minutos, 120 escrituras por minuto, 60 solicitudes a /room-views por minuto y 20 subidas por hora. En el conjunto de todas las credenciales, cada espacio admite 1.200 lecturas cada 5 minutos, 240 escrituras por minuto, 120 solicitudes a /room-views por minuto y 40 subidas por hora. Los fallos de autenticación Bearer y la autenticación no válida del cliente OAuth se limitan por separado a 60 intentos cada 5 minutos por IP cliente. Máximo 50 suscripciones de webhook activas por equipo.
Esta API es utilizada actualmente por nuestra integración con Zapier. Es posible que en el futuro se admitan plataformas de integración adicionales.