API reference

Webhooks and events

Mira tells your system the moment something changes, with signed events. Version 1.0.0. Dealer and broker accounts.
In short
  • Mira sends a signed POST to your endpoint for every event on records you created through the API.
  • Check the signature on every request, answer within 10 seconds, and ignore repeats by event id.
  • Failed deliveries are retried for about two days, and you can resend from the delivery log.

Set up an endpoint

Add an endpoint in Mira Business under Settings, Webhooks: one for live events and, separately, one for test events. It must be HTTPS on port 443 or 8443 and reachable from the public internet. You see its signing secret once, when you add it or replace it.

By default an endpoint receives every event. In settings you can choose only some, by name or by whole group, for example delivery.*; a group also covers events added to it later. The test event is always sent.

What Mira sends

A POST for each event, with the event in the body. Events carry ids and statuses only, never personal details: read the journey or vehicle through the API for more.

Request
POST /your/webhook/path
Mira-Event-Id: 0192f1d0-2a4b-7c3d-8e9f-0a1b2c3d4e5f
Mira-Event-Type: delivery.completed
Mira-Timestamp: 1759140000
Mira-Signature: t=1759140000,v1=<64 hex characters>

{
  "id": "0192f1d0-2a4b-7c3d-8e9f-0a1b2c3d4e5f",
  "type": "delivery.completed",
  "apiVersion": "1.0.0",
  "livemode": true,
  "createdAt": "2026-10-02T14:03:11Z",
  "data": {
    "journeyId": "0192f1c2-6f3b-7d2a-9d6e-1a2b3c4d5e6f",
    "journeyType": "IDENTITY_DELIVERY",
    "journeyStatus": "COMPLETED",
    "externalReference": "DMS-88213",
    "customerReference": "5f1c7a9e-6f3b-4d2a-9d6e-1a2b3c4d5e6f",
    "deliveryStatus": "COMPLETED"
  }
}
HeaderMeaning
Mira-Event-IdThe event id. The same event can arrive more than once; use this to ignore repeats.
Mira-Event-TypeThe event type, also in the body.
Mira-TimestampWhen this delivery was signed, in Unix seconds.
Mira-Signaturet=<unix seconds>,v1=<hex HMAC-SHA256>

Verify the signature

v1 is the HMAC-SHA256 of t + "." + raw body, keyed with your endpoint's secret. Compute it over the exact bytes you received, before parsing the JSON, compare in constant time, and reject a t more than 5 minutes old so an old request cannot be replayed.

Node.js
const crypto = require('crypto')

// rawBody must be the exact bytes received, before any JSON parsing.
function verifyMiraSignature(rawBody, header, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
  const t = Number(parts.t)
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false
  const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex')
  const given = Buffer.from(parts.v1 || '', 'hex')
  return given.length === 32 && crypto.timingSafeEqual(given, Buffer.from(expected, 'hex'))
}

Delivery and retries

  • Any 2xx within 10 seconds counts as delivered. Redirects are not followed.
  • Anything else is retried after 1 minute, 5 minutes, 30 minutes, 2, 6, 12 and 24 hours, then given up on.
  • Events can arrive out of order: use createdAt, or read the record, for the latest state.
  • If nothing reaches an endpoint for three days, Mira turns it off and emails your company admin. Fix it, save the URL again to turn it back on, and resend what you missed from the delivery log.

Event catalogue

Every event has id, type, apiVersion, livemode, createdAt and data. Journey events carry the journey's ids and statuses; stock events carry your stock code. Events marked simulatable can be forced with a sandbox key.

Journey

EventWhenSandbox
journey.createdThe journey was accepted.
journey.customer_face_replacedYou replaced the customer photo.
journey.completedThe handover is complete. Nothing more will happen.
journey.cancelledThe journey ended without a handover (cancelled, declined, or the application could not be submitted).
journey.expiredThe customer did not finish in time.

Finance

EventWhenSandbox
finance_enquiry.submittedFINANCE_IDENTITY_DELIVERY only: the application is recorded (and, for SUBMIT_VIA_MIRA, being sent to your panel). Finance events are not sent for IDENTITY_DELIVERY, which is approved from the start.
finance_enquiry.approvedFinance is approved.simulatable
finance_enquiry.declinedFinance is declined. The journey is cancelled.simulatable
finance_enquiry.referredThe lender referred the application. It stays pending.simulatable
finance_enquiry.submission_failedSUBMIT_VIA_MIRA only: the application could not be sent to your panel. data.reason is PANEL_NOT_CONFIGURED, PANEL_ERROR or SUBMISSION_ERROR. The journey is cancelled; start a new one to try again.simulatable

Identity

EventWhenSandbox
identity.requestedThe customer has been asked to verify their identity (finance journeys, IDENTITY_DELIVERY and cash-sale DELIVERY).
identity.verifiedThe customer is verified.simulatable
identity.under_reviewThe check needs a person to look at it.simulatable
identity.failedThe check failed. The customer can try again.simulatable
identity.unavailableThe check could not be started. data.reason is EKYC_NOT_CONFIGURED or PROVIDER_ERROR. The journey stays open and continues once your team resends the check.

Handover

EventWhenSandbox
delivery.createdThe handover exists. data.deliveryStatus says what the customer does first.
delivery.location_confirmedThe customer confirmed the delivery address (home delivery).simulatable
delivery.awaiting_videoThe customer can record their handover video.simulatable
delivery.video_uploadedThe video arrived and is being checked.simulatable
delivery.under_reviewThe video needs your team to review it.simulatable
delivery.completedThe handover was verified.simulatable
delivery.cancelledThe handover was cancelled.simulatable
delivery.expiredThe handover window passed.simulatable

Stock

EventWhenSandbox
stock.vehicle_soldA vehicle you sent through the vehicle stock API sold through Mira. data has your stockCode, the vehicleId, soldAt and saleType.

Other

EventWhenSandbox
pingSent when you press "Send test event" in settings.