Guide to Quickbase Webhooks: Features and Best Practices
Quickbase webhooks send an HTTP request when records in a table change. A new project is added, a ticket's status moves to Issue, an order is deleted: each can call a URL with a message you design, so you can keep another system in sync, notify a chat tool, or start a process in your own service the moment the data changes.
This guide covers how Quickbase table webhooks are triggered and built, how to authenticate them with a secret header, the markers that make a message useful to a receiver, and the limits that decide whether a message is sent at all.
What are Quickbase webhooks?
A Quickbase webhook belongs to one table. Its When section picks the trigger: a record added, modified or deleted, in any combination, optionally narrowed to changes in specific fields or to records whose field values match criteria after the change. Its Then section is the whole outgoing request: endpoint URL, HTTP method, message format, headers and body.
Because you write the request, Quickbase adds nothing of its own. There's no event field, no fixed schema and no signature. What arrives is the body you composed, with field references and markers replaced by values from the record.
That includes authentication. You add a secret header to the webhook's Message header list, and your receiver checks it.
Quickbase webhook features
| Feature | Details |
|---|---|
| Configuration | Table Settings > Workflow & Permissions > Webhooks > New Webhook, or API_Webhooks_Create |
| Who can create them | App admins and managers |
| Triggers | Record added, modified, deleted, with optional field and value criteria |
| Endpoint | Must begin with https:// |
| HTTP method | POST by default. Also GET, PUT, PATCH, DELETE |
| Message format | XML, JSON or RAW |
| Headers | Up to 10 name/value pairs |
| Body | Your template, with field references and markers. Sent as UTF-8 |
| Authentication | A secret header you add. No signature |
| Limits | 10 webhooks per table, 4 MB per message, 50 messages per second per app |
| Error reporting | 30-day error history, and email to the webhook owner |
| Retries and timeout | Not documented |
| Plans | All plans except Quickbase Essential |
Building the message
Quickbase gives you field references and markers to fill the body. Field references are field names in square brackets, such as [Status], and [old.status] gives the value before the change. Markers include:
| Marker | Inserts |
|---|---|
%action% | Add, Replace or Delete, depending on what triggered the webhook |
%webhookid% | The webhook's numeric ID |
%dbid%, %dbName% | The table's ID and name |
%appid%, %appName% | The app's ID and name |
%curuser% | The user who triggered the webhook |
%curdate% | When the webhook was triggered |
%reclink% | A link to the changed record |
%RepeatOn% ... %RepeatOff% | Repeated content for each record when one event changes several rows |
A JSON template for your own receiver might be:
{
"action": "%action%",
"webhook_id": "%webhookid%",
"table_id": "%dbid%",
"record_id": "[Record ID#]",
"status": "[Status]",
"previous_status": "[old.Status]",
"changed_at": "%curdate%"
}
Use the field names from your own table. %action% and %webhookid% together tell your receiver what happened and which webhook sent it. Grid edits, CSV imports, search-and-replace and table merges can change several records in one event; use %RepeatOn% and %RepeatOff% if you need every row.
Quickbase's documentation gives Content-Type: application/json as an example message header, so add it when you send JSON.
Inspect Quickbase webhooks as they arrive. Point a webhook at a Hookdeck Inspect URL to see the method, headers and rendered body your template produces, with no account or setup required.
Setting up Quickbase webhooks
Generate a long random value first, for example with openssl rand -hex 32.
- Open the table, select Settings, and under Workflow & Permissions select Webhooks.
- Select New Webhook and give it a Name and Description.
- Under When, choose added, modified and/or deleted, and any Additional criteria.
- Under Then, enter the Endpoint URL and choose the HTTP method (leave it on
POSTunless you need another). - Choose the Message format.
- Under Message header, add
Content-Typeif needed, and a secret header such asAuthorizationwith the valueBearer <your random value>. - Write the Message body, then select Save.
To route through Hookdeck, create a source with the Quickbase type and use its URL in step 4. Enter your secret header's name in API Key Header and its exact value, including any Bearer prefix, in API Key. Hookdeck finds the header case-insensitively and compares the whole value.
The Hookdeck source pre-selects POST but doesn't manage the method, because Quickbase lets you choose it. If your webhook uses PUT, PATCH, GET or DELETE, add that method to the source's allowed HTTP methods, or Hookdeck won't accept the request.
Securing Quickbase webhooks
Look up the header you added and compare its whole value with the stored secret, in constant time. Accept the methods your webhook uses, and don't assume there is a body: a GET or DELETE may have none.
const crypto = require('crypto');
const express = require('express');
const HEADER_NAME = (process.env.QUICKBASE_WEBHOOK_HEADER || 'authorization').toLowerCase();
const EXPECTED = process.env.QUICKBASE_WEBHOOK_SECRET; // e.g. "Bearer 3f9c..."
function safeEqual(received, expected) {
const a = Buffer.from(received, 'utf8');
const b = Buffer.from(expected, 'utf8');
// timingSafeEqual throws on unequal lengths, so check first.
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
const app = express();
// Quickbase lets each webhook choose its method, so accept the ones you configured.
app.all('/webhooks/quickbase', express.raw({ type: '*/*' }), (req, res) => {
if (!['POST', 'PUT', 'PATCH', 'GET', 'DELETE'].includes(req.method)) {
return res.sendStatus(405);
}
const received = req.get(HEADER_NAME);
if (!EXPECTED || typeof received !== 'string' || !safeEqual(received, EXPECTED)) {
return res.sendStatus(401);
}
const raw = Buffer.isBuffer(req.body) ? req.body.toString('utf8') : '';
// Parse raw as JSON or XML to match the webhook's message format, then queue it.
res.sendStatus(200);
});
The same check in Python:
import hmac
import os
HEADER_NAME = os.environ.get("QUICKBASE_WEBHOOK_HEADER", "Authorization")
EXPECTED = os.environ.get("QUICKBASE_WEBHOOK_SECRET", "")
def verify_quickbase_request(headers) -> bool:
if not EXPECTED:
return False # never accept when unconfigured
received = headers.get(HEADER_NAME) # most frameworks look headers up case-insensitively
if not received:
return False
# Compare bytes: compare_digest raises TypeError on a non-ASCII str.
return hmac.compare_digest(received.encode("utf-8"), EXPECTED.encode("utf-8"))
A secret header authenticates the sender, not the body. It cannot detect a modified message, and with no signature or timestamp a captured request can be replayed and still pass. Quickbase also warns that webhooks "can be edited or copied by all admins in the app", and any credentials you enter are visible to them. Use a value that exists only for this webhook, keep it long and random, and change it if an admin leaves or it might have leaked.
Make Quickbase webhooks production-ready. Hookdeck Event Gateway checks your secret header, accepts each record change straight away, and delivers it to your service with retries, so a short outage doesn't lose an update.
Quickbase webhook limitations and pain points
Messages over the limits are not sent
The Problem: A bulk import or a busy app silently drops messages your receiver was counting on.
Why It Happens: Quickbase allows at most 50 webhook messages per second per app, shared with Pipelines listening on the same app, and won't send a message larger than 4 MB. Messages past either limit are not sent; the app manager gets an alert and an email.
Workarounds:
- Narrow triggers with Additional criteria so only meaningful changes fire.
- Send IDs and the fields you need, not whole records, to stay well under 4 MB.
- Reconcile against the Quickbase API after large imports.
How Hookdeck Can Help: Hookdeck accepts bursts as fast as Quickbase sends them and delivers to your service at a max delivery rate you choose, so your endpoint never becomes the bottleneck.
No documented retries
The Problem: A request your endpoint fails during a deploy may never be resent.
Why It Happens: Quickbase logs failures in the error history and emails the webhook owner, but its documentation doesn't describe a retry policy or timeout.
Workarounds:
- Keep the endpoint simple and available, and make sure the webhook owner reads the failure emails.
- Review the 30-day View error history list after incidents.
How Hookdeck Can Help: Hookdeck stores each request it accepts and delivers it to your service with retries on your schedule, and you can replay any request after a fix.
Webhooks that stop firing
The Problem: A webhook that worked yesterday sends nothing today.
Why It Happens: The owner must have permission to the table, be a registered user and not be on the deny list, or the webhook isn't sent. Copied apps carry their webhooks over as inactive, and sharing an app to the Exchange removes them.
Workarounds:
- Make a long-lived service account the owner of production webhooks.
- After copying an app, select the copied webhooks and Activate them.
How Hookdeck Can Help: Issues and Hookdeck's request history make a sudden drop in traffic visible, so a silent webhook gets noticed.
Loops
The Problem: A webhook that writes back to its own table triggers itself again and again.
Why It Happens: An update made by the receiver is a record change like any other.
Workarounds:
- Use Additional criteria so the receiver's own update can't match the trigger, as Quickbase advises.
How Hookdeck Can Help: Filters can drop requests that match your receiver's own changes before they reach it.
Best practices
Put %action% and %webhookid% in every body
They tell the receiver what happened and which webhook sent it, which Quickbase otherwise doesn't.
Keep the secret in a header
Add it under Message header and compare it whole, in constant time. Never put it in the URL or the body.
Prefer POST
It is the default and what most receivers expect. If you choose another method, allow it on the Hookdeck source and in your route.
Deduplicate
Include the record ID and %curdate% in the body and build an idempotency key from them. See our guide to webhook idempotency.
Acknowledge fast and process asynchronously
Store the message and respond, then do the work. See why to process webhooks asynchronously.
Conclusion
A Quickbase table webhook sends a request you design when records are added, modified or deleted, with no signature and no Quickbase-defined fields. Authenticate it with a secret header, put %action% and identifiers in the body, stay inside the 50-per-second and 4 MB limits, and allow any non-POST method on your receiver and on the Hookdeck source.
Hookdeck Event Gateway checks the header, absorbs bursts, and keeps every request until your service has processed it.
Get started with Hookdeck for free and handle Quickbase webhooks reliably in minutes.