Webhooks
Rather than polling, you can have StatementIQ POST an event to your server when something happens to a request. Set your webhook URL in the portal under Settings → Company. A signing secret is generated for you at the same time.
Events
consent.completed— the customer authorised data sharing.report.awaiting_share— the report is prepared and the customer is reviewing it (a good moment to prompt them from your own app if you embed the widget).report.ready— the customer shared the report; it can be fetched.report.refreshed— you refreshed anongoing-consent request; the new documents (under theverification_idin the payload) supersede the previous ones.request.withdrawn— consent was withdrawn (by the customer or your firm); derived data has been deleted.
Payload
We POST JSON to your URL. Every payload includes the request_id:
{
"event": "report.ready",
"request_id": "req_1a2b3c…",
"verification_id": "SIQ-6EABF8EC",
"report_type": "expense_summary",
"client_name": "Jordan Wilson"
}On report.ready, call GET /v1/requests/{id}/report to fetch the report.
Verifying the signature
Each delivery includes an X-StatementIQ-Signature header: the HMAC-SHA256 of the raw request body, keyed with your webhook signing secret. Recompute it and compare before trusting a payload.
import hmac, hashlib
def verify(secret: str, raw_body: bytes, signature: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)Respond quickly, then work
Return a 2xx as soon as you have received the event, then do your processing asynchronously. Deliveries are best-effort; if your endpoint is unavailable, the report is still retrievable via the API, and a reconciler will re-attempt generation if an upstream consent event was missed.