MIRA

Journeys API

Base URL https://api.motorsync.co.uk/api/v1/journeys. API version 1.0.0.

Authentication

Send your company's developer key as a bearer token on every request:Authorization: Bearer ms_live_.... Keys are created, rotated and given an expiry in MIRA Business under Settings, API Keys, by the company owner. Rotating a key stops the old one immediately.

A key belongs to one company. A dealer's key can start every journey type; a broker's key can start every finance sale. Everything a key can see is limited to journeys its company started.

Sandbox

Test keys (ms_test_) run the same API against simulated journeys. They never create a real customer or handover, never charge your wallet, and never email a customer: journey emails go to your company admin instead, marked TEST. Photos you send are still checked, then thrown away. Responses and webhooks say"livemode": false.

A test journey moves on by itself every few seconds. To force an outcome, callPOST /{journeyId}/simulate with an event from the catalogue marked simulatable. Live and test data never mix: a live key cannot see test journeys, and the other way round.

Idempotency

Starting a journey needs an Idempotency-Key header (8 to 255 letters, digits, or . _ : -), unique per journey. Use something from your own system, such as your deal number. Sending the same key again with the same body returns the original journey with status 200 and an Idempotent-Replayed: trueheader instead of starting a second one, so it is always safe to retry after a timeout or a 503. The same key with a different body is refused withIDEMPOTENCY_KEY_REUSED. If a request fails, nothing is kept and you can retry with the same key.

Responses

Every response uses the same envelope. On failure, errors[0].code is the stable code to act on.

202 Accepted
{
  "success": true,
  "data": {
    "id": "0192f1c2-6f3b-7d2a-9d6e-1a2b3c4d5e6f",
    "type": "IDENTITY_DELIVERY",
    "status": "ACTIVE",
    "livemode": false,
    "externalReference": "DMS-88213",
    "customerReference": "5f1c7a9e-6f3b-4d2a-9d6e-1a2b3c4d5e6f",
    "delivery": null,
    "finance": null,
    "identity": { "status": null },
    "nextAction": "CUSTOMER_TO_VERIFY_IDENTITY",
    "createdAt": "2026-09-25T10:15:02Z"
  },
  "message": "Journey started",
  "errors": null
}
422 Unprocessable
{
  "success": false,
  "data": null,
  "message": "Identity verification is not set up for this company. Configure it in MIRA Business first.",
  "errors": [{ "field": "journey", "code": "EKYC_NOT_CONFIGURED", "message": "..." }]
}

Starting a journey

POST https://api.motorsync.co.uk/api/v1/journeys. Use the customer's own email address: it is where MIRA sends their sign-in links. The journey identifies the customer with its own customerReference. Pick the journey that matches what has already happened outside MIRA:

typeUse it whenWhat MIRA does
FINANCE_IDENTITY_DELIVERYThe full flow for a financed sale: the finance application, then the customer's identity check, then the verified handover.You send the deal. Either it is already on your own finance panel (ALREADY_SUBMITTED, with your panel reference), or you send the full application and MIRA submits it to your configured panel (SUBMIT_VIA_MIRA). The customer gets a sign-in link and verifies their identity in the app. The lender decision comes from you (ALREADY_SUBMITTED) or from the panel (SUBMIT_VIA_MIRA). Once finance is approved and the customer is verified, the handover is created and the customer completes it in the app.
IDENTITY_DELIVERYFor a financed sale already approved on your own panel. You send who to verify; MIRA runs the identity check, tells you the result, then runs the handover.You send the customer, vehicle and handover details, and optionally your panel name, reference and lender. No finance application is needed: it is recorded as approved. The customer gets a sign-in link and verifies their identity in the app. As soon as they are verified, the handover is created and the customer completes it in the app.
DELIVERYA verified handover with no finance application in MIRA. Say whether it is a cash sale or a finance sale.CASH_SALE: the customer verifies their identity and, for a home delivery, confirms their address in the app, then completes the handover. FINANCE_SALE: the finance and identity checks happened outside MIRA, so you send a photo of the customer with their consent, used to verify the handover. A match completes the handover; anything unclear goes to your team to review.
IDENTITY_DELIVERY
curl -X POST https://api.motorsync.co.uk/api/v1/journeys \
  -H "Authorization: Bearer ms_test_..." \
  -H "Idempotency-Key: deal-88213" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "IDENTITY_DELIVERY",
    "externalReference": "DMS-88213",
    "customer": {
      "firstName": "Jane", "lastName": "Doe",
      "email": "jane@example.com", "mobile": "07700900000"
    },
    "vehicle": { "registration": "AB21XYZ", "make": "BMW", "model": "3 Series", "year": 2021 },
    "delivery": { "type": "HOME_DELIVERY" },
    "finance": { "panelName": "iVendi", "panelReference": "IV-123456", "lender": "Close Brothers" }
  }'

