Delete Webhook Subscription
Requires the manage:webhooks scope.
Unsubscribe by disabling the subscription so delivery stops.
Soft-disable: the record is kept with enabled=False and disabled_at
set. Disabling an already-disabled subscription is a no-op and still
returns 204 No Content, so unsubscribe is idempotent.
- subscription_id
- Opaque id of the subscription to unsubscribe.
An empty 204 No Content response.
- HTTPException
- 404 Not Found when no subscription with that id exists for this financial institution.
Authorization
APIKeyHeader Partner API key, required on every endpoint except "GET /health". Your financial institution issues and revokes these keys from the InvestiFi Ops Center. Each key carries an environment-identifying prefix such as "ifi_prod_" plus a fixed set of scopes, so a valid key still returns 403 Forbidden on an endpoint whose scope it was not granted; the response "detail" names the check that failed.
In: header
Path Parameters
Response Body
application/json
application/json
curl -X DELETE "https://partner-api.investifi.com/v1/webhooks/subscriptions/string"{
"detail": "Key does not have the required scope: manage:webhooks."
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}Create Webhook Subscription
Requires the `manage:webhooks` scope. Create a webhook subscription, issuing the financial institution's signing secret on first use. The signing secret is returned only when this subscribe issued it (the financial institution's first subscription); on later subscribes it already exists and is omitted. The subscription is pinned to the Partner API version this endpoint is mounted under, and links in its delivered payloads are built at that version. Moving to a newer API version means subscribing again through that version.
KYC Status Change Event
Delivers a user's identity verification status change to your callback URL. Sent to every callback URL subscribed to the `kyc` event type when a user's status changes for one of your financial institution's investing products. Intermediate states carrying no outcome you can act on are not delivered. One subscription covers every delivered status: filter on `data.kyc_status` (`pending`, `document_requested`, `approved`, `rejected`, `closed`, `account_takeover`) rather than subscribing per status. A user who has finished onboarding into a product reports `approved` for that product, named in `data.product`. Each request carries two headers: - `X-InvestiFi-Webhook-Id`: the delivery's idempotency key, equal to `event_id` and reused across retries. Deduplicate on it. - `X-InvestiFi-Webhook-Signature`: `t=<unix_seconds>,v1=<hex digest>`. The digest is a hash-based message authentication code (HMAC-SHA256) over the timestamp, a period, and the raw request body, keyed by the signing secret returned from your first subscribe. `v1` is a scheme tag: match on it rather than assuming one value. The header is sent once your financial institution has a signing secret. Verify against the raw request body, before parsing it, so the bytes match what was signed. Compare digests in constant time: ```python import hashlib import hmac parts = dict(p.split("=", 1) for p in signature_header.split(",")) signed = f"{parts['t']}.{raw_body.decode()}".encode() expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() if not hmac.compare_digest(expected, parts["v1"]): raise ValueError("Signature does not match") ``` Delivery is at-least-once. Return any 2xx status to acknowledge; a non-2xx response or a timeout is retried. `links.self` points at the authoritative user record for consumers that would rather refetch than trust the payload. Each subscription is pinned to the API version it was created through, and `links.self` is built at that version: a subscription created via the `v1` subscribe endpoint emits `/v1/...` links, and keeps doing so after newer API versions ship. When you migrate to a new API version, switch both at the same time: point your API calls at the new base URL and re-create your webhook subscriptions through the new version's subscribe endpoint, then delete the old subscriptions.

