Webhooks
Webhooks let your integration react to events as they happen inside Aleta. When a new transaction posts, a holding's market value updates, or an account is reconnected, we send a signed HTTP POST to the URL you've registered.
Registering an endpoint
POST /v1/webhooks
curl https://api.aleta.io/v1/webhooks \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/aleta/webhooks",
"events": ["transaction.created", "account.connected"]
}'
The response includes a secret — store it securely and use it to verify signatures on incoming requests.
Verifying signatures
Every webhook delivery includes an Aleta-Signature header: a timestamp plus an HMAC-SHA256 of the request body keyed by your webhook secret. Reject any delivery whose signature doesn't verify, or whose timestamp is more than five minutes off.
Express handler
import crypto from "crypto";
app.post("/aleta/webhooks", (req, res) => {
const [timestamp, signature] = req.header("Aleta-Signature").split(",");
const expected = crypto
.createHmac("sha256", process.env.ALETA_WEBHOOK_SECRET)
.update(`${timestamp}.${JSON.stringify(req.body)}`)
.digest("hex");
if (signature !== expected) return res.sendStatus(401);
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return res.sendStatus(401);
// Handle the event…
res.sendStatus(200);
});
Return a 2xx response within 10 seconds. We consider anything slower a
failure and retry with exponential backoff, up to 24 hours. Idempotency is
on you — we may deliver the same event more than once.
Event catalogue
| Event | When it fires |
|---|---|
account.connected | A new financial account is linked to an entity. |
account.disconnected | An account's credentials break or it is unlinked. |
transaction.created | A new transaction is ingested from a data source. |
transaction.updated | An existing transaction is classified or amended. |
holding.valued | A holding receives an updated market value snapshot. |