Request fields

Required means the request is refused without it. Codes must be sent exactly as listed. Anything not listed for a journey type is refused rather than ignored, so you never believe a field is being used when it is not.

Top level

FieldRequiredRules
typeAlwaysFINANCE_IDENTITY_DELIVERY, IDENTITY_DELIVERY or DELIVERY
externalReferenceNoYour own id for the deal, up to 100 characters. You can list journeys by it.
externalCompanyNameNoThe selling company's name, for example the dealer a broker is working with, up to 255 characters
customerAlwaysSee below
vehicleAlwaysSee below
deliveryAlwaysSee below
customerFaceDELIVERY with FINANCE_SALE onlySee below. Refused for every other journey.
financeFINANCE_IDENTITY_DELIVERY; optional for IDENTITY_DELIVERYSee below. Refused for DELIVERY.

customer

Use the customer's own email address: it is where MIRA sends their sign-in links.

FieldRequiredRules
firstName, lastNameAlwaysUp to 100 characters each
emailAlwaysA valid email, up to 255 characters
mobileSUBMIT_VIA_MIRA10 to 20 characters: digits, spaces, + - ( )
titleSUBMIT_VIA_MIRAMR, MRS, MISS, MS or DR
dateOfBirthSUBMIT_VIA_MIRAYYYY-MM-DD

vehicle

FieldRequiredRules
registrationAlwaysUp to 20 characters
makeNoUp to 50 characters
modelNoUp to 100 characters
yearNo1900 to 2100
colourNoUp to 50 characters
inventoryVehicleIdNoYour MIRA stock vehicle id; it is marked sold when the handover completes

delivery

FieldRequiredRules
typeAlwaysIN_STORE or HOME_DELIVERY. A home delivery asks the customer to confirm the address in the app.
saleTypeDELIVERY onlyCASH_SALE (identity check in the app) or FINANCE_SALE (you send customerFace). Refused for the other journeys, which are always finance sales.
notesNoUp to 1000 characters, for your team. Never shown to the customer.

customerFace (DELIVERY, FINANCE_SALE)

Sent as a "journey" JSON part plus a "customerFace" file part (JPEG or PNG, one clear face, up to 5 MB) in a multipart request.

FieldRequiredRules
sourceYesIN_PERSON_PHOTO or ID_DOCUMENT_PHOTO
capturedAtNoWhen the photo was taken (ISO 8601)
biometricConsent.givenYesMust be true
biometricConsent.capturedAtYesWhen the customer consented (ISO 8601)
biometricConsent.methodYesSIGNED_IN_PERSON or ONLINE_FORM
biometricConsent.noticeVersionYesThe privacy notice the customer saw, up to 100 characters
biometricConsent.capturedByNoWho took the consent, up to 255 characters

finance

IDENTITY_DELIVERY only takes panelName, panelReference and lender; anything else is refused.

