Skip to content

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:

{ "endpointId": "a1b2c3d4-...", "secret": "e3b0c44298fc1c149afb..." }

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:

X-Octamile-Signature: sha256=3a4e7b2f...

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

  1. Signature mismatch — ensure you are computing HMAC over the raw request body bytes, not a parsed/re-serialised object.
  2. No delivery received — check the delivery log in the dashboard (Partners → Webhooks → expand endpoint). The log shows each attempt, HTTP status, and response body.
  3. Dead delivery — click Retry in the dashboard or issue webhook list + webhook update to re-activate the endpoint, then call SR20 to fetch status directly.
  4. Endpoint unreachable — your URL must be publicly accessible over HTTPS. Test with curl -X POST https://yourserver.com/webhooks/octamile.