Agent skill
Workato Webhooks Skill
Receive and authenticate requests sent by Workato recipes. Use when building an endpoint that a Workato HTTP connector action calls, securing it with the HTTP connection's Basic auth username and password, debugging 401s from Workato, or routing recipe payloads by an event field such as order.created or record.updated.
Install this skill
npx skills add hookdeck/webhook-skills --skill workato-webhooks
Workato is an automation platform with no native outbound webhooks. A recipe pushes data to your app with the HTTP connector's Send request via HTTP action, using an HTTP connection set to Basic authentication. Workato does not sign these requests, so your endpoint authenticates them with the Basic auth username and password and routes them by an event field you put in the body.
When to Use This Skill
- How do I receive webhooks from a Workato recipe?
- How do I secure an endpoint that Workato's HTTP connector calls?
- How do I verify the
Authorization: Basicheader Workato sends? - Does Workato sign webhook requests? (No: static Basic auth credential)
- Why does my Workato HTTP action get a 401 from my webhook endpoint?
Verification (core)
Parse Authorization: Basic base64(username:password) (scheme is case-insensitive), split on the first colon, and compare the username and the password each in constant time. Evaluate both before deciding:
const crypto = require('crypto');
function safeEqual(a, b) {
const ba = Buffer.from(String(a), 'utf8');
const bb = Buffer.from(String(b), 'utf8');
if (ba.length !== bb.length) return false; // timingSafeEqual needs equal lengths
return crypto.timingSafeEqual(ba, bb);
}
function verifyWorkatoRequest(headers, user, password) {
if (!user || !password) return false; // never accept when unconfigured
const m = (headers['authorization'] || '').match(/^Basic\s+([A-Za-z0-9+/]+={0,2})\s*$/i);
if (!m) return false;
const decoded = Buffer.from(m[1].trim(), 'base64').toString('utf8');
const sep = decoded.indexOf(':'); // password may contain ':'
if (sep === -1) return false;
const userOk = safeEqual(decoded.slice(0, sep), user);
const passwordOk = safeEqual(decoded.slice(sep + 1), password);
return userOk && passwordOk; // no short-circuit above
}
Return 401 when this fails, 400 for a non-empty body that isn't a JSON object, and 200 once handled. Authenticate before parsing the body, and read it raw (express.raw({ type: '*/*' })) so any content type works. Python and Next.js equivalents are in references/verification.md.
A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use HTTPS only, and rotate the password if it leaks.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
HTTP Methods and Empty Bodies
The method is whatever the recipe's HTTP action is set to, so the examples accept POST, PUT, PATCH, GET and DELETE on the route and treat an empty body (typical for GET) as {}.
Event Types
Workato defines no webhook event types; the payload is whatever the recipe sends. Send {"event": "...", "data": {...}} and dispatch on event. The examples use these names, which are a convention, not Workato values:
| Event | Sent When |
|---|---|
order.created | A recipe sees a new order |
record.updated | A recipe syncs a changed record |
recipe.failed | An error-handling step reports a failure |
Environment Variables
WORKATO_WEBHOOK_USERNAME=workato # "Basic auth user"
WORKATO_WEBHOOK_PASSWORD=replace-with-a-long-random-password # "Basic auth password"
Local Development
Workato can't reach localhost. Tunnel with the Hookdeck CLI (no account required):
npx hookdeck-cli listen 3000 workato --path /webhooks/workato
Use the printed URL as the HTTP connection's Base URL.
Resources
- references/overview.md - How Workato sends requests, suggested payload shape, example events
- references/setup.md - Configure the HTTP connection and recipe action
- references/verification.md - Basic auth check in Node, Python and Next.js, gotchas, debugging 401s
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests