Users
Manage users, update user information, and order cards
Overview
The Users endpoints allow you to create new users, update existing user information, and order cards for users. All endpoints require authentication using a Bearer token obtained from the authentication endpoint.
Authorization: Bearer {access_token} header and the x-appid: {clientId} header in your requests.
Create User
Creates a new user in the system. The user will be associated with the company specified in the request.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
firstname |
string | Yes | User's first name (max 50 characters) |
lastname |
string | Yes | User's last name (max 50 characters) |
email |
string | Yes | User's email address (must be unique within the company) |
companyId |
string | Yes | The ID of the company this user belongs to |
active |
boolean | No | Whether the user is active (default: false). Set to true to skip activation step. |
reason |
string | No | User status reason. Use "active" for active users. |
emailVerified |
boolean | No | Whether the email has been verified (default: false) |
mobile |
string | No | User's mobile phone number |
employeeId |
string | No | Employee ID or external identifier |
Example Request
Using cURL:
curl -X POST https://sandbox.custodia-tech.com/md/api/User \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"companyId": "your-company-id",
"active": true,
"reason": "active",
"emailVerified": true
}'
Using JavaScript (fetch):
const response = await fetch('https://sandbox.custodia-tech.com/md/api/User', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
firstname: 'John',
lastname: 'Doe',
email: 'john.doe@example.com',
companyId: 'your-company-id',
active: true,
reason: 'active',
emailVerified: true
})
});
const user = await response.json();
Response
Success Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"companyId": "your-company-id",
"active": true,
"reason": "active",
"emailVerified": true,
"created": "2024-01-15T10:30:00.000Z",
"modified": "2024-01-15T10:30:00.000Z"
}
Update User
Updates an existing user's information. Only include the fields you want to update in the request body.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId |
string | Yes | The unique identifier of the user to update |
Request Body
Include only the fields you want to update. All fields are optional.
| Parameter | Type | Description |
|---|---|---|
firstname |
string | User's first name |
lastname |
string | User's last name |
email |
string | User's email address |
mobile |
string | User's mobile phone number |
employeeId |
string | Employee ID or external identifier |
office |
string | Office phone number |
extension |
string | Phone extension |
Example Request
Using cURL:
curl -X PATCH https://sandbox.custodia-tech.com/md/api/User/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"firstname": "Jane",
"mobile": "+1234567890"
}'
Using JavaScript (fetch):
const userId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/User/${userId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
firstname: 'Jane',
mobile: '+1234567890'
})
});
const updatedUser = await response.json();
Response
Success Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"firstname": "Jane",
"lastname": "Doe",
"email": "john.doe@example.com",
"mobile": "+1234567890",
"modified": "2024-01-15T11:00:00.000Z"
}
Order Card for User
Orders a new card for a user. The card will be associated with a card product. If no card product is specified, the system will use the default card product for the user's company.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId |
string | Yes | The unique identifier of the user to order a card for |
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
cardProductId |
string | No | The ID of the card product to use. If not provided, the default card product for the company will be used. |
instructions |
object | No | Additional instructions for card ordering. See below for available options. |
Instructions Object
The instructions object can contain the following optional fields:
| Parameter | Type | Description |
|---|---|---|
address2use |
string | Address to use for shipping. Options: "user" (user's address), "business" (company address) |
expedite |
boolean | Whether to expedite the card shipment (if supported by the card provider) |
Example Request
Using cURL:
curl -X POST https://sandbox.custodia-tech.com/md/api/User/550e8400-e29b-41d4-a716-446655440000/order-card \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"cardProductId": "card-product-id",
"instructions": {
"address2use": "user",
"expedite": false
}
}'
Using JavaScript (fetch):
const userId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/User/${userId}/order-card`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
cardProductId: 'card-product-id',
instructions: {
address2use: 'user',
expedite: false
}
})
});
const card = await response.json();
Ordering with default card product (no cardProductId):
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/User/${userId}/order-card`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
instructions: {
address2use: 'user'
}
})
});
Response
Success Response (200 OK)
{
"id": "card-id-123",
"ownerId": "550e8400-e29b-41d4-a716-446655440000",
"cardProductId": "card-product-id",
"cardNo": "****1234",
"state": "UNACTIVATED",
"cardType": "physical",
"created": "2024-01-15T12:00:00.000Z"
}
Terminate Card
Terminates (cancels) a card for a user. Once terminated, the card cannot be used for transactions. This action is typically irreversible.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId |
string | Yes | The unique identifier of the user who owns the card |
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
pan |
string | Yes | The last 4 digits of the card number (Primary Account Number). This is used to identify the specific card to terminate. |
reasonCode |
string | Yes | A code indicating the reason for termination. Common values: "01" (requested by user/admin), "09" (card reissued), etc. |
issuer |
string | No | The card issuer/vendor. Defaults to "marqeta" if not provided. Options: "marqeta", "dipocket", "icc" |
reason |
string | No | A human-readable description of why the card is being terminated (e.g., "Lost card", "Requested by admin", "Card reissued") |
Example Request
Using cURL:
curl -X POST https://sandbox.custodia-tech.com/md/api/User/550e8400-e29b-41d4-a716-446655440000/terminate-card \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"pan": "1234",
"reasonCode": "01",
"reason": "Card lost - requested by user",
"issuer": "marqeta"
}'
Using JavaScript (fetch):
const userId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/User/${userId}/terminate-card`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
pan: '1234',
reasonCode: '01',
reason: 'Card lost - requested by user',
issuer: 'marqeta'
})
});
const terminatedCard = await response.json();
Terminating with default issuer (marqeta):
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/User/${userId}/terminate-card`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
pan: '1234',
reasonCode: '01',
reason: 'Requested by admin'
})
});
Response
Success Response (200 OK)
{
"id": "card-id-123",
"ownerId": "550e8400-e29b-41d4-a716-446655440000",
"cardNo": "****1234",
"state": "TERMINATED",
"cardType": "physical",
"vendor": "marqeta",
"terminatedOn": "2024-01-15T14:00:00.000Z"
}
pan parameter should be the last 4 digits of the card number. You can retrieve a user's cards to get the card number information before terminating. For ICC cards, use the disassociate-card endpoint instead.
Error Responses
All endpoints may return the following error responses:
| Status Code | Description | Solution |
|---|---|---|
401 Unauthorized |
Invalid or missing access token | Verify your access token is valid and included in the Authorization header |
400 Bad Request |
Invalid request parameters or missing required fields | Check that all required fields are included and have valid values |
404 Not Found |
User not found (for update/order card/terminate card endpoints) or card not found | Verify the user ID and card PAN are correct |
409 Conflict |
User with this email already exists (create user) | Use a different email address or update the existing user |
403 Forbidden |
Insufficient permissions or feature not available | Verify your access token has the required scopes and permissions |
INVALID-USER-STATE error. When terminating a card, make sure the PAN (last 4 digits) matches the card you want to terminate.