Webhooks¶
Use webhooks to receive signed Spendware events in your application.
Example: Create Endpoint¶
curl "$SPENDWARE_WEBHOOKS_BASE_URL/api/v1/endpoints" \
-H "Authorization: Bearer $SPENDWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"tenant_id":"ORGANIZATION_ID","name":"Production receiver","url":"https://example.com/spendware/webhooks","subscribed_events":["usage.logged"]}'
from spendware_provider_sdk.management import SpendwareManagementClient, WebhookEndpointCreate
client = SpendwareManagementClient(
base_url="SPENDWARE_BASE_URL",
webhooks_base_url="SPENDWARE_WEBHOOKS_BASE_URL",
api_key="SPENDWARE_API_KEY",
)
endpoint = client.webhooks.create_endpoint(
tenant_id="ORGANIZATION_ID",
endpoint=WebhookEndpointCreate(
name="Production receiver",
url="https://example.com/spendware/webhooks",
subscribed_events=["usage.logged"],
),
)
client.close()
import { SpendwareManagementClient } from "@spendware/provider-adapters-sdk/management";
const client = new SpendwareManagementClient({
baseUrl: "SPENDWARE_BASE_URL",
webhooksBaseUrl: "SPENDWARE_WEBHOOKS_BASE_URL",
apiKey: "SPENDWARE_API_KEY",
});
const endpoint = await client.webhooks.createEndpoint("ORGANIZATION_ID", {
name: "Production receiver",
url: "https://example.com/spendware/webhooks",
subscribed_events: ["usage.logged"],
});
Verify Signatures¶
Use SDK helpers with the raw request body. Do not parse and reserialize the payload before verifying.
from spendware_provider_sdk import verify_webhook_signature
is_valid = verify_webhook_signature(payload=raw_body, secret=signing_secret, headers=headers)
import { verifyWebhookSignature } from "@spendware/provider-adapters-sdk";
const isValid = verifyWebhookSignature({ payload: rawBodyBuffer, secret: signingSecret, headers });
Delivery Rules¶
- Delivery is asynchronous and at least once.
- Return
2xxonly after durable processing. - Deduplicate by event ID or delivery ID.
- Rotate endpoint secrets through the management API and store new secrets immediately.