API Reference

API Reference

Complete reference for the MID REST API. Server-to-server endpoints are authenticated with a signed X-API-Key request — see Authentication.

Consent Sessions

Create and manage user consent flows for identity verification and data sharing.

POST
/v1/consents/auth

Create a consent session (LOGIN, TRANSACTION, SIGNATURE, OAUTH)

GET
/v1/consents/auth/:sessionId

Retrieve consent session details

GET
/v1/consents/qr/:type/:sessionId

Fetch the QR code image (PNG)

Create consent session
curl -X POST 'https://api.mobid.io/v1/consents/auth' \
  -H 'Content-Type: application/json' \
  -d '{
    "clientId": "your_client_id",
    "recipient": "+2348012345678",
    "intent": "LOGIN",
    "callbackUrl": "https://yourapp.com/api/mid/webhook",
    "transaction": {
      "type": "LOGIN",
      "description": "Sign in to YourApp",
      "amount": 0,
      "currency": "NGN",
      "payee": "your_client_id"
    }
  }'
Response
{
  "code": 201,
  "error": false,
  "message": "Consent created successfully",
  "data": {
    "sessionId": "b0f2…",
    "qr": "<base64 png>",
    "status": "pending"
  }
}

Identity verification

To request verified identity claims, use the OAUTH intent — see Verify with MID.

OAuth Access

Create QR-backed OAuth access requests for user-approved claim transfer. MID releases scoped claims only after the user scans the QR and approves with biometric authentication.

POST
/v1/oauth/requests

Create an OAuth QR approval request

POST
/v1/oauth/requests/status

Poll a request and receive approved claims

POST
/v1/oauth/token

Exchange an approved authorization code for scoped claims

Create request body

FieldTypeRequiredDescription
recipientstringYesEnrolled MID phone number
redirectUristringYesBrowser return URL registered for the application
codeChallengestringYesPKCE challenge generated from your code verifier
codeChallengeMethodstringNoS256 by default; plain is also accepted
claimsstring[]NoClaim keys the user is asked to share
scopesstring[]NoOAuth scopes associated with the grant
callbackUrlstringNoWebhook destination; defaults to the application's callback URL
statestringNoOpaque merchant state returned unchanged
descriptionstringNoMessage shown with the approval request
Create OAuth request
curl -X POST 'https://api.mobid.io/v1/oauth/requests' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: mk_test_your_key' \
  -H 'X-Timestamp: 1736942400000' \
  -H 'X-Signature: your_hmac_signature' \
  -d '{
    "recipient": "+2348000000000",
    "redirectUri": "https://merchant.example.com/oauth/callback",
    "state": "merchant_state_123",
    "codeChallenge": "S256_pkce_challenge",
    "claims": ["name", "email", "phone"],
    "scopes": ["openid", "profile"],
    "description": "Share your verified profile with Merchant"
  }'
Create response
{
  "error": false,
  "message": "OAuth request created",
  "data": {
    "sessionId": "b0f2…",
    "qr": "<base64 png>",
    "status": "pending",
    "type": "OAUTH",
    "redirectUri": "https://merchant.example.com/oauth/callback",
    "state": "merchant_state_123"
  }
}
Poll request status
curl -X POST 'https://api.mobid.io/v1/oauth/requests/status' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: mk_test_your_key' \
  -H 'X-Timestamp: 1736942400000' \
  -H 'X-Signature: your_hmac_signature' \
  -d '{ "sessionId": "b0f2…" }'
Approved status response
{
  "error": false,
  "data": {
    "sessionId": "b0f2…",
    "status": "APPROVED",
    "recipient": "+2348000000000",
    "scopes": ["openid", "profile"],
    "claims": {
      "name": {
        "value": "Ada Obi",
        "verified": true,
        "verificationStatus": "verified",
        "verificationSource": "mid",
        "verifiedAt": "2026-06-19T10:32:05.000Z"
      }
    },
    "approvedAt": "2026-06-19T10:32:05.000Z"
  }
}

While approval is outstanding, the same endpoint returns status: "PENDING" and omits claims and approvedAt. A session can only be queried by the application that created it.

Token exchange
curl -X POST 'https://api.mobid.io/v1/oauth/token' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: mk_test_your_key' \
  -H 'X-Timestamp: 1736942400000' \
  -H 'X-Signature: your_hmac_signature' \
  -d '{
    "code": "mac_authorization_code",
    "codeVerifier": "original_pkce_verifier"
          }'
Token response
{
  "error": false,
  "token_type": "Bearer",
  "access_token": "mat_…",
  "expires_in": 3600,
  "subject": "+2348000000000",
  "scopes": ["openid", "profile"],
  "claims": {
    "name": { "value": "Ada Obi", "verified": true }
  },
  "state": "merchant_state_123"
}

