Rated 5.0 out of 5 on G2
API Reference
HummingDeck exposes a REST API for integration partners and automation platforms. Endpoints authenticate with a Bearer token and return JSON responses.
https://app.hummingdeck.com/api/v1Authentication
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.
/meReturns the current user's name, email, and team information.Documents
Upload, search, and manage documents (PDFs, slide decks, proposals, and other files).
/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./decks?title={query}Search documents by title. Case-insensitive, returns up to 20 matches.Response fields
| Field | Type | Description |
|---|---|---|
| id | string | Document ID |
| title | string | Document title |
| fileType | string | File type (pdf, pptx, docx, html) |
| pageCount | number | Number of pages |
| thumbnailUrl | string | Thumbnail image URL |
| createdAt | string | ISO 8601 timestamp |
Rooms
Retrieve room structure and create trackable room audience links. Available only to workspace API tokens; Zapier OAuth credentials are rejected.
/rooms/{roomId}Returns room metadata, tabs, content items, and active/total link counts./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.
/companies?name={name}&domain={domain}Find up to 10 companies by exact name, domain, or both./companiesFind a company by case-insensitive name, or create it. An explicit domain only enriches the record. Returns created to identify the outcome./contacts?email={query}Search contacts by email address. Returns matching contacts with their associated company./contactsFind a contact by email or create it, with an optional existing or new company.POST /companies request
| Field | Type | Description | |
|---|---|---|---|
| name | string | required | Company name |
| domain | string | optional | Company domain used for enrichment. Never used to match an existing company |
POST /contacts request
| Field | Type | Description | |
|---|---|---|---|
| name | string | conditional | Full name. Use this or firstName and lastName |
| firstName | string | conditional | First name when name is not supplied |
| lastName | string | optional | Last name when using firstName |
| string | required | Email used for case-insensitive matching | |
| title | string | optional | Job title |
| companyId | UUID | optional | Existing company in the authenticated workspace |
| companyName | string | optional | Company to find or create when companyId is not supplied |
| companyDomain | string | optional | Optional enrichment domain used with companyName. Not a company match key |
Company response
| Field | Type | Description |
|---|---|---|
| company.id | UUID | Company ID |
| company.name | string | Company name |
| company.domain | string | null | Normalized company domain |
| created | boolean | Whether this request created the company |
Contact response
| Field | Type | Description |
|---|---|---|
| contact.id | UUID | Contact ID |
| contact.firstName | string | First name |
| contact.lastName | string | Last name |
| contact.email | string | Email address |
| contact.title | string | null | Job title |
| contact.companyId | UUID | null | Associated company ID |
| contact.companyName | string | null | Associated company name |
| created | boolean | Whether this request created the contact |
| company | object | null | Resolved company, when available |
| companyCreated | boolean | Whether 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.
/hooksSubscribe to an event. Requires a target HTTPS URL and an event type. Returns a subscription ID./hooks/{id}Unsubscribe from an event by subscription ID.Event types
| Event | Description |
|---|---|
| view.created | A real person viewed a shared document. Bot traffic (email security scanners, crawlers) is filtered automatically. |
| decision.made | A prospect responded to a proposal: accepted, declined, or requested changes. |
| email_captured | A 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.
/viewsList the most recent 100 document views. Bot sessions are excluded./decisionsList recent proposal decisions (accepted, declined, changes requested)./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.
| Status | Meaning |
|---|---|
| 400 | Bad request: missing or invalid parameters |
| 401 | Unauthorized: invalid or expired Bearer token |
| 403 | Forbidden: plan limit reached, or this credential type is not allowed on this endpoint |
| 404 | Not found: resource does not exist or is not owned by your team |
| 409 | Conflict: the supplied contact, email, and company identifiers do not agree |
| 500 | Server 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.