Agent skill
Proxyclick Webhooks Skill
Receive and authenticate Proxyclick (now Eptura Visitor) webhooks. Use when setting up a Proxyclick webhook endpoint, checking the HTTP Basic credentials Proxyclick sends, debugging 401s, or handling visitor check-in, check-out and visit created, updated or deleted notifications.
Install this skill
npx skills add hookdeck/webhook-skills --skill proxyclick-webhooks
Proxyclick (now Eptura Visitor, visitor management) POSTs a JSON notification to a URL you choose when a visitor or visit changes. Payloads are not signed. The only security option is HTTP Basic authentication (a username and password you enter on the webhook).
When to Use This Skill
- How do I receive Proxyclick (Eptura Visitor) webhooks?
- How do I verify the Proxyclick Basic auth credentials on a webhook?
- Does Proxyclick sign webhook payloads? (No: Basic auth only)
- Why does my Proxyclick webhook endpoint return 401?
- How do I handle visitor check-in, check-out and visit created, updated or deleted events?
Verification (core)
const crypto = require('crypto');
const sha = (s) => crypto.createHash('sha256').update(String(s)).digest();
const safeEqual = (a, b) => crypto.timingSafeEqual(sha(a), sha(b)); // equal-length digests
function verifyProxyclickRequest(headers, env = process.env) {
const m = /^basic +([A-Za-z0-9+/]+={0,2}) *$/i.exec(headers['authorization'] || '');
if (!m || !env.PROXYCLICK_WEBHOOK_USERNAME || !env.PROXYCLICK_WEBHOOK_PASSWORD) return false;
const decoded = Buffer.from(m[1], 'base64').toString('utf8');
const i = decoded.indexOf(':'); // split on the FIRST colon
if (i < 0) return false;
const userOk = safeEqual(decoded.slice(0, i), env.PROXYCLICK_WEBHOOK_USERNAME);
const passOk = safeEqual(decoded.slice(i + 1), env.PROXYCLICK_WEBHOOK_PASSWORD);
return userOk && passOk; // both evaluated, no short-circuit
}
Return 401 when this fails (missing or malformed header, wrong username or password), 400 for a body that isn't a JSON object, and 200 once handled. Read the body raw (express.raw({ type: '*/*' })) and parse JSON only after the credential check.
Security notes
- A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use an HTTPS destination URL (Proxyclick also allows plain HTTP) and rotate the credential if it leaks.
- The Proxyclick docs don't say whether Basic credentials are sent preemptively, so the credentials must arrive on the first request. A
401+WWW-Authenticatechallenge flow won't work, and it won't work through Hookdeck either, which verifies the request as received. - Compare in constant time. In Python use
hmac.compare_digeston bytes (encode both sides); passingstrraises on non-ASCII input.
Python and Next.js equivalents are in references/verification.md.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Webhook Triggers
Proxyclick's docs name six trigger events, only as labels in the webhook settings UI. They document no event-type field in the payload, and the attribute reference shows API objects rather than a webhook body, so the examples dispatch on nothing. Their handlers use a clearly labelled illustrative body.
| Trigger (UI label) | Fires when |
|---|---|
| Visitor on-site | A visitor is on site |
| Visitor check-in | A visitor checks in |
| Visitor check-out | A visitor checks out |
| Visit created | A visit is created |
| Visit updated | A visit is updated |
| Visit deleted | A visit is deleted |
Proxyclick only guarantees backward compatibility for attributes in its public documentation. Log a real delivery before you rely on any key.
Environment Variables
PROXYCLICK_WEBHOOK_USERNAME=proxyclick
PROXYCLICK_WEBHOOK_PASSWORD=replace-with-a-long-random-password
Local Development
npx hookdeck-cli listen 3000 proxyclick --path /webhooks/proxyclick
No account required. Paste the printed URL into the webhook's destination URL in Proxyclick, and enter the same username and password there.
Resources
- references/overview.md - The six triggers, payload caveats, delivery
- references/setup.md - Add a webhook with Basic auth in Eptura Visitor
- references/verification.md - Basic auth check in Node, Python and Next.js, gotchas
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests