Built for trustTLS encryptionGDPR-readyGoogle CloudSecure paymentsSecurity overview
G2

Rated 5.0 out of 5 on G2

Read the reviews on G2
The page-level analytics are the best part because they show real engagement instead of just basic opens.
Verified User in Computer Software
What I like most about the product is how easy it is to use, especially when it comes to listing all my links and embedding demos in one place for leads and prospects.
Jerome K.Founder
Responsiveness, configurability and development velocity.
Suman K.Co-Founder & CEO

API Reference

HummingDeck exposes a REST API for integration partners and automation platforms. Endpoints authenticate with a Bearer token and return JSON responses.

Base URLhttps://app.hummingdeck.com/api/v1
OpenAPI Spec

Authentication

Every API request carries a Bearer token in the Authorization header. Two kinds of credential are accepted, and they behave differently.

Method

Bearer token

Header format

Authorization: Bearer {access_token}

Credential types

Workspace API token

Authorization: Bearer hd_api_...

Issued by a workspace owner from Workspace settings, Integrations, HummingDeck API. REST API access is available by request on Business and is enabled per workspace after review. The token is shown once when it is created and cannot be retrieved afterwards. It expires one year after creation and is bound permanently to the workspace it was issued for, so a request cannot select or override its workspace.

Creating a token when one already exists replaces it, and the previous token stops working immediately. An owner can switch a token off at any time. That is permanent for that token: create a new one rather than expecting to restore it.

Webhook subscription endpoints are not available to workspace API tokens.

Zapier OAuth

Authorization: Bearer {access_token}

Issued through the OAuth authorization flow when a workspace connects the Zapier integration. Access tokens expire after 30 days. Use the refresh token, which lasts 90 days, to obtain a new access token without re-authorizing.

This is the only credential that can create or delete webhook subscriptions.

When a request returns 401

A request is rejected with 401 when the token is unknown or malformed, has expired, has been switched off, belongs to a workspace whose API access was turned off, or was issued by someone who is no longer that workspace's owner.

Test your connection

Verify your token is valid and see the authenticated user's profile.

GET/meReturns the current user's name, email, and team information.

Documents

Upload, search, and manage documents (PDFs, slide decks, proposals, and other files).

POST/decksUpload a new document. Send as multipart/form-data with a file field (PDF, PPTX, DOCX, XLSX, XLS, HTML) and a title field. The API upload limit is 30 MB.
GET/decks?title={query}Search documents by title. Case-insensitive, returns up to 20 matches.

Response fields

FieldTypeDescription
idstringDocument ID
titlestringDocument title
fileTypestringFile type (pdf, pptx, docx, html)
pageCountnumberNumber of pages
thumbnailUrlstringThumbnail image URL
createdAtstringISO 8601 timestamp

Share Links

Create trackable document links. A personal link can resolve or create its contact and company in the same request.

POST/sharesCreate a personal or anonymous link. Personal links can find or create account records automatically.

Request fields

FieldTypeDescription
deckIdstringrequiredID of the document to share
recipientNamestringoptionalRecipient's name (for personal links)
recipientEmailstringoptionalRecipient's email (for personal links)
contactIdUUIDoptionalExisting contact in the authenticated workspace
companyIdUUIDoptionalExisting company. Cannot be combined with companyName
companyNamestringoptionalCompany to find by name or create
companyDomainstringoptionalDomain stored for enrichment when companyName is supplied. Never used to select a company
typestringoptionalDefaults to personal when recipient or account fields are present, otherwise anonymous

Create the link and account records together

Send recipient and company details directly to /shares. HummingDeck finds matching records, creates any that are missing, attaches them to the link, and reports what was created. Set type to anonymous explicitly to skip account creation.

{
  "deckId": "8f3d41de-2bb8-4d8e-80de-6cd2072ffab1",
  "recipientName": "Ada Lovelace",
  "recipientEmail": "ada@analytical.example",
  "companyName": "Analytical Engines",
  "companyDomain": "analytical.example"
}

Response fields

FieldTypeDescription
idstringShare ID
slugstringShare slug (used in the URL)
shareUrlstringFull trackable URL
typestring"personal" or "anonymous"
recipientNamestringRecipient name (if personal)
recipientEmailstringRecipient email (if personal)
contactobject | nullResolved contact attached to the link
contactCreatedbooleanWhether this request created the contact
companyobject | nullResolved company attached to the link
companyCreatedbooleanWhether this request created the company
createdAtstringISO 8601 timestamp

Rooms

Retrieve room structure and create trackable room audience links. Available only to workspace API tokens; Zapier OAuth credentials are rejected.

GET/rooms/{roomId}Returns room metadata, tabs, content items, and active/total link counts.
POST/rooms/{roomId}/linksCreates an attributed Open link for an active room.

Create an Open room link

Provide at least one of recipientName, recipientEmail, contactId, companyId, or companyName. Name/email fields resolve or create a contact; company fields resolve or create a company. Open means anyone with the URL can view the room.

{
  "accessMode": "open",
  "recipientName": "Ada Lovelace",
  "recipientEmail": "ada@analytical.example",
  "companyName": "Analytical Engines"
}

Companies & Contacts

Find existing account records or create them with deterministic matching. Company names and contact emails are matched case-insensitively.

GET/companies?name={name}&domain={domain}Find up to 10 companies by exact name, domain, or both.
POST/companiesFind a company by case-insensitive name, or create it. An explicit domain only enriches the record. Returns created to identify the outcome.
GET/contacts?email={query}Search contacts by email address. Returns matching contacts with their associated company.
POST/contactsFind a contact by email or create it, with an optional existing or new company.

POST /companies request

FieldTypeDescription
namestringrequiredCompany name
domainstringoptionalCompany domain used for enrichment. Never used to match an existing company

POST /contacts request

FieldTypeDescription
namestringconditionalFull name. Use this or firstName and lastName
firstNamestringconditionalFirst name when name is not supplied
lastNamestringoptionalLast name when using firstName
emailstringrequiredEmail used for case-insensitive matching
titlestringoptionalJob title
companyIdUUIDoptionalExisting company in the authenticated workspace
companyNamestringoptionalCompany to find or create when companyId is not supplied
companyDomainstringoptionalOptional enrichment domain used with companyName. Not a company match key

Company response

FieldTypeDescription
company.idUUIDCompany ID
company.namestringCompany name
company.domainstring | nullNormalized company domain
createdbooleanWhether this request created the company

Contact response

FieldTypeDescription
contact.idUUIDContact ID
contact.firstNamestringFirst name
contact.lastNamestringLast name
contact.emailstringEmail address
contact.titlestring | nullJob title
contact.companyIdUUID | nullAssociated company ID
contact.companyNamestring | nullAssociated company name
createdbooleanWhether this request created the contact
companyobject | nullResolved company, when available
companyCreatedbooleanWhether this request created the company

Webhooks

Subscribe to real-time events via REST Hooks. When an event occurs, HummingDeck sends a POST request to your registered HTTPS URL with the event payload. Failed deliveries are retried up to 3 times (at 1s, 5s, and 30s intervals). Webhook subscriptions are managed by the Zapier integration and are not available to workspace API tokens.

POST/hooksSubscribe to an event. Requires a target HTTPS URL and an event type. Returns a subscription ID.
DELETE/hooks/{id}Unsubscribe from an event by subscription ID.

Event types

EventDescription
view.createdA real person viewed a shared document. Bot traffic (email security scanners, crawlers) is filtered automatically.
decision.madeA prospect responded to a proposal: accepted, declined, or requested changes.
email_capturedA viewer entered their email address to access gated content.

Example 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"
  }
}

Views & Events

Polling endpoints for retrieving recent engagement data. These return the same data that webhooks deliver in real time. Use them for backfilling, testing, or as a fallback.

GET/viewsList the most recent 100 document views. Bot sessions are excluded.
GET/decisionsList recent proposal decisions (accepted, declined, changes requested).
GET/emailsList recent email captures from gated content.

Error handling

Every error returns a JSON object with an error field describing what went wrong. Some responses also include a code field for programmatic handling, such as PLAN_LIMIT_REACHED, INVALID_FORMAT, or FILE_TOO_LARGE. HTTP status codes follow standard conventions.

StatusMeaning
400Bad request: missing or invalid parameters
401Unauthorized: invalid or expired Bearer token
403Forbidden: plan limit reached, or this credential type is not allowed on this endpoint
404Not found: resource does not exist or is not owned by your team
409Conflict: the supplied contact, email, and company identifiers do not agree
500Server error: retry the request

Rate limits

Maximum 50 active webhook subscriptions per team. API requests are not rate-limited but excessive use may be throttled.

This API is currently used by our Zapier integration. Additional integration platforms may be supported in the future.