FieldRequiredRules
panelSubmissionFINANCE_IDENTITY_DELIVERYALREADY_SUBMITTED or SUBMIT_VIA_MIRA
panelNameALREADY_SUBMITTEDYour panel, up to 20 characters
panelReferenceALREADY_SUBMITTEDThe application on your panel, up to 100 characters
decisionNo (ALREADY_SUBMITTED only)APPROVED, DECLINED or REFERRED, if already known
lenderNoUp to 50 characters
vehiclePriceSUBMIT_VIA_MIRACash price, above 0
loanTermSUBMIT_VIA_MIRAMonths, 12 to 120
depositAmountNo0 or more (default 0)
monthlyBudgetNo0 or more
maritalStatusNoSINGLE, COHABITING, MARRIED, SEPARATED, DIVORCED, WIDOWED, CIVIL_PARTNERSHIP, DISSOLVED_CIVIL_PARTNERSHIP, ENGAGED
drivingLicenceTypeSUBMIT_VIA_MIRAFULL_UK, PROVISIONAL_UK, CBT, A2, FULL_A_CLASS, EUROPEAN, INTERNATIONAL, NONE
validUkPassportNotrue or false
employmentHistory[]SUBMIT_VIA_MIRAUp to 10 entries, at least one CURRENT. See below.
addressHistory[]SUBMIT_VIA_MIRAUp to 10 entries, exactly one CURRENT, covering at least 3 years in total. See below.
consentsSUBMIT_VIA_MIRASee below

finance.employmentHistory[] (SUBMIT_VIA_MIRA)

FieldRequiredRules
employmentTypeYesCURRENT or PREVIOUS
employmentStatusYesFULL_TIME_EMPLOYMENT, PART_TIME_EMPLOYMENT, SELF_EMPLOYED, RETIRED, HOMEMAKER, CARER, BENEFITS
employerYesUp to 255 characters. For RETIRED, HOMEMAKER, CARER or BENEFITS, send the status in words (for example "Retired").
jobTitleYesUp to 255 characters (as for employer when not employed)
monthlyIncomeYesAbove 0
timeAtEmployerYearsNo0 to 50 (default 0)
timeAtEmployerMonthsNo0 to 11 (default 0)

finance.addressHistory[] (SUBMIT_VIA_MIRA)

FieldRequiredRules
addressTypeYesCURRENT or PREVIOUS
streetYesUp to 255 characters
cityYesUp to 100 characters
postcodeYesUp to 20 characters
buildingNumber, buildingNameNoUp to 20 and 100 characters
subBuildingName, organisationName, countyNoUp to 100 characters
timeAtAddressYearsNo0 to 100 (default 0)
timeAtAddressMonthsNo0 to 11 (default 0)
residentialStatusNoHOMEOWNER, JOINT_OWNER, TENANT_PRIVATE, TENANT_PRIVATE_UNFURNISHED, TENANT_HOUSING_ASSOCIATION, TENANT_COUNCIL, LIVING_WITH_FAMILY, MILITARY_ACCOMMODATION, WORK_ACCOMMODATION, STUDENT_ACCOMMODATION, OTHER

finance.consents (SUBMIT_VIA_MIRA)

The consents the customer gave you for this application. The application goes to the lender panel as soon as it is accepted, so all of them must be true.

FieldRequiredRules
infoAccuracyYestrue: the customer confirmed their details are accurate
motorsyncTermsYestrue: accepted the MIRA terms
providerTermsYestrue: accepted the finance provider's terms and privacy policy
dataSharingYestrue: agreed to share their details with the provider and its lenders
creditCheckYestrue: agreed to a soft credit search
identityVerificationYestrue: agreed to identity verification, including biometric checks
providerNameYesThe finance provider the customer agreed to, up to 255 characters

Identity check and handover (IDENTITY_DELIVERY)

For a financed sale already approved on your own panel. No finance application is needed: MIRA records it as approved, with your panelName, panelReference and lender if you send them. The customer is asked to verify their identity straight away. You are told the result through identity.* events, and as soon as they are verified the handover is created. No photo is needed.

Handover only (DELIVERY)

For a handover with no finance application in MIRA. delivery.saleType says which kind of sale it is:

