Agent skill
Laso Finance Webhooks Skill
Receive and verify Laso Finance webhooks, which follow the Standard Webhooks specification. Use when registering a Laso Finance webhook URL with POST /register-webhook, storing the whsec_ signing secret, debugging webhook-id / webhook-timestamp / webhook-signature verification, or handling notification.transaction, notification.deposit, notification.account, notification.card and notification.giftCard events for an AI agent's bank account.
Install this skill
npx skills add hookdeck/webhook-skills --skill laso-finance-webhooks
Laso Finance provides banking, cards and payouts for AI agents. An agent registers one webhook URL per account with POST /register-webhook and then receives every account notification (banking application status, transfers, deposits, card orders, withdrawals) as a signed JSON POST. Signatures follow Standard Webhooks, so each delivery carries webhook-id, webhook-timestamp and webhook-signature headers.
When to Use This Skill
- How do I receive Laso Finance webhooks?
- How do I verify a Laso Finance webhook signature (
webhook-signature)? - Where do I get the Laso Finance webhook secret (
whsec_...)? (Only from thePOST /register-webhookresponse.) - How do I handle
notification.transaction,notification.depositornotification.withdrawalevents? - Why is my Laso Finance webhook verification failing, or failing only on Hookdeck retries and replays?
- Why did Laso Finance stop sending webhooks? (50 consecutive failures disable the registration.)
Verification (core)
| Header | Value |
|---|---|
webhook-id | msg_... message id. Your idempotency key (the body has no event id) |
webhook-timestamp | Unix seconds when the delivery was signed |
webhook-signature | One or more space-separated v1,<base64> entries |
Signed content is {webhook-id}.{webhook-timestamp}.{raw body}, HMAC-SHA256, base64 output. The key is the base64-decoded part of the whsec_... secret after the prefix. Compare against every v1, entry; ignore other versions. If webhook-id is absent, read svix-id, svix-timestamp and svix-signature instead, as Hookdeck does. The examples use the standardwebhooks library (npm and PyPI):
const { Webhook } = require('standardwebhooks');
// rawBody: exact request body (Buffer or string), NOT re-serialised JSON
function verifyLaso(rawBody, headers, secret = process.env.LASO_FINANCE_WEBHOOK_SECRET) {
const p = headers['webhook-id'] ? 'webhook' : 'svix'; // fall back to the svix-* names
new Webhook(secret).verify(rawBody, {
'webhook-id': headers[`${p}-id`],
'webhook-timestamp': headers[`${p}-timestamp`],
'webhook-signature': headers[`${p}-signature`],
}, { jsonParse: false }); // throws on a bad signature or stale timestamp → respond 401
}
The library always enforces a fixed 5-minute timestamp window. Laso Finance itself never retries, but Hookdeck retries and replays resend the original webhook-timestamp, so the library rejects them once they are more than 5 minutes old. If you receive through Hookdeck and need late retries to pass, use the manual verifier in references/verification.md, which can drop or widen the window. In Express, read the body with express.raw({ type: '*/*' }) so any content type verifies, and parse JSON only after the check.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Event Type and Payload
Every body is the same envelope. The event name is the top-level type, which is notification. plus the notification category:
{
"type": "notification.transaction",
"timestamp": "2026-07-31T18:04:05.000Z",
"data": {
"user_id": "usr_abc123",
"title": "Bank transfer complete",
"text": "$250.00 landed in your agent wallet.",
"category": "transaction"
}
}
data is the notification as the account owner sees it: title and text are human-readable, and category repeats the bare category. There is no event id in the body: use the webhook-id header.
Common Event Types
| Event | Category |
|---|---|
notification.account | Banking application and account status. Also the signed test delivery sent when you register |
notification.transaction | Bank transfers and payouts, such as a transfer completing |
notification.deposit | Agent wallet deposits |
notification.withdrawal | Withdrawals |
notification.card | Card orders |
notification.giftCard | Gift card orders |
notification.refund | Refunds (named in the docs, not described) |
notification.balanceUpdate | Balance changes (named in the docs, not described) |
The docs list these eight under "Categories include" without describing each one, so the list is open-ended and the descriptions above are inferred from the names and the docs' examples. The examples handle all eight and ignore other types. There is no per-type selection: one webhook receives every notification. See references/overview.md.
Delivery Semantics
Respond with any 2xx within 10 seconds, then process asynchronously. Deliveries are not retried: a failed or timed-out delivery is lost, and the status endpoints (listBankingTransactions, /get-withdrawal-status) remain the source of truth, so reconcile against them. After 50 consecutive failures the registration is disabled; GET /get-webhook shows the failure counters and last attempt, and registering again re-enables it. Deduplicate on webhook-id. Return 400 for missing headers and 401 for a bad signature.
Environment Variables
LASO_FINANCE_WEBHOOK_SECRET=whsec_xxxxx # full value from the register response; handlers fail closed (500) without it
The secret is returned only in the POST /register-webhook response and GET /get-webhook never returns it. Registering again rotates it, so update the variable at the same time.
Local Development
# Express / Next.js (use 8000 for FastAPI). No install or account required.
npx hookdeck-cli listen 3000 laso-finance --path /webhooks/laso-finance
Register the printed URL with POST /register-webhook (the URL must be public HTTPS). Registering sends a signed notification.account test delivery to it.
Reference Materials
- references/overview.md - Event catalog, envelope and delivery behaviour
- references/setup.md - Register, check and delete the webhook, handle the secret
- references/verification.md - Library and manual verification, gotchas, debugging