Authorization codes are single-use

A successful token exchange marks the approved grant as exchanged. Reusing the code returns 400 Invalid or expired authorization code.

FIDO / WebAuthn

Passwordless authentication using FIDO2 and WebAuthn standards.

POST
/v1/auth/fido/register/begin

Begin FIDO2 registration

POST
/v1/auth/fido/register/complete

Complete FIDO2 registration

POST
/v1/auth/fido/authenticate/begin

Begin FIDO2 authentication

POST
/v1/auth/fido/authenticate/complete

Complete FIDO2 authentication

FIDO2 Flow

FIDO2 operations follow a two-step pattern: begin (server generates a challenge) and complete (client signs the challenge with a biometric authenticator).

Device Management

Manage registered devices and their authentication capabilities.

GET
/v1/devices

List all registered devices

GET
/v1/devices/:id

Get device details

DELETE
/v1/devices/:id

Deregister a device

POST
/v1/devices/:id/block

Block a device

Merchant Application Access

Merchant applications own callback settings, allowed request types, and API credentials. These management calls use the dashboard's merchant JWT, not HMAC request signing.

POST
/v1/merchants/applications

Create an application and issue sandbox credentials

POST
/v1/merchants/applications/:id/rotate-key

Rotate an active sandbox or live API key

Create application request
{
  "name": "Acme Onboarding",
  "callbackUrl": "https://acme.com/api/mid/webhook",
  "redirectUris": ["https://acme.com/mid/callback"],
  "requestTypes": ["LOGIN", "TRANSACTION", "SIGNATURE", "OAUTH"]
}
Create application response
{
  "error": false,
  "message": "Application created",
  "application": {
    "id": "665f…",
    "clientId": "acmeonboar_a1b2c3d4e5",
    "name": "Acme Onboarding",
    "callbackUrl": "https://acme.com/api/mid/webhook",
    "redirectUris": ["https://acme.com/mid/callback"],
    "requestTypes": ["LOGIN", "TRANSACTION", "SIGNATURE", "OAUTH"],
    "environment": "sandbox",
    "liveStatus": "sandbox",
    "credentials": {
      "sandbox": {
        "apiKey": "mk_test_…",
        "secret": "…",
        "generatedAt": "2026-06-19T10:30:00.000Z"
      },
      "live": { "apiKey": null, "generatedAt": null }
    }
  }
}
Rotate key request and response
// Request body
{ "environment": "sandbox" }

// 200 response
{
  "error": false,
  "message": "API key rotated successfully",
  "credential": {
    "environment": "sandbox",
    "apiKey": "mk_test_…",
    "generatedAt": "2026-06-19T11:15:00.000Z"
  }
}

Key-rotation behavior

Rotation is available to merchant owners, admins, and developers. The old API key is invalidated immediately, while the application secret stays unchanged and is not returned in the response.

Enrollments

User enrollment and identity provisioning endpoints.

POST
/v1/enrollments

Create a new enrollment

GET
/v1/enrollments/:id

Get enrollment status

POST
/v1/enrollments/:id/verify

Verify enrollment with biometrics

QR Code Operations

Generate and manage QR codes for authentication and consent flows.

POST
/v1/qr/generate

Generate a new QR code

GET
/v1/qr/:id

Get QR code status

GET
/v1/qr/:id/image

Get QR code image (PNG/SVG)

Rate Limits

PlanRequests/minDaily LimitConcurrent
Free601,0005
Basic ($79/mo)30050,00025
Growth ($149/mo)1,000500,00050
Enterprise ($499/mo)CustomUnlimitedCustom

Error Responses

CodeTypeDescription
400bad_requestThe request was malformed or missing required fields
401unauthorizedInvalid or missing API key
403forbiddenAPI key lacks required permissions
404not_foundThe requested resource does not exist
409conflictThe request conflicts with an existing resource
422validation_errorRequest body failed validation
429rate_limitedToo many requests — retry after cooldown
500server_errorInternal server error (rare)

Webhooks

Configure webhook endpoints to receive real-time event notifications.

EventTrigger
consent.createdNew consent session initiated
consent.approvedRecipient approved the consent
consent.rejectedRecipient rejected the consent
consent.expiredConsent session timed out
auth.successSuccessful authentication event
auth.failedFailed authentication attempt
device.registeredNew device registered
device.deregisteredDevice was removed
enrollment.completedUser enrollment finished
mandate.signedDigital mandate was signed

Webhook Security

Always verify webhook signatures using your webhook secret. Respond with a 200 status within 5 seconds to avoid retries.