saleTypeIdentityWho can send it
CASH_SALEThe customer verifies their identity in the MIRA app, and confirms the address for a home delivery.Dealer keys
FINANCE_SALEChecked with the finance, outside MIRA. You send customerFace, used to verify the handover.Dealer or broker keys
DELIVERY, CASH_SALE
curl -X POST https://api.motorsync.co.uk/api/v1/journeys \
  -H "Authorization: Bearer ms_test_..." \
  -H "Idempotency-Key: deal-88215" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "DELIVERY",
    "customer": { "firstName": "Alex", "lastName": "Khan", "email": "alex@example.com" },
    "vehicle": { "registration": "EF23GHI" },
    "delivery": { "type": "HOME_DELIVERY", "saleType": "CASH_SALE" }
  }'

For a FINANCE_SALE, send the request as multipart/form-data with a journey JSON part and a customerFace part: a JPEG or PNG up to 5 MB showing exactly one clear face. It is stored without its metadata and checked before anything is created. Using someone's face this way needs their explicit consent, which you confirm in customerFace.biometricConsent. It is recorded with the handover.

DELIVERY, FINANCE_SALE with a photo
curl -X POST https://api.motorsync.co.uk/api/v1/journeys \
  -H "Authorization: Bearer ms_test_..." \
  -H "Idempotency-Key: deal-88214" \
  -F 'journey={
    "type": "DELIVERY",
    "customer": { "firstName": "Sam", "lastName": "Lee", "email": "sam@example.com" },
    "vehicle": { "registration": "CD22ABC" },
    "delivery": { "type": "IN_STORE", "saleType": "FINANCE_SALE" },
    "customerFace": {
      "source": "IN_PERSON_PHOTO",
      "biometricConsent": {
        "given": true, "capturedAt": "2026-09-25T10:15:00Z",
        "method": "SIGNED_IN_PERSON", "noticeVersion": "privacy-v3", "capturedBy": "Front desk"
      }
    }
  };type=application/json' \
  -F 'customerFace=@sam.jpg;type=image/jpeg'

If the video keeps failing to match, replace the photo with PUT /{journeyId}/customer-face while no video is being checked.

Full flow with finance (FINANCE_IDENTITY_DELIVERY)

Choose how the application reaches a lender with finance.panelSubmission:

panelSubmissionUse it whenThe decision comes from
ALREADY_SUBMITTEDThe deal is already on your own finance panel. Send panelName and panelReference; MIRA never submits it anywhere.You, with POST /{journeyId}/finance-decision, or finance.decision at creation if you already know it
SUBMIT_VIA_MIRAYou want MIRA to submit the application to the finance panel set up in MIRA Business. Send the full application.The panel, automatically
ALREADY_SUBMITTED
"type": "FINANCE_IDENTITY_DELIVERY",
"finance": {
  "panelSubmission": "ALREADY_SUBMITTED",
  "panelName": "iVendi",
  "panelReference": "IV-123456",
  "lender": "Close Brothers",
  "vehiclePrice": 15000, "loanTerm": 48, "depositAmount": 1000
}

For SUBMIT_VIA_MIRA the application goes to the panel as soon as it is accepted, so it must be complete and use the codes listed in Request fields, with at least 3 years of address history and the consents the customer gave you. It is sent with the current job and address first.

SUBMIT_VIA_MIRA
"type": "FINANCE_IDENTITY_DELIVERY",
"customer": { ..., "title": "MRS", "mobile": "07700900000", "dateOfBirth": "1990-04-12" },
"finance": {
  "panelSubmission": "SUBMIT_VIA_MIRA",
  "vehiclePrice": 15000, "loanTerm": 48, "depositAmount": 1000, "monthlyBudget": 350,
  "maritalStatus": "MARRIED", "drivingLicenceType": "FULL_UK", "validUkPassport": true,
  "employmentHistory": [{
    "employmentType": "CURRENT", "employmentStatus": "FULL_TIME_EMPLOYMENT", "employer": "Acme Ltd",
    "jobTitle": "Engineer", "monthlyIncome": 3200, "timeAtEmployerYears": 4, "timeAtEmployerMonths": 2
  }],
  "addressHistory": [{
    "addressType": "CURRENT", "buildingNumber": "12", "street": "High Street", "city": "Leeds",
    "postcode": "LS1 4AB", "timeAtAddressYears": 5, "timeAtAddressMonths": 0, "residentialStatus": "TENANT_PRIVATE"
  }],
  "consents": {
    "infoAccuracy": true, "motorsyncTerms": true, "providerTerms": true, "dataSharing": true,
    "creditCheck": true, "identityVerification": true, "providerName": "CarMoney"
  }
}

