# Set your Bearer token and reference number
TOKEN="your_jwt_bearer_token_here"
REF_NO="550e8400-e29b-41d4-a716-446655440000"
curl -X GET "https://kyc.sbx.moduluslabs.io/v2/onboard/$REF_NO/status" \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json"
const axios = require('axios');
const BEARER_TOKEN = process.env.BEARER_TOKEN;
const REFERENCE_NUMBER = '550e8400-e29b-41d4-a716-446655440000';
async function getOnboardingStatus(refNo) {
try {
const response = await axios.get(
`https://kyc.sbx.moduluslabs.io/v2/onboard/${refNo}/status`,
{
headers: {
'Authorization': `Bearer ${BEARER_TOKEN}`,
'Accept': 'application/json'
}
}
);
const { onboardingStatus, merchantName, declinedReason } = response.data;
console.log(' Status retrieved successfully');
console.log(`Merchant: ${merchantName}`);
console.log(`Status: ${onboardingStatus}`);
if (onboardingStatus === 'APPROVED') {
console.log(' Onboarding approved!');
} else if (onboardingStatus === 'DECLINED') {
console.log(` Declined: ${declinedReason}`);
} else if (onboardingStatus === 'PENDING') {
console.log(' Awaiting re-approval...');
} else {
console.log(' Awaiting initial approval...');
}
return response.data;
} catch (error) {
if (error.response?.status === 401) {
console.error(' Unauthorized. Check your Bearer token.');
} else if (error.response?.status === 400) {
console.error(' Bad Request:', error.response.data.message);
} else {
console.error(' Request failed:', error.response?.data || error.message);
}
throw error;
}
}
// Usage
getOnboardingStatus(REFERENCE_NUMBER);
import os
import requests
BEARER_TOKEN = os.getenv('BEARER_TOKEN')
REFERENCE_NUMBER = '550e8400-e29b-41d4-a716-446655440000'
def get_onboarding_status(ref_no):
"""Get onboarding status by reference number"""
try:
response = requests.get(
f'https://kyc.sbx.moduluslabs.io/v2/onboard/{ref_no}/status',
headers={
'Authorization': f'Bearer {BEARER_TOKEN}',
'Accept': 'application/json'
}
)
response.raise_for_status()
data = response.json()
status = data['onboardingStatus']
merchant_name = data['merchantName']
declined_reason = data.get('declinedReason')
print(' Status retrieved successfully')
print(f"Merchant: {merchant_name}")
print(f"Status: {status}")
if status == 'APPROVED':
print(' Onboarding approved!')
elif status == 'DECLINED':
print(f" Declined: {declined_reason}")
elif status == 'PENDING':
print(' Awaiting re-approval...')
else:
print(' Awaiting initial approval...')
return data
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print(' Unauthorized. Check your Bearer token.')
elif e.response.status_code == 400:
print(f" Bad Request: {e.response.json().get('message')}")
else:
print(f' Request failed: {e.response.text}')
raise
if __name__ == '__main__':
get_onboarding_status(REFERENCE_NUMBER)
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$bearerToken = getenv('BEARER_TOKEN');
$referenceNumber = '550e8400-e29b-41d4-a716-446655440000';
function getOnboardingStatus($refNo) {
global $bearerToken;
try {
$client = new Client();
$response = $client->get(
"https://kyc.sbx.moduluslabs.io/v2/onboard/$refNo/status",
[
'headers' => [
'Authorization' => 'Bearer ' . $bearerToken,
'Accept' => 'application/json'
]
]
);
$data = json_decode($response->getBody(), true);
$status = $data['onboardingStatus'];
$merchantName = $data['merchantName'];
$declinedReason = $data['declinedReason'] ?? null;
echo " Status retrieved successfully\n";
echo "Merchant: $merchantName\n";
echo "Status: $status\n";
if ($status === 'APPROVED') {
echo " Onboarding approved!\n";
} elseif ($status === 'DECLINED') {
echo " Declined: $declinedReason\n";
} elseif ($status === 'PENDING') {
echo " Awaiting re-approval...\n";
} else {
echo " Awaiting initial approval...\n";
}
return $data;
} catch (RequestException $e) {
if ($e->hasResponse()) {
$statusCode = $e->getResponse()->getStatusCode();
if ($statusCode === 401) {
echo " Unauthorized. Check your Bearer token.\n";
} elseif ($statusCode === 400) {
$body = json_decode($e->getResponse()->getBody(), true);
echo " Bad Request: " . $body['message'] . "\n";
} else {
echo " Request failed: " . $e->getMessage() . "\n";
echo $e->getResponse()->getBody() . "\n";
}
} else {
echo " Request failed: " . $e->getMessage() . "\n";
}
throw $e;
}
}
getOnboardingStatus($referenceNumber);
?>
import com.google.gson.Gson;
import okhttp3.*;
import java.io.IOException;
public class GetOnboardingStatus {
private static final String BEARER_TOKEN = System.getenv("BEARER_TOKEN");
private static final String REFERENCE_NUMBER = "550e8400-e29b-41d4-a716-446655440000";
private static final String API_URL = "https://kyc.sbx.moduluslabs.io/v2/onboard/";
public static void getOnboardingStatus(String refNo) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(API_URL + refNo + "/status")
.header("Authorization", "Bearer " + BEARER_TOKEN)
.header("Accept", "application/json")
.get()
.build();
try (Response response = client.newCall(request).execute()) {
String responseBody = response.body().string();
if (response.isSuccessful()) {
Gson gson = new Gson();
StatusResponse data = gson.fromJson(responseBody, StatusResponse.class);
System.out.println(" Status retrieved successfully");
System.out.println("Merchant: " + data.merchantName);
System.out.println("Status: " + data.onboardingStatus);
switch (data.onboardingStatus) {
case "APPROVED":
System.out.println(" Onboarding approved!");
break;
case "DECLINED":
System.out.println(" Declined: " + data.declinedReason);
break;
case "PENDING":
System.out.println(" Awaiting re-approval...");
break;
default:
System.out.println(" Awaiting initial approval...");
}
} else if (response.code() == 401) {
System.out.println(" Unauthorized. Check your Bearer token.");
} else if (response.code() == 400) {
System.out.println(" Bad Request: " + responseBody);
} else {
System.out.println(" Request failed: HTTP " + response.code());
System.out.println("Details: " + responseBody);
}
}
}
public static void main(String[] args) {
try {
getOnboardingStatus(REFERENCE_NUMBER);
} catch (IOException e) {
System.err.println(" Error: " + e.getMessage());
e.printStackTrace();
}
}
static class StatusResponse {
String onboardingStatus;
String onboardingReferenceNumber;
String merchantName;
String dateCreated;
String dateUpdated;
String declinedReason;
}
}
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
const (
apiURL = "https://kyc.sbx.moduluslabs.io/v2/onboard/"
referenceNumber = "550e8400-e29b-41d4-a716-446655440000"
)
type StatusResponse struct {
OnboardingStatus string `json:"onboardingStatus"`
OnboardingReferenceNumber string `json:"onboardingReferenceNumber"`
MerchantName string `json:"merchantName"`
DateCreated string `json:"dateCreated"`
DateUpdated *string `json:"dateUpdated"`
DeclinedReason *string `json:"declinedReason"`
}
func getOnboardingStatus(refNo string) error {
bearerToken := os.Getenv("BEARER_TOKEN")
req, err := http.NewRequest("GET", apiURL+refNo+"/status", nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+bearerToken)
req.Header.Set("Accept", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode == http.StatusOK {
var data StatusResponse
if err := json.Unmarshal(body, &data); err != nil {
return fmt.Errorf("failed to parse response: %w", err)
}
fmt.Println(" Status retrieved successfully")
fmt.Printf("Merchant: %s\n", data.MerchantName)
fmt.Printf("Status: %s\n", data.OnboardingStatus)
switch data.OnboardingStatus {
case "APPROVED":
fmt.Println(" Onboarding approved!")
case "DECLINED":
if data.DeclinedReason != nil {
fmt.Printf(" Declined: %s\n", *data.DeclinedReason)
}
case "PENDING":
fmt.Println(" Awaiting re-approval...")
default:
fmt.Println(" Awaiting initial approval...")
}
return nil
} else if resp.StatusCode == http.StatusUnauthorized {
fmt.Println(" Unauthorized. Check your Bearer token.")
return fmt.Errorf("unauthorized")
} else if resp.StatusCode == http.StatusBadRequest {
fmt.Printf(" Bad Request: %s\n", string(body))
return fmt.Errorf("bad request")
}
fmt.Printf(" Request failed: HTTP %d\n", resp.StatusCode)
fmt.Printf("Details: %s\n", string(body))
return fmt.Errorf("request failed with status %d", resp.StatusCode)
}
func main() {
if err := getOnboardingStatus(referenceNumber); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
await GetOnboardingStatus("550e8400-e29b-41d4-a716-446655440000");
}
static async Task GetOnboardingStatus(string refNo)
{
var bearerToken = Environment.GetEnvironmentVariable("BEARER_TOKEN");
if (string.IsNullOrEmpty(bearerToken))
{
Console.WriteLine(" Error: BEARER_TOKEN environment variable not set");
return;
}
try
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", bearerToken);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync(
$"https://kyc.sbx.moduluslabs.io/v2/onboard/{refNo}/status"
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var data = JsonSerializer.Deserialize<StatusResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine(" Status retrieved successfully");
Console.WriteLine($"Merchant: {data.MerchantName}");
Console.WriteLine($"Status: {data.OnboardingStatus}");
switch (data.OnboardingStatus)
{
case "APPROVED":
Console.WriteLine(" Onboarding approved!");
break;
case "DECLINED":
Console.WriteLine($" Declined: {data.DeclinedReason}");
break;
case "PENDING":
Console.WriteLine(" Awaiting re-approval...");
break;
default:
Console.WriteLine(" Awaiting initial approval...");
break;
}
}
else if ((int)response.StatusCode == 401)
{
Console.WriteLine(" Unauthorized. Check your Bearer token.");
}
else if ((int)response.StatusCode == 400)
{
Console.WriteLine($" Bad Request: {responseBody}");
}
else
{
Console.WriteLine($" Request failed: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($" Request failed: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($" Error: {e.Message}");
}
}
}
public class StatusResponse
{
public string OnboardingStatus { get; set; }
public string OnboardingReferenceNumber { get; set; }
public string MerchantName { get; set; }
public string DateCreated { get; set; }
public string DateUpdated { get; set; }
public string DeclinedReason { get; set; }
}
{
"onboardingStatus": "NEW",
"onboardingReferenceNumber": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"merchantName": "<string>",
"dateCreated": "2023-11-07T05:31:56Z",
"dateUpdated": "2023-11-07T05:31:56Z",
"declinedReason": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"error": "<string>",
"details": {}
}{
"statusCode": 123,
"message": "<string>",
"error": "<string>",
"details": {}
}Onboarding API
Retrieve Onboarding Status
Retrieve the current onboarding status for a merchant (lightweight endpoint)
GET
/
v2
/
onboard
/
{refNo}
/
status
# Set your Bearer token and reference number
TOKEN="your_jwt_bearer_token_here"
REF_NO="550e8400-e29b-41d4-a716-446655440000"
curl -X GET "https://kyc.sbx.moduluslabs.io/v2/onboard/$REF_NO/status" \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json"
const axios = require('axios');
const BEARER_TOKEN = process.env.BEARER_TOKEN;
const REFERENCE_NUMBER = '550e8400-e29b-41d4-a716-446655440000';
async function getOnboardingStatus(refNo) {
try {
const response = await axios.get(
`https://kyc.sbx.moduluslabs.io/v2/onboard/${refNo}/status`,
{
headers: {
'Authorization': `Bearer ${BEARER_TOKEN}`,
'Accept': 'application/json'
}
}
);
const { onboardingStatus, merchantName, declinedReason } = response.data;
console.log(' Status retrieved successfully');
console.log(`Merchant: ${merchantName}`);
console.log(`Status: ${onboardingStatus}`);
if (onboardingStatus === 'APPROVED') {
console.log(' Onboarding approved!');
} else if (onboardingStatus === 'DECLINED') {
console.log(` Declined: ${declinedReason}`);
} else if (onboardingStatus === 'PENDING') {
console.log(' Awaiting re-approval...');
} else {
console.log(' Awaiting initial approval...');
}
return response.data;
} catch (error) {
if (error.response?.status === 401) {
console.error(' Unauthorized. Check your Bearer token.');
} else if (error.response?.status === 400) {
console.error(' Bad Request:', error.response.data.message);
} else {
console.error(' Request failed:', error.response?.data || error.message);
}
throw error;
}
}
// Usage
getOnboardingStatus(REFERENCE_NUMBER);
import os
import requests
BEARER_TOKEN = os.getenv('BEARER_TOKEN')
REFERENCE_NUMBER = '550e8400-e29b-41d4-a716-446655440000'
def get_onboarding_status(ref_no):
"""Get onboarding status by reference number"""
try:
response = requests.get(
f'https://kyc.sbx.moduluslabs.io/v2/onboard/{ref_no}/status',
headers={
'Authorization': f'Bearer {BEARER_TOKEN}',
'Accept': 'application/json'
}
)
response.raise_for_status()
data = response.json()
status = data['onboardingStatus']
merchant_name = data['merchantName']
declined_reason = data.get('declinedReason')
print(' Status retrieved successfully')
print(f"Merchant: {merchant_name}")
print(f"Status: {status}")
if status == 'APPROVED':
print(' Onboarding approved!')
elif status == 'DECLINED':
print(f" Declined: {declined_reason}")
elif status == 'PENDING':
print(' Awaiting re-approval...')
else:
print(' Awaiting initial approval...')
return data
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print(' Unauthorized. Check your Bearer token.')
elif e.response.status_code == 400:
print(f" Bad Request: {e.response.json().get('message')}")
else:
print(f' Request failed: {e.response.text}')
raise
if __name__ == '__main__':
get_onboarding_status(REFERENCE_NUMBER)
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$bearerToken = getenv('BEARER_TOKEN');
$referenceNumber = '550e8400-e29b-41d4-a716-446655440000';
function getOnboardingStatus($refNo) {
global $bearerToken;
try {
$client = new Client();
$response = $client->get(
"https://kyc.sbx.moduluslabs.io/v2/onboard/$refNo/status",
[
'headers' => [
'Authorization' => 'Bearer ' . $bearerToken,
'Accept' => 'application/json'
]
]
);
$data = json_decode($response->getBody(), true);
$status = $data['onboardingStatus'];
$merchantName = $data['merchantName'];
$declinedReason = $data['declinedReason'] ?? null;
echo " Status retrieved successfully\n";
echo "Merchant: $merchantName\n";
echo "Status: $status\n";
if ($status === 'APPROVED') {
echo " Onboarding approved!\n";
} elseif ($status === 'DECLINED') {
echo " Declined: $declinedReason\n";
} elseif ($status === 'PENDING') {
echo " Awaiting re-approval...\n";
} else {
echo " Awaiting initial approval...\n";
}
return $data;
} catch (RequestException $e) {
if ($e->hasResponse()) {
$statusCode = $e->getResponse()->getStatusCode();
if ($statusCode === 401) {
echo " Unauthorized. Check your Bearer token.\n";
} elseif ($statusCode === 400) {
$body = json_decode($e->getResponse()->getBody(), true);
echo " Bad Request: " . $body['message'] . "\n";
} else {
echo " Request failed: " . $e->getMessage() . "\n";
echo $e->getResponse()->getBody() . "\n";
}
} else {
echo " Request failed: " . $e->getMessage() . "\n";
}
throw $e;
}
}
getOnboardingStatus($referenceNumber);
?>
import com.google.gson.Gson;
import okhttp3.*;
import java.io.IOException;
public class GetOnboardingStatus {
private static final String BEARER_TOKEN = System.getenv("BEARER_TOKEN");
private static final String REFERENCE_NUMBER = "550e8400-e29b-41d4-a716-446655440000";
private static final String API_URL = "https://kyc.sbx.moduluslabs.io/v2/onboard/";
public static void getOnboardingStatus(String refNo) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(API_URL + refNo + "/status")
.header("Authorization", "Bearer " + BEARER_TOKEN)
.header("Accept", "application/json")
.get()
.build();
try (Response response = client.newCall(request).execute()) {
String responseBody = response.body().string();
if (response.isSuccessful()) {
Gson gson = new Gson();
StatusResponse data = gson.fromJson(responseBody, StatusResponse.class);
System.out.println(" Status retrieved successfully");
System.out.println("Merchant: " + data.merchantName);
System.out.println("Status: " + data.onboardingStatus);
switch (data.onboardingStatus) {
case "APPROVED":
System.out.println(" Onboarding approved!");
break;
case "DECLINED":
System.out.println(" Declined: " + data.declinedReason);
break;
case "PENDING":
System.out.println(" Awaiting re-approval...");
break;
default:
System.out.println(" Awaiting initial approval...");
}
} else if (response.code() == 401) {
System.out.println(" Unauthorized. Check your Bearer token.");
} else if (response.code() == 400) {
System.out.println(" Bad Request: " + responseBody);
} else {
System.out.println(" Request failed: HTTP " + response.code());
System.out.println("Details: " + responseBody);
}
}
}
public static void main(String[] args) {
try {
getOnboardingStatus(REFERENCE_NUMBER);
} catch (IOException e) {
System.err.println(" Error: " + e.getMessage());
e.printStackTrace();
}
}
static class StatusResponse {
String onboardingStatus;
String onboardingReferenceNumber;
String merchantName;
String dateCreated;
String dateUpdated;
String declinedReason;
}
}
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
const (
apiURL = "https://kyc.sbx.moduluslabs.io/v2/onboard/"
referenceNumber = "550e8400-e29b-41d4-a716-446655440000"
)
type StatusResponse struct {
OnboardingStatus string `json:"onboardingStatus"`
OnboardingReferenceNumber string `json:"onboardingReferenceNumber"`
MerchantName string `json:"merchantName"`
DateCreated string `json:"dateCreated"`
DateUpdated *string `json:"dateUpdated"`
DeclinedReason *string `json:"declinedReason"`
}
func getOnboardingStatus(refNo string) error {
bearerToken := os.Getenv("BEARER_TOKEN")
req, err := http.NewRequest("GET", apiURL+refNo+"/status", nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+bearerToken)
req.Header.Set("Accept", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode == http.StatusOK {
var data StatusResponse
if err := json.Unmarshal(body, &data); err != nil {
return fmt.Errorf("failed to parse response: %w", err)
}
fmt.Println(" Status retrieved successfully")
fmt.Printf("Merchant: %s\n", data.MerchantName)
fmt.Printf("Status: %s\n", data.OnboardingStatus)
switch data.OnboardingStatus {
case "APPROVED":
fmt.Println(" Onboarding approved!")
case "DECLINED":
if data.DeclinedReason != nil {
fmt.Printf(" Declined: %s\n", *data.DeclinedReason)
}
case "PENDING":
fmt.Println(" Awaiting re-approval...")
default:
fmt.Println(" Awaiting initial approval...")
}
return nil
} else if resp.StatusCode == http.StatusUnauthorized {
fmt.Println(" Unauthorized. Check your Bearer token.")
return fmt.Errorf("unauthorized")
} else if resp.StatusCode == http.StatusBadRequest {
fmt.Printf(" Bad Request: %s\n", string(body))
return fmt.Errorf("bad request")
}
fmt.Printf(" Request failed: HTTP %d\n", resp.StatusCode)
fmt.Printf("Details: %s\n", string(body))
return fmt.Errorf("request failed with status %d", resp.StatusCode)
}
func main() {
if err := getOnboardingStatus(referenceNumber); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
await GetOnboardingStatus("550e8400-e29b-41d4-a716-446655440000");
}
static async Task GetOnboardingStatus(string refNo)
{
var bearerToken = Environment.GetEnvironmentVariable("BEARER_TOKEN");
if (string.IsNullOrEmpty(bearerToken))
{
Console.WriteLine(" Error: BEARER_TOKEN environment variable not set");
return;
}
try
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", bearerToken);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync(
$"https://kyc.sbx.moduluslabs.io/v2/onboard/{refNo}/status"
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var data = JsonSerializer.Deserialize<StatusResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine(" Status retrieved successfully");
Console.WriteLine($"Merchant: {data.MerchantName}");
Console.WriteLine($"Status: {data.OnboardingStatus}");
switch (data.OnboardingStatus)
{
case "APPROVED":
Console.WriteLine(" Onboarding approved!");
break;
case "DECLINED":
Console.WriteLine($" Declined: {data.DeclinedReason}");
break;
case "PENDING":
Console.WriteLine(" Awaiting re-approval...");
break;
default:
Console.WriteLine(" Awaiting initial approval...");
break;
}
}
else if ((int)response.StatusCode == 401)
{
Console.WriteLine(" Unauthorized. Check your Bearer token.");
}
else if ((int)response.StatusCode == 400)
{
Console.WriteLine($" Bad Request: {responseBody}");
}
else
{
Console.WriteLine($" Request failed: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($" Request failed: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($" Error: {e.Message}");
}
}
}
public class StatusResponse
{
public string OnboardingStatus { get; set; }
public string OnboardingReferenceNumber { get; set; }
public string MerchantName { get; set; }
public string DateCreated { get; set; }
public string DateUpdated { get; set; }
public string DeclinedReason { get; set; }
}
{
"onboardingStatus": "NEW",
"onboardingReferenceNumber": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"merchantName": "<string>",
"dateCreated": "2023-11-07T05:31:56Z",
"dateUpdated": "2023-11-07T05:31:56Z",
"declinedReason": "<string>"
}{
"statusCode": 123,
"message": "<string>",
"error": "<string>",
"details": {}
}{
"statusCode": 123,
"message": "<string>",
"error": "<string>",
"details": {}
}Overview
Retrieves the current onboarding status for a merchant using the onboarding reference number. This is a lightweight endpoint that returns only essential status information without the full onboarding data.Ideal for: Polling the onboarding status, quick status checks in dashboards, or determining if full onboarding data needs to be fetched.
Lightweight Alternative: Use this endpoint instead of Retrieve Onboarding Data when you only need to check the approval status.
Authentication
This endpoint requires JWT Bearer Token authentication.Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization Required: The authenticated user must be the owner of the onboarding record. Only the user who created the onboarding record can retrieve its status.
Status Flow Diagram
The onboarding status follows this flow:NEW → APPROVED (direct approval)
NEW → DECLINED → PENDING → APPROVED (decline then resubmit flow)
NEW → DECLINED → PENDING → DECLINED (multiple decline cycles possible)
1
NEW
Merchant has completed the onboarding form and submitted it for initial review. Awaiting admin approval.
2
DECLINED (Optional)
Admin reviewed the application and declined it. The
declinedReason field contains the reason for rejection. Merchant needs to update their information.3
PENDING (Optional)
Merchant has updated their form after being declined and resubmitted for review. Awaiting admin re-approval.
4
APPROVED
Admin has approved the merchant’s onboarding application. Merchant can now process transactions.
# Set your Bearer token and reference number
TOKEN="your_jwt_bearer_token_here"
REF_NO="550e8400-e29b-41d4-a716-446655440000"
curl -X GET "https://kyc.sbx.moduluslabs.io/v2/onboard/$REF_NO/status" \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json"
const axios = require('axios');
const BEARER_TOKEN = process.env.BEARER_TOKEN;
const REFERENCE_NUMBER = '550e8400-e29b-41d4-a716-446655440000';
async function getOnboardingStatus(refNo) {
try {
const response = await axios.get(
`https://kyc.sbx.moduluslabs.io/v2/onboard/${refNo}/status`,
{
headers: {
'Authorization': `Bearer ${BEARER_TOKEN}`,
'Accept': 'application/json'
}
}
);
const { onboardingStatus, merchantName, declinedReason } = response.data;
console.log(' Status retrieved successfully');
console.log(`Merchant: ${merchantName}`);
console.log(`Status: ${onboardingStatus}`);
if (onboardingStatus === 'APPROVED') {
console.log(' Onboarding approved!');
} else if (onboardingStatus === 'DECLINED') {
console.log(` Declined: ${declinedReason}`);
} else if (onboardingStatus === 'PENDING') {
console.log(' Awaiting re-approval...');
} else {
console.log(' Awaiting initial approval...');
}
return response.data;
} catch (error) {
if (error.response?.status === 401) {
console.error(' Unauthorized. Check your Bearer token.');
} else if (error.response?.status === 400) {
console.error(' Bad Request:', error.response.data.message);
} else {
console.error(' Request failed:', error.response?.data || error.message);
}
throw error;
}
}
// Usage
getOnboardingStatus(REFERENCE_NUMBER);
import os
import requests
BEARER_TOKEN = os.getenv('BEARER_TOKEN')
REFERENCE_NUMBER = '550e8400-e29b-41d4-a716-446655440000'
def get_onboarding_status(ref_no):
"""Get onboarding status by reference number"""
try:
response = requests.get(
f'https://kyc.sbx.moduluslabs.io/v2/onboard/{ref_no}/status',
headers={
'Authorization': f'Bearer {BEARER_TOKEN}',
'Accept': 'application/json'
}
)
response.raise_for_status()
data = response.json()
status = data['onboardingStatus']
merchant_name = data['merchantName']
declined_reason = data.get('declinedReason')
print(' Status retrieved successfully')
print(f"Merchant: {merchant_name}")
print(f"Status: {status}")
if status == 'APPROVED':
print(' Onboarding approved!')
elif status == 'DECLINED':
print(f" Declined: {declined_reason}")
elif status == 'PENDING':
print(' Awaiting re-approval...')
else:
print(' Awaiting initial approval...')
return data
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print(' Unauthorized. Check your Bearer token.')
elif e.response.status_code == 400:
print(f" Bad Request: {e.response.json().get('message')}")
else:
print(f' Request failed: {e.response.text}')
raise
if __name__ == '__main__':
get_onboarding_status(REFERENCE_NUMBER)
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$bearerToken = getenv('BEARER_TOKEN');
$referenceNumber = '550e8400-e29b-41d4-a716-446655440000';
function getOnboardingStatus($refNo) {
global $bearerToken;
try {
$client = new Client();
$response = $client->get(
"https://kyc.sbx.moduluslabs.io/v2/onboard/$refNo/status",
[
'headers' => [
'Authorization' => 'Bearer ' . $bearerToken,
'Accept' => 'application/json'
]
]
);
$data = json_decode($response->getBody(), true);
$status = $data['onboardingStatus'];
$merchantName = $data['merchantName'];
$declinedReason = $data['declinedReason'] ?? null;
echo " Status retrieved successfully\n";
echo "Merchant: $merchantName\n";
echo "Status: $status\n";
if ($status === 'APPROVED') {
echo " Onboarding approved!\n";
} elseif ($status === 'DECLINED') {
echo " Declined: $declinedReason\n";
} elseif ($status === 'PENDING') {
echo " Awaiting re-approval...\n";
} else {
echo " Awaiting initial approval...\n";
}
return $data;
} catch (RequestException $e) {
if ($e->hasResponse()) {
$statusCode = $e->getResponse()->getStatusCode();
if ($statusCode === 401) {
echo " Unauthorized. Check your Bearer token.\n";
} elseif ($statusCode === 400) {
$body = json_decode($e->getResponse()->getBody(), true);
echo " Bad Request: " . $body['message'] . "\n";
} else {
echo " Request failed: " . $e->getMessage() . "\n";
echo $e->getResponse()->getBody() . "\n";
}
} else {
echo " Request failed: " . $e->getMessage() . "\n";
}
throw $e;
}
}
getOnboardingStatus($referenceNumber);
?>
import com.google.gson.Gson;
import okhttp3.*;
import java.io.IOException;
public class GetOnboardingStatus {
private static final String BEARER_TOKEN = System.getenv("BEARER_TOKEN");
private static final String REFERENCE_NUMBER = "550e8400-e29b-41d4-a716-446655440000";
private static final String API_URL = "https://kyc.sbx.moduluslabs.io/v2/onboard/";
public static void getOnboardingStatus(String refNo) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(API_URL + refNo + "/status")
.header("Authorization", "Bearer " + BEARER_TOKEN)
.header("Accept", "application/json")
.get()
.build();
try (Response response = client.newCall(request).execute()) {
String responseBody = response.body().string();
if (response.isSuccessful()) {
Gson gson = new Gson();
StatusResponse data = gson.fromJson(responseBody, StatusResponse.class);
System.out.println(" Status retrieved successfully");
System.out.println("Merchant: " + data.merchantName);
System.out.println("Status: " + data.onboardingStatus);
switch (data.onboardingStatus) {
case "APPROVED":
System.out.println(" Onboarding approved!");
break;
case "DECLINED":
System.out.println(" Declined: " + data.declinedReason);
break;
case "PENDING":
System.out.println(" Awaiting re-approval...");
break;
default:
System.out.println(" Awaiting initial approval...");
}
} else if (response.code() == 401) {
System.out.println(" Unauthorized. Check your Bearer token.");
} else if (response.code() == 400) {
System.out.println(" Bad Request: " + responseBody);
} else {
System.out.println(" Request failed: HTTP " + response.code());
System.out.println("Details: " + responseBody);
}
}
}
public static void main(String[] args) {
try {
getOnboardingStatus(REFERENCE_NUMBER);
} catch (IOException e) {
System.err.println(" Error: " + e.getMessage());
e.printStackTrace();
}
}
static class StatusResponse {
String onboardingStatus;
String onboardingReferenceNumber;
String merchantName;
String dateCreated;
String dateUpdated;
String declinedReason;
}
}
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
const (
apiURL = "https://kyc.sbx.moduluslabs.io/v2/onboard/"
referenceNumber = "550e8400-e29b-41d4-a716-446655440000"
)
type StatusResponse struct {
OnboardingStatus string `json:"onboardingStatus"`
OnboardingReferenceNumber string `json:"onboardingReferenceNumber"`
MerchantName string `json:"merchantName"`
DateCreated string `json:"dateCreated"`
DateUpdated *string `json:"dateUpdated"`
DeclinedReason *string `json:"declinedReason"`
}
func getOnboardingStatus(refNo string) error {
bearerToken := os.Getenv("BEARER_TOKEN")
req, err := http.NewRequest("GET", apiURL+refNo+"/status", nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+bearerToken)
req.Header.Set("Accept", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode == http.StatusOK {
var data StatusResponse
if err := json.Unmarshal(body, &data); err != nil {
return fmt.Errorf("failed to parse response: %w", err)
}
fmt.Println(" Status retrieved successfully")
fmt.Printf("Merchant: %s\n", data.MerchantName)
fmt.Printf("Status: %s\n", data.OnboardingStatus)
switch data.OnboardingStatus {
case "APPROVED":
fmt.Println(" Onboarding approved!")
case "DECLINED":
if data.DeclinedReason != nil {
fmt.Printf(" Declined: %s\n", *data.DeclinedReason)
}
case "PENDING":
fmt.Println(" Awaiting re-approval...")
default:
fmt.Println(" Awaiting initial approval...")
}
return nil
} else if resp.StatusCode == http.StatusUnauthorized {
fmt.Println(" Unauthorized. Check your Bearer token.")
return fmt.Errorf("unauthorized")
} else if resp.StatusCode == http.StatusBadRequest {
fmt.Printf(" Bad Request: %s\n", string(body))
return fmt.Errorf("bad request")
}
fmt.Printf(" Request failed: HTTP %d\n", resp.StatusCode)
fmt.Printf("Details: %s\n", string(body))
return fmt.Errorf("request failed with status %d", resp.StatusCode)
}
func main() {
if err := getOnboardingStatus(referenceNumber); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
await GetOnboardingStatus("550e8400-e29b-41d4-a716-446655440000");
}
static async Task GetOnboardingStatus(string refNo)
{
var bearerToken = Environment.GetEnvironmentVariable("BEARER_TOKEN");
if (string.IsNullOrEmpty(bearerToken))
{
Console.WriteLine(" Error: BEARER_TOKEN environment variable not set");
return;
}
try
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", bearerToken);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync(
$"https://kyc.sbx.moduluslabs.io/v2/onboard/{refNo}/status"
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var data = JsonSerializer.Deserialize<StatusResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine(" Status retrieved successfully");
Console.WriteLine($"Merchant: {data.MerchantName}");
Console.WriteLine($"Status: {data.OnboardingStatus}");
switch (data.OnboardingStatus)
{
case "APPROVED":
Console.WriteLine(" Onboarding approved!");
break;
case "DECLINED":
Console.WriteLine($" Declined: {data.DeclinedReason}");
break;
case "PENDING":
Console.WriteLine(" Awaiting re-approval...");
break;
default:
Console.WriteLine(" Awaiting initial approval...");
break;
}
}
else if ((int)response.StatusCode == 401)
{
Console.WriteLine(" Unauthorized. Check your Bearer token.");
}
else if ((int)response.StatusCode == 400)
{
Console.WriteLine($" Bad Request: {responseBody}");
}
else
{
Console.WriteLine($" Request failed: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($" Request failed: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($" Error: {e.Message}");
}
}
}
public class StatusResponse
{
public string OnboardingStatus { get; set; }
public string OnboardingReferenceNumber { get; set; }
public string MerchantName { get; set; }
public string DateCreated { get; set; }
public string DateUpdated { get; set; }
public string DeclinedReason { get; set; }
}
Polling Best Practices
Implement Smart Polling
Implement Smart Polling
Use this lightweight endpoint for efficient status polling:
async function pollOnboardingStatus(refNo, maxAttempts = 30) {
let attempts = 0;
const pollInterval = 30000; // 30 seconds
const poll = async () => {
if (attempts >= maxAttempts) {
console.log(' Polling timeout reached');
return;
}
attempts++;
console.log(`Checking status (attempt ${attempts}/${maxAttempts})...`);
try {
const status = await getOnboardingStatus(refNo);
if (status.onboardingStatus === 'APPROVED') {
console.log(' Onboarding approved!');
return status;
} else if (status.onboardingStatus === 'DECLINED') {
console.log(' Onboarding declined');
return status;
}
// Continue polling if NEW or PENDING
setTimeout(poll, pollInterval);
} catch (error) {
console.error('Polling error:', error.message);
setTimeout(poll, pollInterval);
}
};
await poll();
}
Exponential Backoff
Exponential Backoff
Implement exponential backoff to reduce server load:
async function pollWithBackoff(refNo, maxAttempts = 20) {
let attempts = 0;
let delay = 10000; // Start with 10 seconds
const maxDelay = 300000; // Max 5 minutes
const poll = async () => {
if (attempts >= maxAttempts) return;
attempts++;
const status = await getOnboardingStatus(refNo);
if (['APPROVED', 'DECLINED'].includes(status.onboardingStatus)) {
return status;
}
// Exponential backoff with max delay cap
delay = Math.min(delay * 1.5, maxDelay);
setTimeout(poll, delay);
};
await poll();
}
Cache Status Results
Cache Status Results
Cache the status response to reduce unnecessary API calls:
const statusCache = new Map();
const CACHE_TTL = 30000; // 30 seconds
async function getCachedStatus(refNo) {
const cached = statusCache.get(refNo);
if (cached && (Date.now() - cached.timestamp) < CACHE_TTL) {
return cached.data;
}
const status = await getOnboardingStatus(refNo);
statusCache.set(refNo, {
data: status,
timestamp: Date.now()
});
return status;
}
Stop Polling on Terminal Status
Stop Polling on Terminal Status
Automatically stop polling when reaching a terminal status:
const TERMINAL_STATUSES = ['APPROVED', 'DECLINED'];
async function pollUntilTerminal(refNo) {
const interval = setInterval(async () => {
const status = await getOnboardingStatus(refNo);
if (TERMINAL_STATUSES.includes(status.onboardingStatus)) {
clearInterval(interval);
console.log(`Terminal status reached: ${status.onboardingStatus}`);
// Trigger appropriate action
if (status.onboardingStatus === 'APPROVED') {
onApproved(status);
} else {
onDeclined(status);
}
}
}, 30000);
return interval;
}
Use Cases
Dashboard Status Widget
Display real-time onboarding status in merchant dashboards
Automated Polling
Poll for status changes without fetching full onboarding data
Conditional UI Updates
Show/hide UI elements based on approval status
Notification Triggers
Trigger notifications when status changes to APPROVED or DECLINED
Status Comparison Table
| Status | Is Approved? | Is Declined? | Is Pending? | Description |
|---|---|---|---|---|
NEW | ❌ | ❌ | ❌ | Merchant completed onboarding, awaiting initial review |
PENDING | ❌ | ✅ (was) | ✅ | Merchant updated form after decline, awaiting re-approval |
APPROVED | ✅ | ❌ | ❌ | Merchant has been approved |
DECLINED | ❌ | ✅ | ❌ | Merchant was declined, needs to update form |
When to Use This Endpoint
- Use This Endpoint
- Use Full Data Endpoint
- Polling for status changes
- Dashboard status displays
- Quick status checks
- Determining if full data fetch is needed
- Triggering status-based workflows
- Mobile applications (reduced bandwidth)
- Displaying complete merchant information
- Editing onboarding data
- Generating reports with full details
- Viewing bank account information
- Showing representative details
Troubleshooting
Reference Number Mismatch
Reference Number Mismatch
Error:
Onboarding reference number mismatchCause: Trying to access an onboarding record that doesn’t belong to your accountSolution:- Verify you’re using the correct JWT token
- Each onboarding record can only be accessed by the account that created it
- Ensure you’re not mixing sandbox and production reference numbers
Polling Never Completes
Polling Never Completes
Issue: Status remains in NEW or PENDING indefinitelyPossible Causes:
- Onboarding awaiting manual admin approval
- Application is in review queue
- Additional documentation may be required
- Implement maximum polling attempts (recommended: 30-60 minutes)
- Contact support if status hasn’t changed after reasonable time
- Check for any notifications or emails from the approval team
Declined Reason Not Showing
Declined Reason Not Showing
Issue:
declinedReason is null even though status is DECLINEDPossible Causes:- Admin declined without providing a reason (rare)
- Data synchronization issue
- Fetch full onboarding data using Retrieve Onboarding Data
- Contact support for clarification
Next Steps
Retrieve Full Data
Get complete onboarding data including all details
Onboard Merchant
Create a new merchant onboarding record
Create Account
Create an account before onboarding
Authentication Guide
Learn about JWT token authentication
Authorizations
JWT Bearer token authentication
Path Parameters
The onboarding reference number (UUID v4 format)
Response
Onboarding status retrieved successfully
Current status of the merchant's onboarding application
Available options:
NEW, PENDING, APPROVED, DECLINED Unique identifier for the onboarding record
Trading name or DBA name of the merchant
Timestamp when the onboarding record was created
Timestamp of the most recent status change
Reason provided when declining the application (only present when status is DECLINED)
Was this page helpful?