Webhooks
Webhooks push loan events to your server in real time. Instead of polling the Credit API for status changes, register a URL and Floe sends you an HTTP POST when something happens.
Base URL: https://credit-api.floelabs.xyz
Events
loan.health_warning
LTV approaches liquidation threshold (at-risk or unhealthy)
currentLtvBps, liquidationLtvBps, healthState, borrower, lender
loan.expiry_warning
24 hours before loan maturity
maturityTime, hoursRemaining
loan.liquidated
Loan was liquidated on-chain
principal, collateralAmount, liquidationLtvBps
loan.repaid
Loan was fully repaid
principal, collateralAmount, interestRateBps
credit.utilization_warning
Borrowed principal exceeds 80% of credit limit
utilizationBps, creditLimitRaw, creditUsedRaw
delegation.expiry_warning
Operator delegation expires within 7 days (or 24 hours for urgent)
expiryTimestamp, hoursRemaining, agentId
Scopes
Each webhook is scoped to control which loans trigger it:
Scope
Description
scopeValue
global
All loans on the protocol
Not required
wallet
Loans where a specific address is borrower or lender
Wallet address (0x...)
loan
A specific loan by ID
Loan ID (e.g., "42")
Registering Webhooks
Via the Dashboard
Click Create Webhook
Enter your endpoint URL (must be HTTPS)
Select the events you want to receive
Choose scope: global, wallet, or loan
Click Create — your webhook secret is displayed once
Copy the secret immediately. You need it to verify webhook signatures.
Via the API
Response:
The secret field is shown only at creation (and when you rotate it). Store it securely.
API Endpoints
All endpoints require a developer key (floe_live_*) in the Authorization header.
POST /v1/developer/webhooks
Register a new webhook endpoint.
url
string
Yes
HTTPS endpoint to receive events
events
string[]
Yes
Array of event types to subscribe to
scope
string
Yes
global, wallet, or loan
scopeValue
string
Conditional
Required for wallet and loan scopes
description
string
No
Human-readable label
GET /v1/developer/webhooks
List all registered webhooks.
PATCH /v1/developer/webhooks/:id
Update a webhook's URL, events, scope, or description.
DELETE /v1/developer/webhooks/:id
Delete a webhook. No further events are sent after deletion.
POST /v1/developer/webhooks/:id/test
Send a test event to your endpoint. The test payload uses realistic data but does not correspond to a real loan.
POST /v1/developer/webhooks/:id/rotate-secret
Generate a new HMAC secret. The old secret stops working immediately. Update your server's verification logic before rotating in production.
Response:
GET /v1/developer/webhooks/:id/deliveries
View the delivery log for a webhook. Shows recent delivery attempts, status codes, and timestamps.
Response:
Payload Format
Every webhook delivery sends a JSON POST request to your endpoint:
Signature Verification
Every delivery includes three headers for verification:
X-Floe-Signature
HMAC-SHA256 signature of {timestamp}.{payload} using your webhook secret
X-Floe-Timestamp
Unix timestamp (seconds) when the event was sent
X-Floe-Delivery-Id
Unique ID for this delivery attempt (use for idempotency)
The signature is computed as:
Always verify the signature before processing the event. This prevents forged requests from reaching your business logic.
Node.js Verification
Python Verification
See the full handler examples: TypeScript | Python
Delivery Guarantees
At-least-once delivery. Your endpoint may receive the same event more than once. Use
X-Floe-Delivery-Idfor idempotency.3 attempts maximum. If your endpoint does not respond with a
2xxstatus code, Floe retries with exponential backoff.Retry schedule: Attempt 1 immediately, Attempt 2 after 1 minute, Attempt 3 after 5 minutes.
Delivery states:
pending(first attempt) ->retrying(attempts 2-3) ->delivered(success) orfailed(all attempts exhausted).
After 3 failed attempts, the delivery is marked as failed. You can see failed deliveries in the dashboard or via GET /v1/developer/webhooks/:id/deliveries.
Testing
Dashboard
Click Send Test Event on any webhook in the dashboard. The test payload looks like a real event but does not correspond to an actual loan.
webhook.site
For quick testing without deploying a server:
Go to webhook.site and copy your unique URL
Register that URL as a webhook endpoint
Send a test event from the dashboard
Inspect the payload and headers on webhook.site
API
Best Practices
Always verify signatures. Never process a webhook payload without checking
X-Floe-Signature. This prevents spoofed requests.Respond with
2xxquickly. Return a200as soon as you receive the payload. Process the event asynchronously in a background job or queue.Implement idempotency. Store
X-Floe-Delivery-Idand skip duplicates. Retries can send the same event more than once.Use HTTPS endpoints. Floe only delivers to HTTPS URLs in production.
Monitor delivery logs. Check the dashboard or
GET /v1/developer/webhooks/:id/deliveriesperiodically for failed deliveries.Rotate secrets safely. Update your server's verification logic to accept both old and new secrets during rotation, then remove the old one.
Next Steps
Webhook Handler (TypeScript) — Complete Express.js example with signature verification.
Webhook Handler (Python) — Complete Flask example with HMAC verification.
API Keys — Create your developer key to register webhooks.
Developer Dashboard — Manage webhooks through the web UI.
Credit API — Full HTTP API reference.
Last updated