The customer is asked to verify their identity once the application is recorded (for SUBMIT_VIA_MIRA, once the panel has accepted it), while the decision is pending. The handover is created only when finance is approved and identity is verified, in either order. A declined application, or one that could not be submitted to the panel (finance_enquiry.submission_failed), ends the journey.

Before accepting a journey that includes an identity check, MIRA checks that identity verification is set up for your company, that a finance panel is set up for SUBMIT_VIA_MIRA, and that the wallets that pay for the checks have enough credit. Each check is billed exactly as when your team starts it in MIRA.

The journey object

status is ACTIVE, COMPLETED, CANCELLED or EXPIRED. delivery has the handoverdelivery.status follows the handover,apos;s statusand, for DELIVERY journeys, its saleType. identity appears on FINANCE_IDENTITY_DELIVERY and IDENTITY_DELIVERY, finance on FINANCE_IDENTITY_DELIVERY only (a cash-sale DELIVERY's identity step shows in delivery.status), and nextAction says what the journey is waiting for:

nextActionMeaning
CUSTOMER_TO_VERIFY_IDENTITYThe customer needs to complete the identity check.
CUSTOMER_TO_CONFIRM_ADDRESSThe customer needs to confirm the delivery address.
CUSTOMER_TO_RECORD_VIDEOThe customer needs to record the handover video.
DEALER_TO_REVIEWYour team needs to review the identity check or video.
IDENTITY_UNDER_REVIEWThe identity check is with a reviewer.
SEND_FINANCE_DECISIONSend the lender decision (ALREADY_SUBMITTED).
AWAITING_LENDER_DECISIONWaiting for the panel decision (SUBMIT_VIA_MIRA).
HANDOVER_BEING_CREATEDFinance is approved and identity verified; the handover is being set up.

Endpoints

MethodPathWhat it does
POST/api/v1/journeysStart a journey. JSON body, or multipart with a "journey" part and a "customerFace" photo for DELIVERY journeys. Needs an Idempotency-Key header. Returns 202, or 200 with an Idempotent-Replayed: true header and the original journey when the same key is replayed.
GET/api/v1/journeys/{journeyId}Get a journey.
GET/api/v1/journeysList journeys. Newest first. Filters: status, externalReference. Paging: page (from 0), size (up to 100).
POST/api/v1/journeys/{journeyId}/cancelCancel a journey. Body: { "reason": "..." } (10 to 500 characters). Refused once the journey has finished.
PUT/api/v1/journeys/{journeyId}/customer-faceReplace the customer photo. DELIVERY journeys only, while no video is being checked. Multipart: "details" (source and consent) and "customerFace".
POST/api/v1/journeys/{journeyId}/finance-decisionReport the lender decision. ALREADY_SUBMITTED finance journeys only. Body: { "decision": "APPROVED" | "DECLINED" | "REFERRED" }.
POST/api/v1/journeys/{journeyId}/simulateForce the next outcome (sandbox). Test keys only. Body: { "event": "delivery.completed" } or any event marked "simulatable" below.

What customers receive

A new customer gets a welcome email first. Then, at each step that needs them (verify identity, confirm the delivery address, record the handover video) they get an email with a one-time sign-in link that opens the MIRA app on that step. They also hear when finance is approved or updated and when the handover is complete. Emails are sent in your company's name.

Webhooks

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.

MIRA sends a POST for each event on journeys you started through the API. By default that is every event; in settings you can choose only some, by name or by whole group (a group also covers events added to it later). The test event is always sent. Events carry ids and statuses only, never personal details: callGET /api/v1/journeys/{journeyId} 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"
  }
}

