Best for
- How do I receive Ascend webhooks?
- How do I verify Ascend webhook signatures?
- How do I parse the X-Ascend-Signature header?
hookdeck/webhook-skills/skills/ascend-webhooks/SKILL.md
Receive and verify Ascend webhooks. Use when setting up Ascend webhook handlers, debugging Ascend signature verification (X-Ascend-Signature, HMAC-SHA256), or handling insurance payment events like invoice.paid, payout.paid, and refund.paid.
Decision brief
Ascend (insurance payments / premium financing) sends webhooks so your app is notified when an event happens — for example when an invoice is paid. Ascend POSTs a JSON payload over HTTPS and signs it with an HMAC-SHA256 signature you must verify before trusting the event.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/hookdeck/webhook-skills --skill "skills/ascend-webhooks"Inspect the Agent Skill "ascend-webhooks" from https://github.com/hookdeck/webhook-skills/blob/b568103d289159ac69c1324a2bb868286ab13714/skills/ascend-webhooks/SKILL.md at commit b568103d289159ac69c1324a2bb868286ab13714. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Ascend webhook registration is manual — there is no self-serve dashboard. Email [email protected] with your organization, environment (sandbox/production), the events you want, and your HTTPS endpoint URL. Ascend returns a webhook signing secret. See references/setup.md.
How do I receive Ascend webhooks?
Ascend uses a custom Stripe-style HMAC-SHA256 scheme (not Svix, not Standard Webhooks). Two headers are sent:
Every event has the same top-level shape. Unlike Stripe, data is the resource object directly (there is no data.object wrapper):
Permission review
The documentation asks the agent to run terminal commands or scripts.
For local webhook testing, run the Hookdeck CLI via `npx` — no install required:The documentation asks the agent to run terminal commands or scripts.
npx hookdeck-cli listen 3000 ascend --path /webhooks/ascendEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 89/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 79 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Ascend (insurance payments / premium financing) sends webhooks so your app is notified when an event happens — for example when an invoice is paid. Ascend POSTs a JSON payload over HTTPS and signs it with an HMAC-SHA256 signature you must verify before trusting the event.
X-Ascend-Signature header?invoice.paid (or payout / refund) events?Ascend uses a custom Stripe-style HMAC-SHA256 scheme (not Svix, not Standard Webhooks). Two headers are sent:
| Header | Example | Purpose |
|---|---|---|
X-Ascend-Signature | t=1696200697,v1=5257a869e7... | Timestamp + HMAC signature |
X-Ascend-Request-Timestamp | 1696200697 | Same Unix timestamp (redundant) |
The signature is verified by:
X-Ascend-Signature into t (timestamp) and v1 (hex HMAC).`${t}:${rawBody}` — the timestamp, a colon, then the raw request body.HMAC-SHA256(signed_string, webhook_secret) and hex-encode it.v1.Use the raw request body. Re-serializing the parsed JSON (key reordering, whitespace) changes the bytes and breaks the signature. There is no official Ascend SDK, so every framework below verifies manually.
const crypto = require('crypto');
// Verify Ascend's "t=<timestamp>,v1=<hex>" signature over "<timestamp>:<rawBody>".
function verifyAscendSignature(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(
signatureHeader.split(',').map((p) => p.split('=').map((s) => s.trim()))
);
const { t: timestamp, v1: signature } = parts;
if (!timestamp || !signature) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}:${rawBody}`) // colon separator + RAW body
.digest('hex');
try {
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex')
);
} catch {
return false; // length mismatch = invalid
}
}
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Every event has the same top-level shape. Unlike Stripe, data is the
resource object directly (there is no data.object wrapper):
{
"id": "ajskljfaklsjd0912132",
"type": "invoice.paid",
"data": {
"id": "684c8c8e-75eb-4134-925a-cb3a30f23633",
"status": "paid",
"payee": "John Doe Trucking",
"payer_name": "John Doe",
"total_amount_cents": 600000,
"invoice_number": "II2DH1HGHJ",
"paid_at": "2023-10-01T23:51:37.507Z"
}
}
| Event | Triggered When |
|---|---|
invoice.created | An invoice is created |
invoice.processing_payment | An invoice payment is being processed |
invoice.paid | An invoice is paid |
invoice.voided | An invoice is voided |
invoice.marked_overdue | An invoice is marked overdue |
payout.paying | A payout is being paid out |
payout.paid | A payout has been paid |
payout.on_hold | A payout is placed on hold |
payout.canceled | A payout is canceled |
payout.failed | A payout failed |
refund.paid | A refund has been paid |
refund.cancelled | A refund was cancelled |
Always branch on the type field and handle unknown types gracefully. See
references/overview.md for the full list and payloads.
| Variable | Description |
|---|---|
ASCEND_WEBHOOK_SECRET | The webhook signing secret provided by Ascend |
Ascend webhook registration is manual — there is no self-serve dashboard.
Email [email protected] with your organization, environment
(sandbox/production), the events you want, and your HTTPS endpoint URL. Ascend
returns a webhook signing secret. See references/setup.md.
For local webhook testing, run the Hookdeck CLI via npx — no install required:
npx hookdeck-cli listen 3000 ascend --path /webhooks/ascend
No account required — the CLI creates a guest account on first run and provides a local tunnel + web UI for inspecting requests.
Install webhook-handler-patterns alongside this skill for cross-cutting concerns:
t=,v1= scheme (Ascend mirrors this style)