# 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; }
}
{
"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": {}
}Retrieve Onboarding Status
Retrieve the current onboarding status for a merchant (lightweight endpoint)
# 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; }
}
{
"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.Authentication
This endpoint requires JWT Bearer Token authentication.Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Path Parameters
"550e8400-e29b-41d4-a716-446655440000"referenceNumber returned when you successfully submit an onboarding request via the Onboard Merchant endpoint.Response
Success Response
Status Code:200 OK
NEW: Merchant completed onboarding, awaiting initial approvalPENDING: Merchant updated form after decline, awaiting re-approvalAPPROVED: Merchant has been approvedDECLINED: Merchant was declined and needs to update their form
"NEW""550e8400-e29b-41d4-a716-446655440000""Acme Store""2024-01-15T10:30:00Z""2024-01-20T14:45:00Z"ApprovedAt, DeclinedAt, or PendingAt. Returns null if no status change has occurred (still in NEW status)."Missing required documents: SEC Registration Certificate"onboardingStatus is DECLINED. Set to null for other statuses.Response Examples
{
"onboardingStatus": "NEW",
"onboardingReferenceNumber": "550e8400-e29b-41d4-a716-446655440000",
"merchantName": "Acme Store",
"dateCreated": "2024-01-15T10:30:00Z",
"dateUpdated": null,
"declinedReason": null
}
{
"onboardingStatus": "APPROVED",
"onboardingReferenceNumber": "550e8400-e29b-41d4-a716-446655440000",
"merchantName": "Acme Store",
"dateCreated": "2024-01-15T10:30:00Z",
"dateUpdated": "2024-01-20T14:45:00Z",
"declinedReason": null
}
{
"onboardingStatus": "DECLINED",
"onboardingReferenceNumber": "550e8400-e29b-41d4-a716-446655440000",
"merchantName": "Acme Store",
"dateCreated": "2024-01-15T10:30:00Z",
"dateUpdated": "2024-01-18T09:15:00Z",
"declinedReason": "Missing required documents: SEC Registration Certificate"
}
{
"onboardingStatus": "PENDING",
"onboardingReferenceNumber": "550e8400-e29b-41d4-a716-446655440000",
"merchantName": "Acme Store",
"dateCreated": "2024-01-15T10:30:00Z",
"dateUpdated": "2024-01-22T11:00:00Z",
"declinedReason": null
}
Error Responses
400 Bad Request - Invalid Reference Number Format
400 Bad Request - Invalid Reference Number Format
400{
"statusCode": 400,
"message": "Invalid onboarding reference number format",
"error": "Bad Request",
"details": {
"refNumReceived": "invalid-uuid"
}
}
400 Bad Request - Record Does Not Exist
400 Bad Request - Record Does Not Exist
400{
"statusCode": 400,
"message": "Onboarding record does not exist",
"error": "Bad Request"
}
- The authenticated user has no associated business account
- The business account has no associated business record
- The onboarding record was deleted
400 Bad Request - Reference Number Mismatch
400 Bad Request - Reference Number Mismatch
400{
"statusCode": 400,
"message": "Onboarding reference number mismatch",
"error": "Bad Request",
"details": {
"refNumReceived": "550e8400-e29b-41d4-a716-446655440000"
}
}
401 Unauthorized
401 Unauthorized
401{
"statusCode": 401,
"message": "Account not found",
"error": "Unauthorized"
}
- Verify the Authorization header contains a valid JWT token
- Ensure the token hasn’t expired
- Confirm the account exists in the system
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)
NEW
DECLINED (Optional)
declinedReason field contains the reason for rejection. Merchant needs to update their information.PENDING (Optional)
APPROVED
# 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
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
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
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
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
Automated Polling
Conditional UI Updates
Notification Triggers
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
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
- 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
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
Onboard Merchant
Create Account
Authentication Guide
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
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?