Skip to main content
POST
/
v2
/
account
Create Account
curl --request POST \
  --url https://kyc.sbx.moduluslabs.io/v2/account \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "contact": {
    "email": "[email protected]",
    "phone": "9876543212"
  },
  "user": {
    "firstName": "John",
    "middleName": "Michael",
    "lastName": "Doe",
    "username": "johndoe123",
    "password": "SecureP@ssw0rd!",
    "pin": "1234"
  }
}
'
{
  "id": 12345
}

Overview

Creates a new user account with associated contact information and credentials. This is the first step in the merchant onboarding process.
Account approval required: New accounts are initially registered under Packworks Merchant parent and become visible in the backoffice only after admin approval. Upon approval, a new merchant branch is created and assigned to the account.
Password security: Passwords expire after 90 days from creation. The password is hashed using bcrypt, and the PIN is encrypted using Rijndael encryption.

Rate Limiting

This endpoint is rate limited to 10 requests per 60 seconds per client.

Authentication

This endpoint requires JWT Bearer Token authentication.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
See the Authentication Guide for details on generating JWT tokens.

Request Parameters

Contact Information

contact
object
required
User’s contact information

User Information

user
object
required
User’s personal information and credentials

Response

Success Response

Status Code: 200 OK
id
integer
The unique account ID of the newly created accountUsage: Use this ID for subsequent onboarding steps (JWT token generation, merchant onboarding)Example: 12345
{
  "id": 12345
}
{
  "id": 12345
}

Error Responses

Status Code: 401
{
  "statusCode": 401,
  "message": "Unauthorized",
  "error": "Unauthorized"
}
Cause: Missing or invalid JWT Bearer tokenSolution:
  • Ensure you’re sending the Authorization header with a valid JWT token
  • Verify the JWT token is generated correctly with the proper secret key
  • Check that the token hasn’t expired
Status Code: 400Cause: Request parameters don’t meet validation rulesExamples:
Invalid Password
{
  "statusCode": 400,
  "message": "user.password must have at least 1 uppercase and lowercase character, a number, and special character.",
  "error": "Bad Request"
}
Invalid Email
{
  "statusCode": 400,
  "message": "contact.email is invalid.",
  "error": "Bad Request"
}
Invalid Phone
{
  "statusCode": 400,
  "message": "contact.phone is invalid.",
  "error": "Bad Request"
}
Solution: Ensure all parameters meet the validation requirements listed above
Status Code: 400
{
  "statusCode": 400,
  "message": "Username is not available",
  "error": "Bad Request"
}
Cause: The requested username is already taken by another userSolution: Choose a different username
Status Code: 400
{
  "statusCode": 400,
  "message": "Failed to save account: [error details]",
  "error": "Bad Request"
}
Cause: Failed to save the account to the databaseSolution: Retry the request. If the issue persists, contact support
Status Code: 429
{
  "statusCode": 429,
  "message": "ThrottlerException: Too Many Requests",
  "error": "Too Many Requests"
}
Cause: Rate limit exceeded (more than 10 requests in 60 seconds)Solution: Wait before retrying. Implement exponential backoff in your application
Status Code: 500
{
  "statusCode": 500,
  "message": "Internal server error",
  "error": "Internal Server Error"
}
Cause: Unexpected server errorSolution: Retry the request. If the issue persists, contact support

Code Examples

# Set your Bearer token
TOKEN="your_jwt_bearer_token_here"

curl -X POST https://kyc.sbx.moduluslabs.io/v2/onboard/signup \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "contact": {
      "email": "[email protected]",
      "phone": "09171234567"
    },
    "user": {
      "firstName": "John",
      "middleName": "Michael",
      "lastName": "Doe",
      "username": "john.doe",
      "password": "SecurePass123!",
      "pin": "1234"
    }
  }'

Validation Requirements

1

Email Validation

✓ Valid email format ✓ Contains @ symbol ✓ Valid domain
2

Phone Validation

✓ 1-30 digits ✓ Numbers only (no spaces, dashes, or special characters)
3

Name Validation

✓ 1-100 characters ✓ Unicode letters, spaces, hyphens, and apostrophes only ✓ No numbers or special characters (except hyphens and apostrophes)
4

Username Validation

✓ 1-50 characters ✓ Letters, numbers, dots, underscores, and hyphens only ✓ Must be unique across the system
5

Password Validation

✓ 12-64 characters ✓ At least 1 uppercase letter ✓ At least 1 lowercase letter ✓ At least 1 number ✓ At least 1 special character from: #?!@$%^&*-
6

PIN Validation

✓ Exactly 4 digits ✓ Numbers only

Best Practices

Client-Side Validation

Validate all fields before submitting to avoid 400 errors

Handle Rate Limiting

Implement retry logic with exponential backoff for 429 errors

Secure Password Handling

Never log or store passwords in plain text

Save Account ID

Store the returned account ID for subsequent onboarding steps

Username Availability

Check username uniqueness before submission if possible

Error Feedback

Provide clear error messages to users when validation fails

Account Lifecycle

1

Create Account

Call this endpoint to create a new user account
2

Pending Approval

Account is registered under Packworks Merchant parent and awaits admin approval
3

Admin Review

Modulus Labs admin reviews and approves the account
4

Account Activation

Upon approval, a new merchant branch is created and assigned to the account
5

Begin Onboarding

Use the account ID to generate JWT token and proceed with merchant onboarding

Security Notes

  • Passwords are hashed using bcrypt before storage
  • Passwords expire after 90 days and must be changed
  • Never send passwords over unencrypted connections
  • Implement strong password requirements on the client side
  • PINs are encrypted using Rijndael encryption
  • PINs provide additional security for sensitive operations
  • Consider implementing PIN rate limiting in your application
  • Maximum 10 requests per 60 seconds per client
  • Implement exponential backoff when encountering 429 errors
  • Consider caching account creation attempts to prevent abuse

Troubleshooting

Error: Username is not availableSolution:
  • Try a different username
  • Add numbers or special characters (dots, underscores, hyphens)
  • Consider using email prefix or unique identifiers
Error: user.password must have at least 1 uppercase and lowercase character, a number, and special characterSolution:
  • Ensure password is 12-64 characters long
  • Include at least one uppercase letter (A-Z)
  • Include at least one lowercase letter (a-z)
  • Include at least one number (0-9)
  • Include at least one special character from: #?!@$%^&*-
Example valid password: SecurePass123!
Error: ThrottlerException: Too Many RequestsSolution:
  • Wait 60 seconds before retrying
  • Implement exponential backoff
  • Don’t retry immediately on 429 errors
  • Consider queueing account creation requests

Next Steps

Authorizations

Authorization
string
header
required

JWT Bearer token authentication

Body

application/json
contact
object
required

Contact information for the account

user
object
required

User credentials and personal information

Response

Account created successfully

id
string

Unique account identifier

emailAddress
string

Registered email address

firstName
string

First name

lastName
string

Last name

accessToken
string

JWT access token for authentication

refreshToken
string

JWT refresh token for obtaining new access tokens