Skip to main content
Migo Docs

Cardholder Management

A cardholder is a user who owns a Migo card. This page is the canonical reference for registering and managing cardholders on the Wallet Gateway. It is organized in two parts:

All endpoints require a valid JWT (Authorization: Bearer <token>).


Register a cardholder​

POST /users registers a new cardholder. It requires the USER_REGISTRATION application permission and supports two modes, chosen by the gateway from the request body:

  • invitationCode present β†’ validated as ExternalUserRegistrationDto (registration via a branch invitation code).
  • otherwise β†’ validated as CreateUserDto (direct registration with personal information).

Only the Authorization header is required; x-user-token does not apply to this endpoint.

Mode 1 β€” Branch invitation code​

curl -X POST https://api.ali.app/rest/users \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"deviceId": "device-0000",
"invitationCode": "INV-0000",
"username": "user@example.com",
"password": "<password>",
"confirmPassword": "<password>",
"termsAndConditionsAccepted": true
}'
FieldTypeRequiredNotes
deviceIdstringyesUnique identifier of the device that started the registration
invitationCodestringyesBranch invitation code that grants access to register
usernamestring (email)yesEmail address used as the username
passwordstringyesAccount password (non-empty)
confirmPasswordstringyesMust match password
nitstringnoTax identification number (NIT)
termsAndConditionsAcceptedbooleannoWhether terms and conditions were accepted

Mode 2 β€” Direct registration​

curl -X POST https://api.ali.app/rest/users \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Example",
"lastName": "User",
"address": "Example address",
"countryOfBirth": "GTM",
"placeOfBirth": "Example City",
"gender": "M",
"maritalStatus": "soltero",
"phoneNumber": "+50200000000",
"username": "user@example.com",
"dateOfBirth": "1990-01-01",
"termsAndConditionsAccepted": true,
"identificationDocuments": [
{ "documentNumber": "XXXXXXXXXXXXX", "documentType": "DPI" }
]
}'
FieldTypeRequiredNotes
firstNamestringyesFirst name
lastNamestringyesLast name
addressstringyesResidential address
countryOfBirthCountry enumyesISO alpha-3 code (e.g. GTM). Alpha-2 input is normalized to alpha-3 by the gateway
placeOfBirthstringyesFree text
genderGender enumyesM, F or OTHER
phoneNumberstringyesPhone number in international format
dateOfBirthstringyesYYYY-MM-DD
identificationDocumentsarrayyesArray of { documentNumber, documentType } (both strings, e.g. documentType: "DPI")
usernamestring (email)noEmail address used as the username
maritalStatusMaritalStatus enumnosoltero, casado, viudo, divorciado or separado
neighborhoodstringnoNeighborhood or district
termsAndConditionsAcceptedbooleannoWhether terms and conditions were accepted
additionalDataobjectnoAdditional user metadata

There is no top-level email / documentId / birthDate in either mode β€” the email is username, and identity documents live in identificationDocuments.

Response​

Both modes return the standard response envelope; on success the created user is returned under data:

{ "success": true, "data": { } }

On error, success is false and errors carries the detail. The envelope fields are success (boolean), optional message, optional data, and optional errors (array of { message, code }).

Generate an invitation code (for Mode 1)​

The branch invitation code consumed by Mode 1 is created with POST /users/invitation-code (InvitationCodeGenerateDto):

curl -X POST https://api.ali.app/rest/users/invitation-code \
-H "Authorization: Bearer <token>" \
-H "x-user-token: <user-token>" \
-H "Content-Type: application/json" \
-d '{ "branchId": 24, "role": "owner" }'

role is one of owner, admin, cashier. The full onboarding flow is described in Tap to Phone β†’ SDK install and Terminal Payments.


Manage a cardholder​

Find a cardholder​

GET /users retrieves a single user filtered by either id (numeric) or username (email) β€” at least one is required:

curl "https://api.ali.app/rest/users?username=user@example.com" \
-H "Authorization: Bearer <token>" \
-H "x-application-id: YOUR_APP_ID"

Account states​

The auth_user.status values are:

StateMeaning
PendingAccount created, not yet activated
ActiveFully onboarded
InactiveDeactivated
BlockedDisabled (fraud, KYC issue, customer request)
PasswordResetRequiredMust reset password before continuing

There is no profile-update PATCH endpoint; card status changes go through the card block/unblock endpoints (see Card Lifecycle).

Verify a password​

POST /users/{userId}/auth validates a password against the user's credentials β€” used for step-up confirmation before sensitive actions (VerifyPasswordDto):

curl -X POST "https://api.ali.app/rest/users/{userId}/auth" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "password": "<password>" }'

Profile image​

PUT /users/{userId}/profile-image accepts a multipart/form-data upload with the field profileImage (max 5 MB; png, jpeg, jpg):

curl -X PUT "https://api.ali.app/rest/users/{userId}/profile-image" \
-H "Authorization: Bearer <token>" \
-F "profileImage=@avatar.jpg"

Push notification tokens​

Register and remove the cardholder's FCM (Firebase Cloud Messaging) token so the platform can deliver push notifications:

# Register
curl -X POST "https://api.ali.app/rest/users/fcm-tokens" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "token": "fcm-token-abc123xyz" }'

# Remove (on logout / token rotation) β€” returns 204 No Content
curl -X DELETE "https://api.ali.app/rest/users/fcm-tokens/{token}" \
-H "Authorization: Bearer <token>"

Roles​

List the available roles and add/remove roles for a user:

# List roles
curl https://api.ali.app/rest/users/roles \
-H "Authorization: Bearer <token>"

# Add / remove roles for a user
curl -X PATCH https://api.ali.app/rest/users/{id}/roles \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "addRoles": ["SHOP_ADMIN"], "removeRoles": [] }'