Check every request. Mira-Signature ist=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256 of t + "." + raw bodykeyed with your secret. Compute it over the exact bytes you received, compare in constant time, and reject at 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'))
}

Answer quickly. 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. The same event can arrive more than once and out of order, so useMira-Event-Id to ignore repeats and createdAt or a fresh GET 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 (journeyId, journeyType, journeyStatus, externalReference, customerReference, deliveryStatus, and financeStatus and identityStatus on finance journeys).

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

Other

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

Errors

StatusCodeWhat to do
400IDEMPOTENCY_KEY_REQUIREDSend an Idempotency-Key header: 8 to 255 letters, digits, or . _ : -
400APPLICATION_INCOMPLETESUBMIT_VIA_MIRA is missing fields, has no single CURRENT address, or less than 3 years of address history. The message says which.
400PANEL_REFERENCE_REQUIREDALREADY_SUBMITTED needs finance.panelName and finance.panelReference.
400PANEL_FIELDS_NOT_USEDSUBMIT_VIA_MIRA does not take panelName, panelReference or decision.
400SALE_TYPE_REQUIRED / SALE_TYPE_NOT_USEDDELIVERY needs delivery.saleType; the other journeys must not send it.
400CUSTOMER_FACE_REQUIRED / CUSTOMER_FACE_NOT_USEDA FINANCE_SALE DELIVERY needs a customerFace photo; every other journey must not send one.
400FINANCE_FIELDS_NOT_USEDIDENTITY_DELIVERY only takes panelName, panelReference and lender.
400INVALID_APPLICATION_VALUEA SUBMIT_VIA_MIRA code (marital status, licence, employment or residential status) is not one the panels accept. The message lists the allowed values.
400UNSUPPORTED_IMAGE_TYPEcustomerFace must be a JPEG or PNG.
401INVALID_API_KEYThe key is wrong, revoked, or not a developer key.
401API_KEY_EXPIREDThe key has passed its expiry date.
403API_KEY_NOT_PERMITTEDThe key may not call this endpoint.
404JOURNEY_NOT_FOUNDNo such journey for this key. Live keys never see test journeys, and the other way round.
409IDEMPOTENCY_KEY_REUSEDThe Idempotency-Key was used before with a different request.
409FINANCE_DECISION_FROM_PANELSUBMIT_VIA_MIRA decisions come from the lender panel.
409FINANCE_ALREADY_DECIDEDA decision is already recorded.
409CUSTOMER_FACE_LOCKEDThe photo cannot change while a video is being checked or after the handover.
409JOURNEY_FINISHEDThe journey has already ended.
422BIOMETRIC_CONSENT_REQUIREDcustomerFace.biometricConsent.given must be true.
422NO_FACE / MULTIPLE_FACES / FACE_TOO_SMALLThe photo must show exactly one clear, large enough face.
422CONSENT_REQUIREDSUBMIT_VIA_MIRA needs every finance consent set to true, and consents.providerName.
422EKYC_NOT_CONFIGUREDIdentity verification is not set up. Set it up in MIRA Business under Settings, Identity Verification.
422FINANCE_PANEL_NOT_CONFIGUREDSUBMIT_VIA_MIRA needs a finance panel set up in MIRA Business.
422INSUFFICIENT_CREDITSThe wallet that pays for these checks needs topping up.
422DEALER_ONLYA cash-sale DELIVERY needs a dealer key.
429RATE_LIMITEDMore than 500 requests in a minute on this key.
503TEMPORARILY_UNAVAILABLETry again with the same Idempotency-Key. Nothing was created.

Limits

  • 500 requests a minute per key; beyond that, 429.
  • Customer photos up to 5 MB, JPEG or PNG.
  • List pages up to 100 journeys.
  • Webhook responses within 10 seconds.