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.
/v1/consents/authCreate a consent session (LOGIN, TRANSACTION, SIGNATURE, OAUTH)
/v1/consents/auth/:sessionIdRetrieve consent session details
/v1/consents/qr/:type/:sessionIdFetch the QR code image (PNG)
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"
}
}'{
"code": 201,
"error": false,
"message": "Consent created successfully",
"data": {
"sessionId": "b0f2…",
"qr": "<base64 png>",
"status": "pending"
}
}Identity verification
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.
/v1/oauth/requestsCreate an OAuth QR approval request
/v1/oauth/requests/statusPoll a request and receive approved claims
/v1/oauth/tokenExchange an approved authorization code for scoped claims
Create request body
| Field | Type | Required | Description |
|---|---|---|---|
| recipient | string | Yes | Enrolled MID phone number |
| redirectUri | string | Yes | Browser return URL registered for the application |
| codeChallenge | string | Yes | PKCE challenge generated from your code verifier |
| codeChallengeMethod | string | No | S256 by default; plain is also accepted |
| claims | string[] | No | Claim keys the user is asked to share |
| scopes | string[] | No | OAuth scopes associated with the grant |
| callbackUrl | string | No | Webhook destination; defaults to the application's callback URL |
| state | string | No | Opaque merchant state returned unchanged |
| description | string | No | Message shown with the approval 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"
}'{
"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"
}
}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…" }'{
"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.
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"
}'{
"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
400 Invalid or expired authorization code.FIDO / WebAuthn
Passwordless authentication using FIDO2 and WebAuthn standards.
/v1/auth/fido/register/beginBegin FIDO2 registration
/v1/auth/fido/register/completeComplete FIDO2 registration
/v1/auth/fido/authenticate/beginBegin FIDO2 authentication
/v1/auth/fido/authenticate/completeComplete FIDO2 authentication
FIDO2 Flow
Device Management
Manage registered devices and their authentication capabilities.
/v1/devicesList all registered devices
/v1/devices/:idGet device details
/v1/devices/:idDeregister a device
/v1/devices/:id/blockBlock 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.
/v1/merchants/applicationsCreate an application and issue sandbox credentials
/v1/merchants/applications/:id/rotate-keyRotate an active sandbox or live API key
{
"name": "Acme Onboarding",
"callbackUrl": "https://acme.com/api/mid/webhook",
"redirectUris": ["https://acme.com/mid/callback"],
"requestTypes": ["LOGIN", "TRANSACTION", "SIGNATURE", "OAUTH"]
}{
"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 }
}
}
}// 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
Enrollments
User enrollment and identity provisioning endpoints.
/v1/enrollmentsCreate a new enrollment
/v1/enrollments/:idGet enrollment status
/v1/enrollments/:id/verifyVerify enrollment with biometrics
QR Code Operations
Generate and manage QR codes for authentication and consent flows.
/v1/qr/generateGenerate a new QR code
/v1/qr/:idGet QR code status
/v1/qr/:id/imageGet QR code image (PNG/SVG)
Rate Limits
| Plan | Requests/min | Daily Limit | Concurrent |
|---|---|---|---|
| Free | 60 | 1,000 | 5 |
| Basic ($79/mo) | 300 | 50,000 | 25 |
| Growth ($149/mo) | 1,000 | 500,000 | 50 |
| Enterprise ($499/mo) | Custom | Unlimited | Custom |
Error Responses
| Code | Type | Description |
|---|---|---|
| 400 | bad_request | The request was malformed or missing required fields |
| 401 | unauthorized | Invalid or missing API key |
| 403 | forbidden | API key lacks required permissions |
| 404 | not_found | The requested resource does not exist |
| 409 | conflict | The request conflicts with an existing resource |
| 422 | validation_error | Request body failed validation |
| 429 | rate_limited | Too many requests — retry after cooldown |
| 500 | server_error | Internal server error (rare) |
Webhooks
Configure webhook endpoints to receive real-time event notifications.
| Event | Trigger |
|---|---|
| consent.created | New consent session initiated |
| consent.approved | Recipient approved the consent |
| consent.rejected | Recipient rejected the consent |
| consent.expired | Consent session timed out |
| auth.success | Successful authentication event |
| auth.failed | Failed authentication attempt |
| device.registered | New device registered |
| device.deregistered | Device was removed |
| enrollment.completed | User enrollment finished |
| mandate.signed | Digital mandate was signed |
Webhook Security