Skip to main content

The referenceId

The referenceId is the foundation of user management in M2M. It’s your unique identifier for a user, and M2M uses it to:
  • Identify returning users - Skip verification for known users
  • Track CIP status - Know if a user has completed identity verification
  • Manage data requests - Request only missing data
  • Link transactions - Connect multiple transactions to the same user
Always use the same referenceId for the same user. Using different IDs for the same person creates duplicate users and increases friction.

How M2M uses referenceId

When you create a link, M2M checks: When a referenceId appears for the first time:
  1. M2M creates a new user record
  2. Stores any userData you provided
  3. Evaluates what data is missing for CIP
  4. If webhooks are configured and data is incomplete, sends user.data_request
  5. User completes any remaining verification in the widget
When you create a link for an existing referenceId:
  1. M2M finds the existing user record
  2. Merges any new userData (respecting precedence rules)
  3. Checks if CIP was already completed
  4. If CIP is complete, user skips verification entirely
  5. If CIP is incomplete, only missing steps are shown
Key benefit: Once a user completes CIP, future links for that user are frictionless - they go straight to the transaction.

User states

M2M tracks these states for each user:
StateDescription
pendingUser created, no activity yet
data_incompleteMissing data for CIP
data_completeAll CIP data collected
cip_pendingCIP verification in progress
cip_verifiedIdentity verified
cip_failedVerification failed (needs review)

State transitions

Data management

What M2M stores

For each user (identified by referenceId), M2M stores:
  • User data (name, ID, DOB, etc.)
  • Data source for each field (API, webhook, or widget)
  • CIP verification status
  • Transaction history reference

Data precedence

When the same field comes from multiple sources:
PrioritySourceWhen it’s set
1 (highest)partner_apiLink creation with userData
2partner_webhookData request response
3 (lowest)widgetUser input in widget
Higher priority data is never overwritten. If you send firstName via API, a webhook response with a different firstName is ignored.

Updating user data

To update user data for an existing user, provide new values when creating a new link:
{
  "referenceId": "user_12345",
  "userData": {
    "paymentMethod": {
      "type": "bank_account",
      "bankAccount": {
        "country": "MX",
        "accountNumber": "098765432109876543"
      }
    }
  }
}
Only fields you include are updated. Existing data is preserved. Each link goes through its own lifecycle, independent of user state:
StatusDescription
createdLink generated, not opened
openedUser opened the link
in_progressUser is in the widget flow
completedTransaction completed
expiredLink expired
revokedLink manually revoked
M2M enforces a single active link per user. If you try to create a link for a user with an active link:
{
  "success": false,
  "error": {
    "code": "ACTIVE_LINK_EXISTS",
    "message": "User already has an active link",
    "existingLinkId": "link_acme_abc123"
  }
}
To create a new link:
  1. Wait for the existing link to expire or complete, OR
  2. Revoke the existing link via API (coming soon)

Best practices

Use your primary user ID as the referenceId. Don’t use:
  • Session IDs (change each visit)
  • Email addresses (users can change them)
  • Phone numbers (can be recycled)
Good: user_12345, usr_abc123def456 Bad: session_xyz, john@example.com
If you merge user accounts in your system, you may have multiple referenceIds for the same person. Options:
  • Continue using the original ID
  • Create a mapping in your system
  • Contact support for account merging
Cache the user’s CIP status in your system to:
  • Show different UI for verified vs. unverified users
  • Skip unnecessary data collection
  • Predict user journey time
Always provide the same data for the same user. Inconsistent data can:
  • Trigger unnecessary data requests
  • Cause CIP verification issues
  • Confuse the user

Example: Complete user journey

Here’s how a typical user progresses through M2M:

First transaction

// Partner creates first link with partial data
POST /partner/links
{
  "referenceId": "user_12345",
  "userData": {
    "name": { "firstName": "Juan", "lastName": "Garcia" }
  }
}

// M2M sends webhook for missing data
{
  "event": "user.data_request",
  "data": {
    "requiredFields": ["name.secondName", "idNumber", "dob"]
  }
}

// Partner responds with data
PUT /partner/data-requests/dr_123
{
  "userData": {
    "name": { "secondName": "Carlos" },
    "idNumber": "GALO900515",
    "dob": "1990-05-15"
  }
}

// User opens link, completes CIP, makes transaction
// Status: cip_verified

Second transaction (frictionless)

// Partner creates second link - same referenceId
POST /partner/links
{
  "referenceId": "user_12345"  // No userData needed!
}

// M2M recognizes verified user
// No webhook sent - data is complete
// User opens link, skips CIP, makes transaction immediately

Third transaction (new payment method)

// Partner creates link with updated payment method
POST /partner/links
{
  "referenceId": "user_12345",
  "userData": {
    "paymentMethod": {
      "type": "bank_account",
      "bankAccount": {
        "country": "MX",
        "accountNumber": "098765432109876543"
      }
    }
  }
}

// M2M updates payment method, user is still verified
// Smooth transaction with new payment destination

Next steps

User Data Guide

Understand the friction vs. integration trade-off.

Data Requests

Handle webhooks for missing user data.