Webhook Reference¶
Webhooks let you receive real-time notifications when a policy event occurs, instead of polling Step 4 repeatedly. Octamile sends a signed POST request to your registered endpoint when a policy is issued, approved, or declined.
Registering an Endpoint¶
Use the webhook register API command to add an endpoint. Octamile returns a signing secret — store it securely, it is shown only once. You can also manage endpoints from the Webhooks page in the partner dashboard.
{
"userInfo": { "id": "YOUR_PARTNER_UUID", "athrzt": { "id": "AUTH_ID", "key": "AUTH_KEY" } },
"cmmnd": {
"cmmnd": "webhook register",
"seed": {
"url": "https://yourserver.com/webhooks/octamile",
"events": "policy.issued,policy.approved,policy.declined"
}
}
}
Response:
Each partner may register up to 5 endpoints. The URL must be a publicly reachable HTTPS address.
Endpoint Commands¶
| Command | Seed fields | Action |
|---|---|---|
webhook register |
url (required), events (optional) |
Create a new endpoint; returns endpointId + secret |
webhook update |
endpointId (required), url, events, active (bool) |
Update URL, events filter, or pause/resume |
webhook delete |
endpointId (required) |
Permanently delete endpoint and delivery history |
webhook list |
— | List your registered endpoints |
Events¶
| Event | When it fires |
|---|---|
policy.issued |
SR15 succeeds — the InsuranceRequest row is written |
policy.approved |
SR30 sets ApprovalStatus = 'a' (manual approval or auto-approve) |
policy.declined |
SR30 sets ApprovalStatus = 'd' |
The events field on an endpoint is a comma-separated filter. Set it to a subset if you only need some events.
Payload¶
Octamile sends a POST request with Content-Type: application/json:
{
"event": "policy.issued",
"requestId": "z9y8x7w6-v5u4-z9y8-x7w6-v5u4z9y8x7w6",
"product": "vhcl-tprt-1111",
"consumerId": "a1b2c3d4-e5f6-a1b2-c3d4-e5f6a1b2c3d4",
"environment": "live"
}
For policy.approved and policy.declined:
{
"event": "policy.approved",
"requestId": "z9y8x7w6-v5u4-z9y8-x7w6-v5u4z9y8x7w6",
"product": "vhcl-tprt-1111",
"status": "a",
"note": ""
}
After receiving a policy.approved event, call SR20 with the requestId to retrieve the certificate or policy number.
Payload Fields¶
| Field | Type | Events | Description |
|---|---|---|---|
event |
string | all | Event type: policy.issued, policy.approved, policy.declined |
requestId |
string | all | The InsuranceRequest UUID (your transaction reference) |
product |
string | all | Product code, e.g. vhcl-tprt-1111 |
consumerId |
string | policy.issued |
The EndCustomer UUID |
environment |
string | policy.issued |
"test" or "live" |
status |
string | policy.approved, policy.declined |
"a" (approved) or "d" (declined) |
note |
string | policy.declined |
Decline reason, if provided |
Verifying Signatures¶
Every delivery includes an X-Octamile-Signature header:
Verify it using HMAC-SHA256 with your endpoint secret before processing the payload.
Node.js:
const crypto = require('crypto');
function verifySignature(secret, rawBody, header) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}
app.post('/webhooks/octamile', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-octamile-signature'];
if (!verifySignature(process.env.OCTAMILE_WEBHOOK_SECRET, req.body, sig)) {
return res.sendStatus(401);
}
res.sendStatus(200); // respond fast; process async
const event = JSON.parse(req.body);
if (event.event === 'policy.approved') {
// call SR20 to fetch certificate
}
});
Python:
import hmac, hashlib
def verify_signature(secret: str, body: bytes, header: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, header)
@app.route('/webhooks/octamile', methods=['POST'])
def octamile_webhook():
sig = request.headers.get('X-Octamile-Signature', '')
if not verify_signature(os.environ['OCTAMILE_WEBHOOK_SECRET'], request.data, sig):
return '', 401
return '', 200 # respond fast; hand off to background worker
Delivery and Retries¶
- Your endpoint must return HTTP 2xx within 10 seconds.
- On failure, Octamile retries with exponential backoff: 1 min → 5 min → 30 min → 2 h → 12 h.
- After 5 failed attempts the delivery is marked dead. You can manually retry from the dashboard or via SR20 polling.
- Deliveries older than 30 days are not retried.
Webhooks vs. Polling¶
| Webhook | Polling (SR20) | |
|---|---|---|
| Recommended for | Production integrations | Development and debugging |
| Latency | Near real-time | Depends on poll interval |
| Requires public HTTPS URL | Yes | No |
| Retried on failure | Yes (5 attempts) | On each poll |
Use webhooks in production. Use SR20 polling during development — tools like ngrok can expose a local port for webhook testing.
Troubleshooting¶
- Signature mismatch — ensure you are computing HMAC over the raw request body bytes, not a parsed/re-serialised object.
- No delivery received — check the delivery log in the dashboard (Partners → Webhooks → expand endpoint). The log shows each attempt, HTTP status, and response body.
- Dead delivery — click Retry in the dashboard or issue
webhook list+webhook updateto re-activate the endpoint, then call SR20 to fetch status directly. - Endpoint unreachable — your URL must be publicly accessible over HTTPS. Test with
curl -X POST https://yourserver.com/webhooks/octamile.