MENU navbar-image

Introduction

This documentation aims to provide all the information you need to work with our API.

Authenticating requests

This API is not authenticated.

Admin Authentication

Admin login

Authenticates an admin user and returns an access token. If two-factor authentication is enabled, it will require verification.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/login" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"[email protected]\",
    \"password\": \"password123\",
    \"two_factor_code\": \"123456\",
    \"recovery_code\": \"ABCDEF-123456\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/login"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]",
    "password": "password123",
    "two_factor_code": "123456",
    "recovery_code": "ABCDEF-123456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, Success):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Successfully logged in",
    "data": {
        "token": "1|abcdefghijklmnopqrstuvwxyz123456",
        "refresh_token": "abcdefghijklmnopqrstuvwxyz123456",
        "expire_at": "01-01-23 12:30:00",
        "token_type": "Bearer",
        "admin": {
            "id": 1,
            "name": "Admin User",
            "email": "[email protected]",
            "role": "super_admin",
            "roles": [
                "super_admin"
            ],
            "permissions": [
                "view_dashboard",
                "manage_users"
            ],
            "profile_image": "https://example.com/images/profile.jpg",
            "two_factor_enabled": true,
            "two_factor_method": "email"
        }
    }
}
 

Example response (200, Two-factor required):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Two-factor authentication required",
    "data": {
        "two_factor_required": true,
        "two_factor_method": "email"
    }
}
 

Example response (403, Account deactivated):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Your account has been deactivated. Please contact support.",
    "data": null
}
 

Example response (422, Invalid credentials):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "invalid credentials",
    "data": null
}
 

Request      

POST api/admin/login

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

email   string   

Admin email address. Example: [email protected]

password   string   

Admin password (min 6 characters). Example: password123

two_factor_code   string  optional  

Two-factor authentication code (6 digits). Example: 123456

recovery_code   string  optional  

Recovery code for two-factor authentication. Example: ABCDEF-123456

Admin logout

requires authentication

Invalidates the current access token for the authenticated admin user.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/logout" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/logout"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Successfully logged out",
    "data": null
}
 

Example response (500):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Internal server error",
    "data": null
}
 

Request      

POST api/admin/logout

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Request password reset

Sends a password reset OTP to the admin's email address.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/forgot-password" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"[email protected]\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/forgot-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, Success):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Password reset OTP sent to your email",
    "data": null
}
 

Example response (404, Email not found):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin with this email not found",
    "data": null
}
 

Request      

POST api/admin/forgot-password

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

email   string   

Admin email address. Example: [email protected]

Verify OTP and reset password

Verifies the OTP and resets the admin's password.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/reset-password" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"[email protected]\",
    \"otp\": \"123456\",
    \"password\": \"newpassword123\",
    \"password_confirmation\": \"newpassword123\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/reset-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]",
    "otp": "123456",
    "password": "newpassword123",
    "password_confirmation": "newpassword123"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, Success):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Password reset successfully",
    "data": null
}
 

Example response (400, Invalid OTP):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Invalid verification code",
    "data": null
}
 

Example response (404, Email not found):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin with this email not found",
    "data": null
}
 

Request      

POST api/admin/reset-password

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

email   string   

Admin email address. Example: [email protected]

otp   string   

The verification code sent to the admin's email. Example: 123456

password   string   

New password (min 6 characters). Example: newpassword123

password_confirmation   string   

Password confirmation. Example: newpassword123

Admin Chat

List conversations

requires authentication

Retrieves all chat conversations for the authenticated admin user.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/chat/conversations" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/chat/conversations"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Conversations retrieved successfully",
    "data": [
        {
            "id": 1,
            "title": "Support Conversation",
            "admin_id": 1,
            "agent_id": 2,
            "is_closed": false,
            "last_message": "How can I help you today?",
            "last_message_at": "2023-01-01T12:00:00.000000Z",
            "unread_count": 0,
            "created_at": "2023-01-01T12:00:00.000000Z",
            "updated_at": "2023-01-01T12:00:00.000000Z",
            "agent": {
                "id": 2,
                "first_name": "John",
                "last_name": "Doe",
                "profile": "profiles/agent.jpg"
            }
        }
    ]
}
 

Request      

GET api/admin/chat/conversations

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Get conversation details

requires authentication

Retrieves details of a specific conversation by ID.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/chat/conversations/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/chat/conversations/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Conversation retrieved successfully",
    "data": {
        "id": 1,
        "title": "Support Conversation",
        "admin_id": 1,
        "agent_id": 2,
        "is_closed": false,
        "last_message": "How can I help you today?",
        "last_message_at": "2023-01-01T12:00:00.000000Z",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z",
        "agent": {
            "id": 2,
            "first_name": "John",
            "last_name": "Doe",
            "email": "[email protected]",
            "phone": "+1234567890",
            "profile": "profiles/agent.jpg"
        }
    }
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "You do not have access to this conversation",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Conversation not found",
    "data": null
}
 

Request      

GET api/admin/chat/conversations/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the conversation. Example: 1

List conversation messages

requires authentication

Retrieves messages for a specific conversation with pagination support. Also marks messages as read for the authenticated admin.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/chat/conversations/ipsam/messages?page=1&per_page=15" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/chat/conversations/ipsam/messages"
);

const params = {
    "page": "1",
    "per_page": "15",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Messages retrieved successfully",
    "data": {
        "current_page": 1,
        "data": [
            {
                "id": 1,
                "conversation_id": 1,
                "sender_type": "App\\Models\\Admin",
                "sender_id": 1,
                "message": "Hello, how can I help you today?",
                "attachments": [],
                "is_read": true,
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z",
                "sender": {
                    "id": 1,
                    "name": "Admin User",
                    "profile_image": "profiles/admin.jpg"
                }
            },
            {
                "id": 2,
                "conversation_id": 1,
                "sender_type": "App\\Models\\Agent",
                "sender_id": 2,
                "message": "I need help with my account",
                "attachments": [],
                "is_read": true,
                "created_at": "2023-01-01T12:05:00.000000Z",
                "updated_at": "2023-01-01T12:05:00.000000Z",
                "sender": {
                    "id": 2,
                    "first_name": "John",
                    "last_name": "Doe",
                    "profile": "profiles/agent.jpg"
                }
            }
        ],
        "first_page_url": "http://example.com/api/admin/chat/conversations/1/messages?page=1",
        "from": 1,
        "last_page": 1,
        "last_page_url": "http://example.com/api/admin/chat/conversations/1/messages?page=1",
        "links": [],
        "next_page_url": null,
        "path": "http://example.com/api/admin/chat/conversations/1/messages",
        "per_page": 15,
        "prev_page_url": null,
        "to": 2,
        "total": 2
    }
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "You do not have access to this conversation",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Conversation not found",
    "data": null
}
 

Request      

GET api/admin/chat/conversations/{id}/messages

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the conversation. Example: ipsam

conversationId   integer   

The ID of the conversation. Example: 1

Query Parameters

page   integer  optional  

Page number for pagination. Example: 1

per_page   integer  optional  

Number of messages per page. Example: 15

Create conversation

requires authentication

Creates a new chat conversation between the authenticated admin and an agent.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/chat/conversations" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"agent_id\": 2,
    \"title\": \"Support Request\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/chat/conversations"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "agent_id": 2,
    "title": "Support Request"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Conversation created successfully",
    "data": {
        "id": 1,
        "title": "Support Request",
        "admin_id": 1,
        "agent_id": 2,
        "is_closed": false,
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z",
        "agent": {
            "id": 2,
            "first_name": "John",
            "last_name": "Doe",
            "email": "[email protected]",
            "phone": "+1234567890",
            "profile": "profiles/agent.jpg"
        }
    }
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The agent id field is required",
    "data": null
}
 

Request      

POST api/admin/chat/conversations

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

agent_id   integer   

The ID of the agent to start a conversation with. Example: 2

title   string  optional  

Optional title for the conversation. Example: Support Request

Send message

requires authentication

Sends a new message in an existing conversation.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/chat/conversations/voluptate/messages" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"message\": \"Hello, how can I help you today?\",
    \"attachments\": [
        \"laboriosam\"
    ]
}"
const url = new URL(
    "https://sabisave.com/api/admin/chat/conversations/voluptate/messages"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "message": "Hello, how can I help you today?",
    "attachments": [
        "laboriosam"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Message sent successfully",
    "data": {
        "id": 3,
        "conversation_id": 1,
        "sender_type": "App\\Models\\Admin",
        "sender_id": 1,
        "message": "Hello, how can I help you today?",
        "attachments": [],
        "is_read": false,
        "created_at": "2023-01-01T12:10:00.000000Z",
        "updated_at": "2023-01-01T12:10:00.000000Z",
        "sender": {
            "id": 1,
            "name": "Admin User",
            "profile_image": "profiles/admin.jpg"
        }
    }
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "This conversation is closed",
    "data": null
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "You do not have access to this conversation",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Conversation not found",
    "data": null
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The message field is required",
    "data": null
}
 

Request      

POST api/admin/chat/conversations/{id}/messages

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the conversation. Example: voluptate

conversationId   integer   

The ID of the conversation. Example: 1

Body Parameters

message   string   

The message content to send. Example: Hello, how can I help you today?

attachments   string[]  optional  

Optional array of attachments to include with the message.

Close conversation

requires authentication

Closes an active conversation, preventing new messages from being sent.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/chat/conversations/fugiat/close" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/chat/conversations/fugiat/close"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Conversation closed successfully",
    "data": null
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "You do not have access to this conversation",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Conversation not found",
    "data": null
}
 

Request      

POST api/admin/chat/conversations/{id}/close

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the conversation. Example: fugiat

conversationId   integer   

The ID of the conversation to close. Example: 1

Reopen conversation

requires authentication

Reopens a previously closed conversation, allowing new messages to be sent.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/chat/conversations/non/reopen" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/chat/conversations/non/reopen"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Conversation reopened successfully",
    "data": null
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "You do not have access to this conversation",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Conversation not found",
    "data": null
}
 

Request      

POST api/admin/chat/conversations/{id}/reopen

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the conversation. Example: non

conversationId   integer   

The ID of the conversation to reopen. Example: 1

List available agents

requires authentication

Retrieves a list of all agents available for starting a new conversation.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/chat/agents" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/chat/agents"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Agents retrieved successfully",
    "data": [
        {
            "id": 1,
            "first_name": "John",
            "last_name": "Doe",
            "email": "[email protected]",
            "phone": "+1234567890",
            "profile": "profiles/agent1.jpg"
        },
        {
            "id": 2,
            "first_name": "Jane",
            "last_name": "Smith",
            "email": "[email protected]",
            "phone": "+0987654321",
            "profile": "profiles/agent2.jpg"
        }
    ]
}
 

Request      

GET api/admin/chat/agents

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Admin Dashboard

APIs for retrieving dashboard statistics and analytics data

Get Dashboard Statistics

requires authentication

Retrieves comprehensive dashboard statistics and analytics data for the admin dashboard, including financial summaries, user counts, and chart data for visualizations.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/dashboard?time_frame=last_30_days&chart_period=yearly" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/dashboard"
);

const params = {
    "time_frame": "last_30_days",
    "chart_period": "yearly",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, Success):


{
    "success": true,
    "message": "Dashboard data retrieved successfully",
    "data": {
        "summary": {
            "total_collections": 250000.5,
            "total_withdrawals": 125000.25,
            "total_traders": 500,
            "total_agents": 50
        },
        "analytics": {
            "labels": [
                "Jan",
                "Feb",
                "Mar",
                "Apr",
                "May",
                "Jun",
                "Jul",
                "Aug",
                "Sep",
                "Oct",
                "Nov",
                "Dec"
            ],
            "datasets": [
                {
                    "label": "Collections",
                    "data": [
                        15000,
                        21000,
                        18000,
                        24000,
                        23000,
                        24000,
                        19000,
                        20000,
                        22000,
                        20000,
                        25000,
                        19000
                    ],
                    "borderColor": "#F6C000",
                    "backgroundColor": "rgba(246, 192, 0, 0.1)"
                },
                {
                    "label": "Withdrawals",
                    "data": [
                        10000,
                        15000,
                        12000,
                        14000,
                        9000,
                        10000,
                        12000,
                        8000,
                        7500,
                        9000,
                        10000,
                        8500
                    ],
                    "borderColor": "#000000",
                    "backgroundColor": "rgba(0, 0, 0, 0.1)"
                }
            ]
        },
        "time_frame": "last_30_days"
    }
}
 

Example response (500, Server Error):


{
    "success": false,
    "message": "Internal server error",
    "error": {
        "code": 500,
        "message": "Server error details"
    }
}
 

Request      

GET api/admin/dashboard

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

time_frame   string  optional  

optional The time period for which to retrieve statistics. Options: today, yesterday, last_30_days (default). Example: last_30_days

chart_period   string  optional  

optional The period for chart data. Options: yearly (default). Example: yearly

Admin Management

List all admins

requires authentication

Retrieves a paginated list of all admin users with optional filtering by name, email, role, or status.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/admins?search=john&role=editor&status=1&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/admins"
);

const params = {
    "search": "john",
    "role": "editor",
    "status": "1",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admins retrieved successfully",
    "data": {
        "admins": {
            "current_page": 1,
            "data": [
                {
                    "id": 1,
                    "name": "Admin User",
                    "email": "[email protected]",
                    "phone": "1234567890",
                    "profile_image": "admin-profiles/image.jpg",
                    "status": true,
                    "created_at": "2023-01-01T12:00:00.000000Z",
                    "updated_at": "2023-01-01T12:00:00.000000Z",
                    "roles": [
                        {
                            "id": 1,
                            "name": "super-admin",
                            "guard_name": "admin",
                            "description": "Super Administrator",
                            "created_at": "2023-01-01T12:00:00.000000Z",
                            "updated_at": "2023-01-01T12:00:00.000000Z"
                        }
                    ]
                }
            ],
            "first_page_url": "http://example.com/api/admin/admins?page=1",
            "from": 1,
            "last_page": 1,
            "last_page_url": "http://example.com/api/admin/admins?page=1",
            "links": [],
            "next_page_url": null,
            "path": "http://example.com/api/admin/admins",
            "per_page": 10,
            "prev_page_url": null,
            "to": 1,
            "total": 1
        },
        "roles": [
            {
                "id": 1,
                "name": "super-admin",
                "guard_name": "admin",
                "description": "Super Administrator",
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z"
            }
        ]
    }
}
 

Request      

GET api/admin/admins

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Search term for filtering by name or email. Example: john

role   string  optional  

Filter by role name. Example: editor

status   boolean  optional  

Filter by account status (1 for active, 0 for inactive). Example: true

page   integer  optional  

Page number for pagination. Example: 1

Get admin details

requires authentication

Retrieves detailed information about a specific admin user including their roles.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/admins/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/admins/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin retrieved successfully",
    "data": {
        "id": 1,
        "name": "Admin",
        "last_name": "User",
        "email": "[email protected]",
        "phone": "+1234567890",
        "profile_image": "admin-profiles/profile.jpg",
        "status": true,
        "is_admin": true,
        "gender": "male",
        "dob": "1990-01-01",
        "address": "123 Main St, City",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z",
        "roles": [
            {
                "id": 1,
                "name": "super-admin",
                "guard_name": "admin",
                "description": "Super Administrator",
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z"
            }
        ]
    }
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin not found",
    "data": null
}
 

Request      

GET api/admin/admins/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the admin. Example: 1

Create a new admin

requires authentication

Creates a new admin user with the specified details and assigns a role.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/admins/store" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=John"\
    --form "[email protected]"\
    --form "password=password123"\
    --form "role=editor"\
    --form "phone=+1234567890"\
    --form "last_name=Doe"\
    --form "gender=male"\
    --form "dob=1990-01-01"\
    --form "address=123 Main St, City"\
    --form "profile_image=@/tmp/php3bZ7Pv" 
const url = new URL(
    "https://sabisave.com/api/admin/admins/store"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'John');
body.append('email', '[email protected]');
body.append('password', 'password123');
body.append('role', 'editor');
body.append('phone', '+1234567890');
body.append('last_name', 'Doe');
body.append('gender', 'male');
body.append('dob', '1990-01-01');
body.append('address', '123 Main St, City');
body.append('profile_image', document.querySelector('input[name="profile_image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin created successfully",
    "data": {
        "id": 2,
        "name": "John",
        "last_name": "Doe",
        "email": "[email protected]",
        "phone": "+1234567890",
        "profile_image": "admin-profiles/profile.jpg",
        "status": true,
        "is_admin": true,
        "gender": "male",
        "dob": "1990-01-01",
        "address": "123 Main St, City",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The given data was invalid.",
    "data": {
        "email": [
            "The email has already been taken."
        ]
    }
}
 

Request      

POST api/admin/admins/store

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

name   string   

Admin's first name. Example: John

email   string   

Admin's email address. Example: [email protected]

password   string   

Admin's password (min 8 characters). Example: password123

role   string   

Role name to assign to the admin. Example: editor

phone   string  optional  

Admin's phone number. Example: +1234567890

profile_image   file  optional  

Admin's profile image (jpeg, png, jpg, gif, max 2MB). Example: /tmp/php3bZ7Pv

last_name   string  optional  

Admin's last name. Example: Doe

gender   string  optional  

Admin's gender (male, female, rather_not_say). Example: male

dob   date  optional  

Admin's date of birth. Example: 1990-01-01

address   string  optional  

Admin's address. Example: 123 Main St, City

Update admin

requires authentication

Updates an existing admin user's details and role.

Example request:
curl --request PUT \
    "https://sabisave.com/api/admin/admins/update/1" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=John"\
    --form "[email protected]"\
    --form "role=editor"\
    --form "phone=+1234567890"\
    --form "last_name=Doe"\
    --form "gender=male"\
    --form "dob=1990-01-01"\
    --form "password=newpassword123"\
    --form "address=123 Main St, City"\
    --form "profile_image=@/tmp/phpqfZqGK" 
const url = new URL(
    "https://sabisave.com/api/admin/admins/update/1"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'John');
body.append('email', '[email protected]');
body.append('role', 'editor');
body.append('phone', '+1234567890');
body.append('last_name', 'Doe');
body.append('gender', 'male');
body.append('dob', '1990-01-01');
body.append('password', 'newpassword123');
body.append('address', '123 Main St, City');
body.append('profile_image', document.querySelector('input[name="profile_image"]').files[0]);

fetch(url, {
    method: "PUT",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin updated successfully",
    "data": {
        "id": 1,
        "name": "John",
        "last_name": "Doe",
        "email": "[email protected]",
        "phone": "+1234567890",
        "profile_image": "admin-profiles/profile.jpg",
        "status": true,
        "is_admin": true,
        "gender": "male",
        "dob": "1990-01-01",
        "address": "123 Main St, City",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin not found",
    "data": null
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The given data was invalid.",
    "data": {
        "email": [
            "The email has already been taken."
        ]
    }
}
 

Request      

PUT api/admin/admins/update/{id}

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the admin. Example: 1

Body Parameters

name   string   

Admin's first name. Example: John

email   string   

Admin's email address. Example: [email protected]

role   string   

Role name to assign to the admin. Example: editor

phone   string  optional  

Admin's phone number. Example: +1234567890

profile_image   file  optional  

Admin's profile image (jpeg, png, jpg, gif, max 2MB). Example: /tmp/phpqfZqGK

last_name   string  optional  

Admin's last name. Example: Doe

gender   string  optional  

Admin's gender (male, female, rather_not_say). Example: male

dob   date  optional  

Admin's date of birth. Example: 1990-01-01

password   string  optional  

Admin's new password (min 8 characters). Example: newpassword123

address   string  optional  

Admin's address. Example: 123 Main St, City

Delete admin

requires authentication

Permanently deletes an admin account.

Example request:
curl --request DELETE \
    "https://sabisave.com/api/admin/admins/delete/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/admins/delete/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin deleted successfully",
    "data": null
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot delete your own account",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin not found",
    "data": null
}
 

Request      

DELETE api/admin/admins/delete/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the admin. Example: 1

Toggle admin status

requires authentication

Activates or deactivates an admin account.

Example request:
curl --request PATCH \
    "https://sabisave.com/api/admin/admins/toggle-status/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/admins/toggle-status/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "PATCH",
    headers,
}).then(response => response.json());

Example response (200, Deactivated):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin deactivated successfully",
    "data": {
        "id": 1,
        "status": false,
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (200, Activated):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin activated successfully",
    "data": {
        "id": 1,
        "status": true,
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot deactivate your own account",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin not found",
    "data": null
}
 

Request      

PATCH api/admin/admins/toggle-status/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the admin. Example: 1

Create a new admin

requires authentication

Creates a new admin user with the specified details and assigns a role.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/admins" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=John"\
    --form "[email protected]"\
    --form "password=password123"\
    --form "role=editor"\
    --form "phone=+1234567890"\
    --form "last_name=Doe"\
    --form "gender=male"\
    --form "dob=1990-01-01"\
    --form "address=123 Main St, City"\
    --form "profile_image=@/tmp/php3GnyJn" 
const url = new URL(
    "https://sabisave.com/api/admin/admins"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'John');
body.append('email', '[email protected]');
body.append('password', 'password123');
body.append('role', 'editor');
body.append('phone', '+1234567890');
body.append('last_name', 'Doe');
body.append('gender', 'male');
body.append('dob', '1990-01-01');
body.append('address', '123 Main St, City');
body.append('profile_image', document.querySelector('input[name="profile_image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin created successfully",
    "data": {
        "id": 2,
        "name": "John",
        "last_name": "Doe",
        "email": "[email protected]",
        "phone": "+1234567890",
        "profile_image": "admin-profiles/profile.jpg",
        "status": true,
        "is_admin": true,
        "gender": "male",
        "dob": "1990-01-01",
        "address": "123 Main St, City",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The given data was invalid.",
    "data": {
        "email": [
            "The email has already been taken."
        ]
    }
}
 

Request      

POST api/admin/admins

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

name   string   

Admin's first name. Example: John

email   string   

Admin's email address. Example: [email protected]

password   string   

Admin's password (min 8 characters). Example: password123

role   string   

Role name to assign to the admin. Example: editor

phone   string  optional  

Admin's phone number. Example: +1234567890

profile_image   file  optional  

Admin's profile image (jpeg, png, jpg, gif, max 2MB). Example: /tmp/php3GnyJn

last_name   string  optional  

Admin's last name. Example: Doe

gender   string  optional  

Admin's gender (male, female, rather_not_say). Example: male

dob   date  optional  

Admin's date of birth. Example: 1990-01-01

address   string  optional  

Admin's address. Example: 123 Main St, City

Update admin

requires authentication

Updates an existing admin user's details and role.

Example request:
curl --request PUT \
    "https://sabisave.com/api/admin/admins/1" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=John"\
    --form "[email protected]"\
    --form "role=editor"\
    --form "phone=+1234567890"\
    --form "last_name=Doe"\
    --form "gender=male"\
    --form "dob=1990-01-01"\
    --form "password=newpassword123"\
    --form "address=123 Main St, City"\
    --form "profile_image=@/tmp/phphWj6OA" 
const url = new URL(
    "https://sabisave.com/api/admin/admins/1"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'John');
body.append('email', '[email protected]');
body.append('role', 'editor');
body.append('phone', '+1234567890');
body.append('last_name', 'Doe');
body.append('gender', 'male');
body.append('dob', '1990-01-01');
body.append('password', 'newpassword123');
body.append('address', '123 Main St, City');
body.append('profile_image', document.querySelector('input[name="profile_image"]').files[0]);

fetch(url, {
    method: "PUT",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin updated successfully",
    "data": {
        "id": 1,
        "name": "John",
        "last_name": "Doe",
        "email": "[email protected]",
        "phone": "+1234567890",
        "profile_image": "admin-profiles/profile.jpg",
        "status": true,
        "is_admin": true,
        "gender": "male",
        "dob": "1990-01-01",
        "address": "123 Main St, City",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin not found",
    "data": null
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The given data was invalid.",
    "data": {
        "email": [
            "The email has already been taken."
        ]
    }
}
 

Request      

PUT api/admin/admins/{id}

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the admin. Example: 1

Body Parameters

name   string   

Admin's first name. Example: John

email   string   

Admin's email address. Example: [email protected]

role   string   

Role name to assign to the admin. Example: editor

phone   string  optional  

Admin's phone number. Example: +1234567890

profile_image   file  optional  

Admin's profile image (jpeg, png, jpg, gif, max 2MB). Example: /tmp/phphWj6OA

last_name   string  optional  

Admin's last name. Example: Doe

gender   string  optional  

Admin's gender (male, female, rather_not_say). Example: male

dob   date  optional  

Admin's date of birth. Example: 1990-01-01

password   string  optional  

Admin's new password (min 8 characters). Example: newpassword123

address   string  optional  

Admin's address. Example: 123 Main St, City

Toggle admin status

requires authentication

Activates or deactivates an admin account.

Example request:
curl --request PATCH \
    "https://sabisave.com/api/admin/admins/1/toggle-status" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/admins/1/toggle-status"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "PATCH",
    headers,
}).then(response => response.json());

Example response (200, Deactivated):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin deactivated successfully",
    "data": {
        "id": 1,
        "status": false,
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (200, Activated):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin activated successfully",
    "data": {
        "id": 1,
        "status": true,
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot deactivate your own account",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin not found",
    "data": null
}
 

Request      

PATCH api/admin/admins/{id}/toggle-status

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the admin. Example: 1

Delete admin

requires authentication

Permanently deletes an admin account.

Example request:
curl --request DELETE \
    "https://sabisave.com/api/admin/admins/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/admins/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Admin deleted successfully",
    "data": null
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot delete your own account",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Admin not found",
    "data": null
}
 

Request      

DELETE api/admin/admins/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the admin. Example: 1

Admin Profile Management

APIs for managing admin profile information

Get Admin Profile

requires authentication

Retrieves the authenticated admin's profile information including personal details and last login time.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/profile" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/profile"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, Success):


{
    "success": true,
    "message": "Profile retrieved successfully",
    "data": {
        "id": 1,
        "name": "John",
        "email": "[email protected]",
        "phone": "+1234567890",
        "role": "super_admin",
        "profile_image": "storage/admin/profile/image.jpg",
        "last_name": "Doe",
        "gender": "male",
        "dob": "1990-01-01",
        "address": "123 Admin Street, City",
        "last_login_at": "2023-05-17 10:30:45"
    }
}
 

Example response (500, Server Error):


{
    "success": false,
    "message": "Internal server error",
    "error": {
        "code": 500,
        "message": "Server error details"
    }
}
 

Request      

GET api/admin/profile

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Update Admin Profile

requires authentication

Updates the authenticated admin's profile information with the provided data.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/profile/update" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"John\",
    \"email\": \"[email protected]\",
    \"phone\": \"+1234567890\",
    \"last_name\": \"Doe\",
    \"gender\": \"male\",
    \"dob\": \"1990-01-01\",
    \"address\": \"123 Admin Street, City\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/profile/update"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "John",
    "email": "[email protected]",
    "phone": "+1234567890",
    "last_name": "Doe",
    "gender": "male",
    "dob": "1990-01-01",
    "address": "123 Admin Street, City"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, Success):


{
    "success": true,
    "message": "Profile updated successfully",
    "data": {
        "id": 1,
        "name": "John",
        "email": "[email protected]",
        "phone": "+1234567890",
        "role": "super_admin",
        "profile_image": "storage/admin/profile/image.jpg",
        "last_name": "Doe",
        "gender": "male",
        "dob": "1990-01-01",
        "address": "123 Admin Street, City"
    }
}
 

Example response (400, Validation Error):


{
    "success": false,
    "message": "Validation failed",
    "error": {
        "code": 400,
        "message": "The email has already been taken.",
        "data": {
            "email": [
                "The email has already been taken."
            ]
        }
    }
}
 

Example response (500, Server Error):


{
    "success": false,
    "message": "Internal server error",
    "error": {
        "code": 500,
        "message": "Server error details"
    }
}
 

Request      

POST api/admin/profile/update

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string  optional  

optional The admin's first name. Example: John

email   string  optional  

optional The admin's email address. Must be unique. Example: [email protected]

phone   string  optional  

optional The admin's phone number. Example: +1234567890

last_name   string  optional  

optional The admin's last name. Example: Doe

gender   string  optional  

optional The admin's gender. Must be one of: male, female, rather_not_say. Example: male

dob   date  optional  

optional The admin's date of birth. Example: 1990-01-01

address   string  optional  

optional The admin's address. Example: 123 Admin Street, City

Update Admin Profile Image

requires authentication

Updates the authenticated admin's profile image.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/profile/update-image" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "profile_image=@/tmp/phpxD3Svo" 
const url = new URL(
    "https://sabisave.com/api/admin/profile/update-image"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('profile_image', document.querySelector('input[name="profile_image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200, Success):


{
    "success": true,
    "message": "Profile image updated successfully",
    "data": {
        "profile_image": "storage/admin/profile/image123456.jpg"
    }
}
 

Example response (400, Validation Error):


{
    "success": false,
    "message": "Validation failed",
    "error": {
        "code": 400,
        "message": "The profile image field is required.",
        "data": {
            "profile_image": [
                "The profile image field is required."
            ]
        }
    }
}
 

Example response (500, Server Error):


{
    "success": false,
    "message": "Internal server error",
    "error": {
        "code": 500,
        "message": "Server error details"
    }
}
 

Request      

POST api/admin/profile/update-image

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

profile_image   file   

The admin's profile image file. Must be an image (jpeg, png, jpg, gif) and less than 2MB. Example: /tmp/phpxD3Svo

Change Admin Password

requires authentication

Updates the authenticated admin's password after verifying the current password.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/profile/change-password" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"current_password\": null,
    \"password\": null,
    \"password_confirmation\": null
}"
const url = new URL(
    "https://sabisave.com/api/admin/profile/change-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "current_password": null,
    "password": null,
    "password_confirmation": null
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, Success):


{
    "success": true,
    "message": "Password changed successfully"
}
 

Example response (400, Validation Error):


{
    "success": false,
    "message": "Validation failed",
    "error": {
        "code": 400,
        "message": "The password confirmation does not match.",
        "data": {
            "password": [
                "The password confirmation does not match."
            ]
        }
    }
}
 

Example response (400, Incorrect Current Password):


{
    "success": false,
    "message": "Current password is incorrect",
    "error": {
        "code": 102,
        "message": "Current password is incorrect"
    }
}
 

Example response (500, Server Error):


{
    "success": false,
    "message": "Internal server error",
    "error": {
        "code": 500,
        "message": "Server error details"
    }
}
 

Request      

POST api/admin/profile/change-password

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

current_password   string   

The admin's current password.

password   string   

The new password. Must be at least 8 characters.

password_confirmation   string   

Must match the new password.

Admin Roles & Permissions

List all roles

requires authentication

Retrieves a list of all available admin roles.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/admins/roles" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/admins/roles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Roles retrieved successfully",
    "data": [
        {
            "id": 1,
            "name": "super-admin",
            "guard_name": "admin",
            "description": "Super Administrator",
            "created_at": "2023-01-01T12:00:00.000000Z",
            "updated_at": "2023-01-01T12:00:00.000000Z",
            "permissions": [
                {
                    "id": 1,
                    "name": "manage_admins",
                    "guard_name": "admin",
                    "created_at": "2023-01-01T12:00:00.000000Z",
                    "updated_at": "2023-01-01T12:00:00.000000Z"
                }
            ]
        }
    ]
}
 

Request      

GET api/admin/admins/roles

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

List all roles

requires authentication

Retrieves a list of all available admin roles.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/roles" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/roles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Roles retrieved successfully",
    "data": [
        {
            "id": 1,
            "name": "super-admin",
            "guard_name": "admin",
            "description": "Super Administrator",
            "created_at": "2023-01-01T12:00:00.000000Z",
            "updated_at": "2023-01-01T12:00:00.000000Z",
            "permissions": [
                {
                    "id": 1,
                    "name": "manage_admins",
                    "guard_name": "admin",
                    "created_at": "2023-01-01T12:00:00.000000Z",
                    "updated_at": "2023-01-01T12:00:00.000000Z"
                }
            ]
        }
    ]
}
 

Request      

GET api/admin/roles

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Create role

requires authentication

Creates a new role with assigned permissions.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/roles" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"editor\",
    \"permissions\": [
        \"view_dashboard\",
        \"manage_content\"
    ],
    \"description\": \"Content Editor Role\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/roles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "editor",
    "permissions": [
        "view_dashboard",
        "manage_content"
    ],
    "description": "Content Editor Role"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Role created successfully",
    "data": {
        "id": 2,
        "name": "editor",
        "guard_name": "admin",
        "description": "Content Editor Role",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z",
        "permissions": [
            {
                "id": 2,
                "name": "view_dashboard",
                "guard_name": "admin",
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z"
            },
            {
                "id": 3,
                "name": "manage_content",
                "guard_name": "admin",
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z"
            }
        ]
    }
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The given data was invalid.",
    "data": {
        "name": [
            "The name has already been taken."
        ]
    }
}
 

Request      

POST api/admin/roles

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

The name of the role. Example: editor

permissions   string[]   

List of permission names to assign to the role.

description   string  optional  

Description of the role. Example: Content Editor Role

Update role

requires authentication

Updates an existing role and its assigned permissions.

Example request:
curl --request PUT \
    "https://sabisave.com/api/admin/roles/2" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"content_editor\",
    \"permissions\": [
        \"view_dashboard\",
        \"manage_content\",
        \"publish_articles\"
    ],
    \"description\": \"Content Editor with publishing rights\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/roles/2"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "content_editor",
    "permissions": [
        "view_dashboard",
        "manage_content",
        "publish_articles"
    ],
    "description": "Content Editor with publishing rights"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Role updated successfully",
    "data": {
        "id": 2,
        "name": "content_editor",
        "guard_name": "admin",
        "description": "Content Editor with publishing rights",
        "created_at": "2023-01-01T12:00:00.000000Z",
        "updated_at": "2023-01-01T12:00:00.000000Z",
        "permissions": [
            {
                "id": 2,
                "name": "view_dashboard",
                "guard_name": "admin",
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z"
            },
            {
                "id": 3,
                "name": "manage_content",
                "guard_name": "admin",
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z"
            },
            {
                "id": 4,
                "name": "publish_articles",
                "guard_name": "admin",
                "created_at": "2023-01-01T12:00:00.000000Z",
                "updated_at": "2023-01-01T12:00:00.000000Z"
            }
        ]
    }
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot modify super-admin role",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Role not found",
    "data": null
}
 

Request      

PUT api/admin/roles/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the role. Example: 2

Body Parameters

name   string   

The name of the role. Example: content_editor

permissions   string[]   

List of permission names to assign to the role.

description   string  optional  

Description of the role. Example: Content Editor with publishing rights

Delete role

requires authentication

Permanently deletes a role if it's not assigned to any admin users.

Example request:
curl --request DELETE \
    "https://sabisave.com/api/admin/roles/2" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/roles/2"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Role deleted successfully",
    "data": null
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot delete role that is assigned to 2 admin(s)",
    "data": null
}
 

Example response (403):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot delete super-admin role",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Role not found",
    "data": null
}
 

Request      

DELETE api/admin/roles/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the role. Example: 2

List all permissions

requires authentication

Retrieves a list of all available permissions for admin roles.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/permissions" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/permissions"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Permissions retrieved successfully",
    "data": [
        {
            "id": 1,
            "name": "manage_admins",
            "guard_name": "admin",
            "created_at": "2023-01-01T12:00:00.000000Z",
            "updated_at": "2023-01-01T12:00:00.000000Z"
        },
        {
            "id": 2,
            "name": "view_dashboard",
            "guard_name": "admin",
            "created_at": "2023-01-01T12:00:00.000000Z",
            "updated_at": "2023-01-01T12:00:00.000000Z"
        }
    ]
}
 

Request      

GET api/admin/permissions

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Admin Two-Factor Authentication

Get 2FA status

requires authentication

Retrieves the current two-factor authentication status for the authenticated admin user.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/two-factor-auth/status" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/status"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Two-factor authentication status retrieved successfully",
    "data": {
        "enabled": true,
        "method": "email",
        "confirmed": true,
        "has_recovery_codes": true
    }
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Request      

GET api/admin/two-factor-auth/status

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Enable 2FA

requires authentication

Enables two-factor authentication for the authenticated admin user and generates recovery codes.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/two-factor-auth/enable" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"method\": \"email\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/enable"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "method": "email"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Two-factor authentication has been enabled",
    "data": {
        "recovery_codes": [
            "ABCDEF-123456",
            "GHIJKL-789012",
            "MNOPQR-345678",
            "STUVWX-901234",
            "YZABCD-567890",
            "EFGHIJ-123456",
            "KLMNOP-789012",
            "QRSTUV-345678"
        ]
    }
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Two-factor authentication is already enabled",
    "data": null
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The method field must be either email or sms",
    "data": null
}
 

Request      

POST api/admin/two-factor-auth/enable

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

method   string   

The 2FA method to use (email or sms). Example: email

Disable 2FA

requires authentication

Disables two-factor authentication for the authenticated admin user.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/two-factor-auth/disable" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/disable"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Two-factor authentication has been disabled",
    "data": null
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Two-factor authentication is not enabled",
    "data": null
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Request      

POST api/admin/two-factor-auth/disable

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Change 2FA method

requires authentication

Changes the two-factor authentication method for the authenticated admin user.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/two-factor-auth/change-method" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"method\": \"sms\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/change-method"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "method": "sms"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Two-factor authentication method has been changed to sms",
    "data": null
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Two-factor authentication is not enabled",
    "data": null
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The method field must be either email or sms",
    "data": null
}
 

Request      

POST api/admin/two-factor-auth/change-method

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

method   string   

The new 2FA method to use (email or sms). Example: sms

Generate verification code

requires authentication

Generates and sends a new verification code to the admin user via their chosen method (email or SMS).

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/two-factor-auth/generate-code" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/generate-code"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Verification code has been sent to your email",
    "data": {
        "method": "email"
    }
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Two-factor authentication is not enabled",
    "data": null
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Request      

POST api/admin/two-factor-auth/generate-code

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Verify 2FA code

requires authentication

Verifies a two-factor authentication code for the authenticated admin user.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/two-factor-auth/verify-code" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"code\": \"123456\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/verify-code"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "123456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Two-factor authentication has been confirmed",
    "data": null
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Invalid verification code",
    "data": null
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The code must be 6 characters",
    "data": null
}
 

Request      

POST api/admin/two-factor-auth/verify-code

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

code   string   

The 6-digit verification code. Example: 123456

Verify recovery code

requires authentication

Verifies a recovery code for the authenticated admin user. Recovery codes can be used when the user doesn't have access to their primary 2FA method.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/two-factor-auth/verify-recovery-code" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"recovery_code\": \"ABCDEF-123456\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/verify-recovery-code"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "recovery_code": "ABCDEF-123456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Recovery code verified successfully",
    "data": {
        "remaining_codes": 7
    }
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Invalid recovery code",
    "data": null
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The recovery code field is required",
    "data": null
}
 

Request      

POST api/admin/two-factor-auth/verify-recovery-code

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

recovery_code   string   

The recovery code to verify. Example: ABCDEF-123456

Regenerate recovery codes

requires authentication

Generates a new set of recovery codes for the authenticated admin user. This invalidates all previously generated recovery codes.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/two-factor-auth/regenerate-recovery-codes" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/two-factor-auth/regenerate-recovery-codes"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Recovery codes have been regenerated",
    "data": {
        "recovery_codes": [
            "ABCDEF-123456",
            "GHIJKL-789012",
            "MNOPQR-345678",
            "STUVWX-901234",
            "YZABCD-567890",
            "EFGHIJ-123456",
            "KLMNOP-789012",
            "QRSTUV-345678"
        ]
    }
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Two-factor authentication is not enabled",
    "data": null
}
 

Example response (401):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "User not authenticated",
    "data": null
}
 

Request      

POST api/admin/two-factor-auth/regenerate-recovery-codes

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Agent Management

List all agents

requires authentication

Retrieves a paginated list of all agents along with summary statistics, status overview, and monthly analytics data.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/agents?page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/agents"
);

const params = {
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Agents data retrieved successfully",
    "data": {
        "summary": {
            "total_collections": 500000,
            "total_withdrawals": 200000,
            "earned_interest": 40000,
            "outstanding_balance": 300000,
            "total_agents": 50
        },
        "agents_status": {
            "total": 50,
            "active": 45,
            "inactive": 5,
            "active_percentage": 90,
            "inactive_percentage": 10
        },
        "analytics": {
            "labels": [
                "Jan",
                "Feb",
                "Mar",
                "Apr",
                "May",
                "Jun",
                "Jul",
                "Aug",
                "Sep",
                "Oct",
                "Nov",
                "Dec"
            ],
            "datasets": [
                {
                    "label": "Collections",
                    "data": [
                        10000,
                        15000,
                        20000,
                        25000,
                        30000,
                        35000,
                        40000,
                        45000,
                        50000,
                        55000,
                        60000,
                        65000
                    ],
                    "backgroundColor": "#F6C000"
                },
                {
                    "label": "Withdrawals",
                    "data": [
                        5000,
                        7500,
                        10000,
                        12500,
                        15000,
                        17500,
                        20000,
                        22500,
                        25000,
                        27500,
                        30000,
                        32500
                    ],
                    "backgroundColor": "#000000"
                }
            ]
        },
        "agents": {
            "data": [
                {
                    "id": 1,
                    "name": "John Doe",
                    "email": "[email protected]",
                    "phone": "+1234567890",
                    "status": {
                        "id": 1,
                        "name": "active"
                    },
                    "location": {
                        "country": "Nigeria",
                        "state": "Lagos",
                        "lga": "Ikeja"
                    },
                    "created_at": "2023-01-01T12:00:00.000000Z",
                    "updated_at": "2023-01-01T12:00:00.000000Z"
                }
            ],
            "links": {
                "first": "http://example.com/api/admin/agents?page=1",
                "last": "http://example.com/api/admin/agents?page=5",
                "prev": null,
                "next": "http://example.com/api/admin/agents?page=2"
            },
            "meta": {
                "current_page": 1,
                "from": 1,
                "last_page": 5,
                "path": "http://example.com/api/admin/agents",
                "per_page": 10,
                "to": 10,
                "total": 50
            }
        }
    }
}
 

Example response (500):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Internal server error",
    "data": null
}
 

Request      

GET api/admin/agents

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

page   integer  optional  

Page number for pagination. Example: 1

Get agent details

requires authentication

Retrieves detailed information about a specific agent including their personal details, financial summary, and transaction history.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/agents/agent/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/agents/agent/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Agent details retrieved successfully",
    "data": {
        "agent": {
            "id": 1,
            "name": "John Doe",
            "email": "[email protected]",
            "phone": "+1234567890",
            "status": {
                "id": 1,
                "name": "active"
            },
            "location": {
                "country": "Nigeria",
                "state": "Lagos",
                "lga": "Ikeja",
                "address": "123 Main Street"
            },
            "bank_details": {
                "bank_name": "Example Bank",
                "account_number": "1234567890",
                "account_name": "John Doe"
            },
            "created_at": "2023-01-01T12:00:00.000000Z",
            "updated_at": "2023-01-01T12:00:00.000000Z"
        },
        "financial_summary": {
            "balance": 50000,
            "total_collections": 100000,
            "total_withdrawals": 50000,
            "total_traders": 10
        },
        "recent_transactions": [
            {
                "id": 1,
                "type": "deposit",
                "amount": 10000,
                "status": {
                    "id": 1,
                    "name": "completed"
                },
                "trader": {
                    "id": 1,
                    "name": "Jane Smith"
                },
                "created_at": "2023-01-01T12:00:00.000000Z"
            }
        ]
    }
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Agent not found",
    "data": null
}
 

Request      

GET api/admin/agents/agent/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the agent. Example: 1

Toggle agent status

requires authentication

Blocks or unblocks an agent account. When blocked, the agent cannot access the system or perform any transactions.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/agents/1/toggle-block" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"reason\": \"Suspicious activity detected\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/agents/1/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "reason": "Suspicious activity detected"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, Blocked):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Agent blocked successfully",
    "data": {
        "id": 1,
        "name": "John Doe",
        "status": {
            "id": 2,
            "name": "inactive"
        },
        "block_reason": "Suspicious activity detected",
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (200, Unblocked):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Agent unblocked successfully",
    "data": {
        "id": 1,
        "name": "John Doe",
        "status": {
            "id": 1,
            "name": "active"
        },
        "block_reason": null,
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Agent not found",
    "data": null
}
 

Request      

POST api/admin/agents/{id}/toggle-block

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the agent. Example: 1

Body Parameters

reason   string   

Reason for blocking/unblocking the agent. Example: Suspicious activity detected

Delete agent

requires authentication

Permanently deletes an agent account and all associated data. This action cannot be undone.

Example request:
curl --request DELETE \
    "https://sabisave.com/api/admin/agents/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/agents/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Agent deleted successfully",
    "data": null
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot delete agent with active balance",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Agent not found",
    "data": null
}
 

Request      

DELETE api/admin/agents/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the agent. Example: 1

Agent Transactions

List agent transactions

requires authentication

Retrieves a paginated list of agent transactions with optional filtering by agent ID, date range, transaction type, and status.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/agents/transactions?agent_id=1&start_date=2023-01-01&end_date=2023-12-31&type=deposit&status_id=1&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/agents/transactions"
);

const params = {
    "agent_id": "1",
    "start_date": "2023-01-01",
    "end_date": "2023-12-31",
    "type": "deposit",
    "status_id": "1",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Transactions retrieved successfully",
    "data": {
        "transactions": {
            "current_page": 1,
            "data": [
                {
                    "id": 1,
                    "agent": {
                        "id": 1,
                        "name": "John Doe"
                    },
                    "trader": {
                        "id": 1,
                        "name": "Jane Smith"
                    },
                    "type": "deposit",
                    "amount": 10000,
                    "status": {
                        "id": 1,
                        "name": "completed"
                    },
                    "created_at": "2023-01-01T12:00:00.000000Z"
                }
            ],
            "first_page_url": "http://example.com/api/admin/agents/transactions?page=1",
            "from": 1,
            "last_page": 5,
            "last_page_url": "http://example.com/api/admin/agents/transactions?page=5",
            "links": [],
            "next_page_url": "http://example.com/api/admin/agents/transactions?page=2",
            "path": "http://example.com/api/admin/agents/transactions",
            "per_page": 10,
            "prev_page_url": null,
            "to": 10,
            "total": 50
        },
        "summary": {
            "total_amount": 500000,
            "total_count": 50
        }
    }
}
 

Example response (500):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Internal server error",
    "data": null
}
 

Request      

GET api/admin/agents/transactions

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

agent_id   integer  optional  

ID of the agent to filter transactions. Example: 1

start_date   string  optional  

date Start date for filtering transactions (YYYY-MM-DD). Example: 2023-01-01

end_date   string  optional  

date End date for filtering transactions (YYYY-MM-DD). Example: 2023-12-31

type   string  optional  

Transaction type (deposit/withdrawal). Example: deposit

status_id   integer  optional  

Status ID for filtering transactions. Example: 1

page   integer  optional  

Page number for pagination. Example: 1

Agents

APIs for Agents

Agent Login.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/login" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"agent_number\": \"8013221673\",
    \"password\": \"12345678\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/login"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "agent_number": "8013221673",
    "password": "12345678"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "status": 1,
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "refresh_token": "def50200ea86c5d6161c...",
  "expire_at": "29-06-24 14:57:10",
  "token_type": "Bearer",
  "message": "Successfully logged in",
  "agent": {
      "id": 1,
      "name": "John Doe",
      "agent_number": "8013221673",
      "email": "[email protected]",
      ...
  }
}
 

Example response (422):


{
    "message": "Invalid data sent",
    "details": {
        "agent_id": [
            "The agent id field is required."
        ],
        "password": [
            "The password must be at least 6 characters."
        ]
    }
}
 

Request      

POST api/agents/login

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

agent_number   string   

The agent number of the agent. Example: 8013221673

password   string   

The password of the agent. Minimum length of 6 characters. Example: 12345678

Create Agent Step 1.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/register-step-1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"username\": \"user_name\",
    \"email\": \"[email protected]\",
    \"phone\": \"08013221673\",
    \"trader_union\": \"user trader_union\",
    \"password\": \"12345678\",
    \"first_name\": \"John\",
    \"last_name\": \"mark\",
    \"gender\": \"male\",
    \"dob\": \"2024-03-09\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/register-step-1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "username": "user_name",
    "email": "[email protected]",
    "phone": "08013221673",
    "trader_union": "user trader_union",
    "password": "12345678",
    "first_name": "John",
    "last_name": "mark",
    "gender": "male",
    "dob": "2024-03-09"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201):


{
    "data": {
        "id": 4,
        "trader_union": "user trader_union",
        "email": "[email protected]",
        "username": "user_name",
        "password": "12345678",
        "first_name": "John",
        "last_name": "mark",
        "phone": "08013221673",
        "gender": "male",
        "dob": "2024-03-09"
    }
}
 

Example response (422):


{
    "message": "Invalid data sent",
    "details": {
        "email": [
            "The email field is required."
        ],
        "password": [
            "The password must be at least 8 characters."
        ]
    }
}
 

Request      

POST api/agents/register-step-1

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

username   string   

The username of the user. Example: user_name

email   string   

The email of the user. Example: [email protected]

phone   string   

The phone number of the user. Example: 08013221673

trader_union   string   

The trader union of the user. Example: user trader_union

password   string   

The password of the user. Example: 12345678

first_name   string   

The first name of the user. Example: John

last_name   string   

The last name of the user. Example: mark

gender   string   

The gender of the user. Example: male

dob   date   

The date of birth of the user. Example: 2024-03-09

Complete agent registration step 2.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/register-step-2" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"agent_id\": 1,
    \"country_id\": \"1\",
    \"state_id\": \"1\",
    \"lga_id\": \"1\",
    \"address\": \"\\\"123 Street, City, State\\\"\",
    \"post_code\": \"\\\"100001\\\"\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/register-step-2"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "agent_id": 1,
    "country_id": "1",
    "state_id": "1",
    "lga_id": "1",
    "address": "\"123 Street, City, State\"",
    "post_code": "\"100001\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Agent step 2 registration completed",
    "data": {
        "id": 1,
        "trader_union": "user trader_union",
        "email": "[email protected]",
        "username": "user_name",
        "password": "12345678",
        "first_name": "John",
        "last_name": "mark",
        "phone": "08013221673",
        "gender": "male",
        "dob": "2024-03-09",
        "country_id": "Nigeria",
        "state_id": "Abia State",
        "lga_id": "Ikwuano",
        "address": "5 cape ville",
        "post_code": "10090"
    }
}
 

Example response (403):


{
    "message": "User not verified",
    "details": []
}
 

Example response (404):


{
    "message": "Agent not found",
    "details": []
}
 

Request      

POST api/agents/register-step-2

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

agent_id   integer   

The ID of the agent. Example: 1

country_id   numeric   

The ID of the country. Example: 1

state_id   numeric   

The ID of the state. Example: 1

lga_id   numeric   

The ID of the local government area. Example: 1

address   string   

The address of the agent. Example: "123 Street, City, State"

post_code   string   

The postal code of the agent's address. Example: "100001"

Create a new transaction PIN for an agent.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/transaction-pin" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"pin\": \"1234\",
    \"pin_confirmation\": \"1234\",
    \"agent_id\": 1
}"
const url = new URL(
    "https://sabisave.com/api/agents/transaction-pin"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "pin": "1234",
    "pin_confirmation": "1234",
    "agent_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201):


{
    "message": "Transaction PIN created successfully",
    "data": {
        "agent_id": "8013221673"
    },
    "meta-links": []
}
 

Example response (404):


{
    "message": "Agent not found",
    "details": {
        "error": "Agent not found"
    }
}
 

Example response (500):


{
    "message": "Failed to create transaction PIN",
    "details": {
        "error": "Internal Server Error"
    }
}
 

Request      

POST api/agents/transaction-pin

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

pin   string   

The PIN of the transaction. Example: 1234

pin_confirmation   string   

The confirmation of the PIN. Example: 1234

agent_id   integer   

The ID of the agent. Example: 1

Profile image upload.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/uploadid" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "agent_id=1"\
    --form "id_type=passport"\
    --form "id_file=@/tmp/php4eUZ7r" 
const url = new URL(
    "https://sabisave.com/api/agents/uploadid"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('agent_id', '1');
body.append('id_type', 'passport');
body.append('id_file', document.querySelector('input[name="id_file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
  "message": "File uploaded successfully",

}
 

Example response (500):


{
    "message": "Failed to create ID",
    "error": "Error message"
}
 

Request      

POST api/agents/uploadid

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

agent_id   string   

The ID of the agent. Example: 1

id_type   string   

The type of ID. Example: passport

id_file   file   

The file of the ID. Example: /tmp/php4eUZ7r

Verify the token for the agent.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/verify-phone" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"2348012345678\",
    \"token\": \"123456\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/verify-phone"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "2348012345678",
    "token": "123456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Verification successful",
    "data": [],
    "meta-links": []
}
 

Example response (400):


{
    "success": false,
    "message": "Invalid or expired verification code",
    "errors": []
}
 

Example response (404):


{
    "success": false,
    "message": "Agent not found",
    "errors": []
}
 

Example response (500):


{
    "success": false,
    "message": "Failed to verify token",
    "errors": []
}
 

Request      

POST api/agents/verify-phone

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The ID of the agent. Example: 2348012345678

token   string   

The verification token. Example: 123456

Resend the verification token to the agent's phone number.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/resend-verification" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"2348012345678\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/resend-verification"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "2348012345678"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "success": true,
    "message": "Verification code resent successfully",
    "data": [],
    "meta-links": []
}
 

Example response (404):


{
    "success": false,
    "message": "Agent not found",
    "errors": []
}
 

Example response (500):


{
    "success": false,
    "message": "Failed to resend verification code",
    "errors": []
}
 

Request      

POST api/agents/resend-verification

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The ID of the agent. Example: 2348012345678

Get the profile for the specified agent.

requires authentication

This endpoint retrieves the profile information for an agent.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/agents/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/agents/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": {
        "id": 1,
        "first_name": "John",
        "last_name": "Doe",
        "email": "[email protected]",
        "phone": "1234567890",
        "gender": "male",
        "dob": "1990-01-01"
    }
}
 

Example response (404):


{
    "error": "Agent not found",
    "message": "Agent not found"
}
 

Example response (500):


{
    "error": "Failed to get profile",
    "message": "Failed to get profile"
}
 

Request      

GET api/agents/{agent_id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

agent_id   integer   

The ID of the agent. Example: 1

Get all agents.

requires authentication

This endpoint retrieves all the agents in the system.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/agents?number=3" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/agents"
);

const params = {
    "number": "3",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{"data": [{"id": 1, "first_name": "John", "last_name": "Doe", "email": "[email protected]", "phone": "1234567890", "gender": "male", "dob": "1990-01-01"}, {"id": 2, "first_name": "Jane", "last_name": "Doe", "email": "[email protected]", "phone": "1234567890", "gender": "female", "dob": "1990-01-01"}, ...]}
 

Example response (500):


{
    "error": "Failed to get agents",
    "message": "Failed to get agents"
}
 

Request      

GET api/agents

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

number   integer  optional  

The number of agents to retrieve. Defaults to 10. Example: 3

Updates the transaction PIN for the specified agent.

requires authentication

This endpoint updates the transaction PIN for an agent after verifying a one-time password (OTP) sent to the agent's phone.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/update-transaction-pin" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"pin\": \"voluptatibus\",
    \"pin_confirmation\": \"laborum\",
    \"otp\": \"repudiandae\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/update-transaction-pin"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "pin": "voluptatibus",
    "pin_confirmation": "laborum",
    "otp": "repudiandae"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Transaction PIN updated successfully"
}
 

Example response (400):


{
    "error": "Invalid OTP",
    "message": "Invalid OTP provided"
}
 

Example response (500):


{"error": "Failed to update transaction PIN", "message": "Failed to update transaction PIN"}

Example Request:
{
  "pin": "1234",
  "pin_confirmation": "1234",
  "otp": "5678"
}

Example Response (Success):
{
  "message": "Transaction PIN updated successfully"
}

Example Response (Invalid OTP):
{
  "error": "Invalid OTP",
  "message": "Invalid OTP provided"
}

Example Response (Failed to update transaction PIN):
{
  "error": "Failed to update transaction PIN",
  "message": "Failed to update transaction PIN"
}
 

Request      

POST api/agents/update-transaction-pin

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

pin   string   

The new transaction PIN for the agent. Must be numeric and exactly 4 digits. Example: voluptatibus

pin_confirmation   string   

The confirmation of the new transaction PIN. Example: laborum

otp   string   

The one-time password sent to the agent's phone. Must be numeric and exactly 4 digits. Example: repudiandae

Updates the profile image for the specified agent.

requires authentication

This endpoint updates the profile image for an agent after verifying a one-time password (OTP) sent to the agent's phone.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/update-profile-image" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "otp=sit"\
    --form "profile_image=@/tmp/phpufwK6E" 
const url = new URL(
    "https://sabisave.com/api/agents/update-profile-image"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('otp', 'sit');
body.append('profile_image', document.querySelector('input[name="profile_image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
    "message": "image updated successfully"
}
 

Example response (400):


{
    "error": "Invalid OTP",
    "message": "Invalid OTP provided"
}
 

Example response (500):


{
    "error": "Failed to update profile image",
    "message": "Failed to update profile image"
}
 

Request      

POST api/agents/update-profile-image

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

profile_image   file  optional  

nullable The profile image of the agent. Must be in JPEG, PNG, or JPG format and cannot exceed 1MB in size. Example: /tmp/phpufwK6E

otp   string   

The one-time password sent to the agent's phone. Must be numeric and exactly 4 digits. Example: sit

Deactivate an agent account.

requires authentication

This endpoint deactivates an agent account after verifying a specific delete phrase.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/deactivate" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"delete_phrase\": \"\\\"delete_johndoe\\\".\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/deactivate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "delete_phrase": "\"delete_johndoe\"."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Agent deleted successfully"
}
 

Example response (400):


{
    "error": "Invalid delete phrase",
    "message": "Invalid delete phrase provided"
}
 

Example response (500):


{
    "error": "Failed to delete agent",
    "message": "Failed to delete agent"
}
 

Request      

POST api/agents/deactivate

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

delete_phrase   string   

The delete phrase to verify the deletion. Example: "delete_johndoe".

Reactivate an agent account.

requires authentication

This endpoint reactivates an agent account that has been previously deactivated.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/reactivate" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"agent_id\": 1
}"
const url = new URL(
    "https://sabisave.com/api/agents/reactivate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "agent_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Agent restored successfully"
}
 

Example response (404):


{
    "error": "Agent not found",
    "message": "Agent not found"
}
 

Request      

POST api/agents/reactivate

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

agent_id   integer   

The ID of the agent to reactivate. Example: 1

Update the password for the specified agent.

requires authentication

This endpoint updates the password for an agent after verifying the current password and a one-time password (OTP) sent to the agent's phone.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/change-password" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"password\": \"0L?iHQl_I\",
    \"password_confirmation\": \"quae\",
    \"current_password\": \"voluptas\",
    \"otp\": \"sed\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/change-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "password": "0L?iHQl_I",
    "password_confirmation": "quae",
    "current_password": "voluptas",
    "otp": "sed"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Password updated successfully"
}
 

Example response (400):


{
    "error": "In correct password",
    "message": "Current password does not match"
}
 

Example response (400):


{
    "error": "Invalid OTP",
    "message": "Invalid OTP provided"
}
 

Example response (500):


{
    "error": "Failed to update password",
    "message": "Failed to update password"
}
 

Request      

POST api/agents/change-password

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

password   string   

The new password for the agent. Must be at least 8 characters. Example: 0L?iHQl_I

password_confirmation   string   

The confirmation of the new password. Example: quae

current_password   string   

The current password of the agent. Must be at least 8 characters. Example: voluptas

otp   string   

The one-time password sent to the agent's phone. Must be numeric and exactly 4 digits. Example: sed

Update the profile for the specified agent.

requires authentication

This endpoint updates the profile information for an agent after verifying a one-time password (OTP) sent to the agent's phone.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/update-profile" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"first_name\": \"quod\",
    \"last_name\": \"enim\",
    \"email\": \"[email protected]\",
    \"phone\": \"voluptatem\",
    \"gender\": \"dolor\",
    \"dob\": \"numquam\",
    \"trader_union\": \"impedit\",
    \"otp\": \"nam\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/update-profile"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "first_name": "quod",
    "last_name": "enim",
    "email": "[email protected]",
    "phone": "voluptatem",
    "gender": "dolor",
    "dob": "numquam",
    "trader_union": "impedit",
    "otp": "nam"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Profile updated successfully"
}
 

Example response (400):


{
    "error": "Invalid OTP",
    "message": "Invalid OTP provided"
}
 

Example response (500):


{
    "error": "Failed to update profile",
    "message": "Failed to update profile"
}
 

Request      

POST api/agents/update-profile

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

first_name   string  optional  

nullable The first name of the agent. Maximum length is 255 characters. Example: quod

last_name   string  optional  

nullable The last name of the agent. Maximum length is 255 characters. Example: enim

email   string  optional  

nullable The email address of the agent. Must be a valid email address and maximum length is 255 characters. Example: [email protected]

phone   string  optional  

nullable The phone number of the agent. Maximum length is 255 characters. Example: voluptatem

gender   string  optional  

nullable The gender of the agent. Example: dolor

dob   date  optional  

nullable The date of birth of the agent. Example: numquam

trader_union   string  optional  

nullable The trader union of the agent. Maximum length is 255 characters. Example: impedit

otp   string   

The one-time password sent to the agent's phone. Must be numeric and exactly 4 digits. Example: nam

Banks

Get list of supported banks.

requires authentication

This endpoint returns a list of banks available for transactions. Requires Bearer Token Authentication.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/banks" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/banks"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2025-05-18T06:00:39.874949Z",
    "status": true,
    "message": "Banks",
    "data": {
        "success": true,
        "data": [
            {
                "id": 302,
                "name": "9mobile 9Payment Service Bank",
                "slug": "9mobile-9payment-service-bank-ng",
                "code": "120001",
                "longcode": "120001",
                "gateway": "",
                "pay_with_bank": false,
                "supports_transfer": true,
                "active": true,
                "country": "Nigeria",
                "currency": "NGN",
                "type": "nuban",
                "is_deleted": false,
                "createdAt": "2022-05-31T06:50:27.000Z",
                "updatedAt": "2022-06-23T09:33:55.000Z"
            },
            {
                "id": 174,
                "name": "Abbey Mortgage Bank",
                "slug": "abbey-mortgage-bank-ng",
                "code": "404",
                "longcode": "",
                "gateway": null,
                "pay_with_bank": false,
                "supports_transfer": true,
                "active": true,
                "country": "Nigeria",
                "currency": "NGN",
                "type": "nuban",
                "is_deleted": false,
                "createdAt": "2020-12-07T16:19:09.000Z",
                "updatedAt": "2023-09-14T13:02:38.000Z"
            }
        ]
    }
}
 

Example response (500):


{
    "message": "cURL Error #: <description>"
}
 

Request      

GET api/banks

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Country

Get Counteries

Example request:
curl --request GET \
    --get "https://sabisave.com/api/countries" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/countries"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "Country Name"
        },
        {
            "id": 2,
            "name": "Another Country"
        }
    ]
}
 

Request      

GET api/countries

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Deposit

Process a deposit for a trader.

requires authentication

Example request:
curl --request POST \
    "https://sabisave.com/api/deposits" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"trader_account_number\": 1,
    \"amount\": \"\\\"23000\\\"\",
    \"agent_id\": \"\\\"1\\\"\",
    \"pin\": \"\\\"1234\\\"\"
}"
const url = new URL(
    "https://sabisave.com/api/deposits"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "trader_account_number": 1,
    "amount": "\"23000\"",
    "agent_id": "\"1\"",
    "pin": "\"1234\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "message": "Deposit successful",

}
 

Example response (500):


{
    "message": "Deposit failed",
    "errors": []
}
 

Request      

POST api/deposits

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

trader_account_number   integer   

The account number of the trader. Example: 1

amount   string   

The amount to be deposited. Example: "23000"

agent_id   string   

The ID of the agent processing the deposit. Example: "1"

pin   string   

The PIN of the agent processing the deposit. Example: "1234"

Endpoints

Register a device token for push notifications

Example request:
curl --request POST \
    "https://sabisave.com/api/notifications/register-token" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"token\": \"djweqeyjnt\",
    \"device_type\": \"ios\"
}"
const url = new URL(
    "https://sabisave.com/api/notifications/register-token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "token": "djweqeyjnt",
    "device_type": "ios"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/notifications/register-token

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

token   string   

Must not be greater than 255 characters. Example: djweqeyjnt

device_type   string   

Example: ios

Must be one of:
  • android
  • ios
  • web

Unregister a device token

Example request:
curl --request POST \
    "https://sabisave.com/api/notifications/unregister-token" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"token\": \"qtzlxredxlexpdorsp\"
}"
const url = new URL(
    "https://sabisave.com/api/notifications/unregister-token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "token": "qtzlxredxlexpdorsp"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/notifications/unregister-token

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

token   string   

Must not be greater than 255 characters. Example: qtzlxredxlexpdorsp

Get notification settings

Example request:
curl --request GET \
    --get "https://sabisave.com/api/notifications/settings" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/notifications/settings"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (403):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: http://localhost:3000
access-control-allow-credentials: true
 

{
    "status": false,
    "message": "Unauthorize"
}
 

Request      

GET api/notifications/settings

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Update notification settings

Example request:
curl --request POST \
    "https://sabisave.com/api/notifications/settings" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"general_notifications\": true,
    \"payment_notifications\": true,
    \"system_notifications\": false
}"
const url = new URL(
    "https://sabisave.com/api/notifications/settings"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "general_notifications": true,
    "payment_notifications": true,
    "system_notifications": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/notifications/settings

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

general_notifications   boolean  optional  

Example: true

payment_notifications   boolean  optional  

Example: true

system_notifications   boolean  optional  

Example: false

Get all notifications for the authenticated user

Example request:
curl --request GET \
    --get "https://sabisave.com/api/notifications" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/notifications"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (403):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: http://localhost:3000
access-control-allow-credentials: true
 

{
    "status": false,
    "message": "Unauthorize"
}
 

Request      

GET api/notifications

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Get unread notification count

Example request:
curl --request GET \
    --get "https://sabisave.com/api/notifications/unread-count" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/notifications/unread-count"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (403):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: http://localhost:3000
access-control-allow-credentials: true
 

{
    "status": false,
    "message": "Unauthorize"
}
 

Request      

GET api/notifications/unread-count

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Mark a notification as read

Example request:
curl --request POST \
    "https://sabisave.com/api/notifications/ut/read" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/notifications/ut/read"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/notifications/{id}/read

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the notification. Example: ut

Mark all notifications as read

Example request:
curl --request POST \
    "https://sabisave.com/api/notifications/read-all" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/notifications/read-all"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/notifications/read-all

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Delete a notification

Example request:
curl --request DELETE \
    "https://sabisave.com/api/notifications/qui" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/notifications/qui"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/notifications/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the notification. Example: qui

POST api/webhook/paystack

Example request:
curl --request POST \
    "https://sabisave.com/api/webhook/paystack" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/webhook/paystack"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/webhook/paystack

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Send a test notification to the authenticated admin

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/notifications/test" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/notifications/test"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/admin/notifications/test

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Send a notification to all traders

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/notifications/notify-all-traders" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/notifications/notify-all-traders"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/admin/notifications/notify-all-traders

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Send a notification to specific traders

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/notifications/notify-selected-traders" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/notifications/notify-selected-traders"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/admin/notifications/notify-selected-traders

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Send a notification to a topic

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/notifications/notify-topic" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/notifications/notify-topic"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/admin/notifications/notify-topic

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Get all conversations for the authenticated agent.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/agent/chat/conversations" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/agent/chat/conversations"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Request      

GET api/agent/chat/conversations

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Get a specific conversation.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/agent/chat/conversations/pariatur" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/agent/chat/conversations/pariatur"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Request      

GET api/agent/chat/conversations/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the conversation. Example: pariatur

Get messages for a conversation.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/agent/chat/conversations/rerum/messages" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/agent/chat/conversations/rerum/messages"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Request      

GET api/agent/chat/conversations/{id}/messages

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the conversation. Example: rerum

Create a new conversation with an admin.

Example request:
curl --request POST \
    "https://sabisave.com/api/agent/chat/conversations" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"admin_id\": \"officia\",
    \"title\": \"euzfgmlgprwhrizq\"
}"
const url = new URL(
    "https://sabisave.com/api/agent/chat/conversations"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "admin_id": "officia",
    "title": "euzfgmlgprwhrizq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/agent/chat/conversations

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

admin_id   string   

Example: officia

title   string  optional  

Must not be greater than 255 characters. Example: euzfgmlgprwhrizq

Send a message in a conversation.

Example request:
curl --request POST \
    "https://sabisave.com/api/agent/chat/conversations/velit/messages" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"message\": \"veritatis\"
}"
const url = new URL(
    "https://sabisave.com/api/agent/chat/conversations/velit/messages"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "message": "veritatis"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/agent/chat/conversations/{id}/messages

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the conversation. Example: velit

Body Parameters

message   string   

Example: veritatis

attachments   object  optional  

Get all admins for starting a new conversation.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/agent/chat/admins" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/agent/chat/admins"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Request      

GET api/agent/chat/admins

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Guarantor

Create a new guarantor.

Example request:
curl --request POST \
    "https://sabisave.com/api/agents/guarantor" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"agent_id\": 1,
    \"gua1_relationship\": \"\\\"Father\\\"\",
    \"gua1_marital_status\": \"\\\"Married\\\"\",
    \"gua1_name\": \"\\\"John Doe\\\"\",
    \"gua1_phone_1\": \"\\\"08012345678\\\"\",
    \"gua1_phone_2\": \"\\\"08098765432\\\"\",
    \"gua1_work_category\": \"\\\"Employed\\\"\",
    \"gua1_work_address\": \"\\\"123 Street, Lagos\\\"\",
    \"gua1_place_of_work\": \"\\\"ABC Company\\\"\",
    \"gua2_relationship\": \"\\\"Mother\\\"\",
    \"gua2_marital_status\": \"\\\"Single\\\"\",
    \"gua2_name\": \"\\\"Jane Doe\\\"\",
    \"gua2_phone_1\": \"\\\"08011122233\\\"\",
    \"gua2_phone_2\": \"\\\"08033344455\\\"\",
    \"gua2_work_category\": \"\\\"Self-Employed\\\"\",
    \"gua2_work_address\": \"\\\"456 Street, Abuja\\\"\",
    \"gua2_place_of_work\": \"\\\"XYZ Enterprise\\\"\"
}"
const url = new URL(
    "https://sabisave.com/api/agents/guarantor"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "agent_id": 1,
    "gua1_relationship": "\"Father\"",
    "gua1_marital_status": "\"Married\"",
    "gua1_name": "\"John Doe\"",
    "gua1_phone_1": "\"08012345678\"",
    "gua1_phone_2": "\"08098765432\"",
    "gua1_work_category": "\"Employed\"",
    "gua1_work_address": "\"123 Street, Lagos\"",
    "gua1_place_of_work": "\"ABC Company\"",
    "gua2_relationship": "\"Mother\"",
    "gua2_marital_status": "\"Single\"",
    "gua2_name": "\"Jane Doe\"",
    "gua2_phone_1": "\"08011122233\"",
    "gua2_phone_2": "\"08033344455\"",
    "gua2_work_category": "\"Self-Employed\"",
    "gua2_work_address": "\"456 Street, Abuja\"",
    "gua2_place_of_work": "\"XYZ Enterprise\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201):


{
    "data": {
        "id": 1,
        "agent_id": 1,
        "gua1_relationship": "Father",
        "gua1_marital_status": "Married",
        "gua1_name": "John Doe",
        "gua1_phone_1": "08012345678",
        "gua1_phone_2": "08098765432",
        "gua1_work_category": "Employed",
        "gua1_work_address": "123 Street, Lagos",
        "gua1_place_of_work": "ABC Company",
        "gua2_relationship": "Mother",
        "gua2_marital_status": "Single",
        "gua2_name": "Jane Doe",
        "gua2_phone_1": "08011122233",
        "gua2_phone_2": "08033344455",
        "gua2_work_category": "Self-Employed",
        "gua2_work_address": "456 Street, Abuja",
        "gua2_place_of_work": "XYZ Enterprise"
    }
}
 

Example response (400):


{
    "message": "Invalid data sent",
    "details": {
        "agent_id": [
            "The agent_id field is required."
        ],
        "gua1_relationship": [
            "The gua1_relationship field is required."
        ]
    }
}
 

Request      

POST api/agents/guarantor

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

agent_id   integer   

The ID of the agent. Example: 1

gua1_relationship   string   

The relationship of the first guarantor. Example: "Father"

gua1_marital_status   string   

The marital status of the first guarantor. Example: "Married"

gua1_name   string   

The name of the first guarantor. Example: "John Doe"

gua1_phone_1   string   

The first phone number of the first guarantor. Example: "08012345678"

gua1_phone_2   string  optional  

nullable The second phone number of the first guarantor. Example: "08098765432"

gua1_work_category   string   

The work category of the first guarantor. Example: "Employed"

gua1_work_address   string   

The work address of the first guarantor. Example: "123 Street, Lagos"

gua1_place_of_work   string   

The place of work of the first guarantor. Example: "ABC Company"

gua2_relationship   string  optional  

nullable The relationship of the second guarantor. Example: "Mother"

gua2_marital_status   string  optional  

nullable The marital status of the second guarantor. Example: "Single"

gua2_name   string  optional  

nullable The name of the second guarantor. Example: "Jane Doe"

gua2_phone_1   string  optional  

nullable The first phone number of the second guarantor. Example: "08011122233"

gua2_phone_2   string  optional  

nullable The second phone number of the second guarantor. Example: "08033344455"

gua2_work_category   string  optional  

nullable The work category of the second guarantor. Example: "Self-Employed"

gua2_work_address   string  optional  

nullable The work address of the second guarantor. Example: "456 Street, Abuja"

gua2_place_of_work   string  optional  

nullable The place of work of the second guarantor. Example: "XYZ Enterprise"

LGA

Get Local Government Area

Example request:
curl --request GET \
    --get "https://sabisave.com/api/lgas?country_id=1&state_id=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/lgas"
);

const params = {
    "country_id": "1",
    "state_id": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "Lga Name",
            "state_id": "1",
            "country_id": "1"
        },
        {
            "id": 2,
            "name": "Another Lga",
            "state_id": "1",
            "country_id": "1"
        }
    ]
}
 

Example response (500):


{
    "message": "An error occurred",
    "data": [],
    "statusCode": 500
}
 

Request      

GET api/lgas

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

country_id   integer  optional  

(optional)string The ID of the country. Example: 1

state_id   string  optional  

(optional)string The ID of the state. Example: 1

OAuth

APIs for OAuth token refresh

Refreshes an existing token.

Example request:
curl --request POST \
    "https://sabisave.com/api/auth/refresh-token" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"refresh_token\": \"\\\"your_refresh_token_here\\\"\"
}"
const url = new URL(
    "https://sabisave.com/api/auth/refresh-token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "refresh_token": "\"your_refresh_token_here\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "status": 1,
    "message": "Successfully refreshed token",
    "token": "your_new_token_here",
    "refresh_token": "your_new_refresh_token_here",
    "expire_at": "dd-mm-yy HH:mm:ss",
    "token_type": "Bearer"
}
 

Example response (400):


{
    "status": 0,
    "message": {
        "refresh_token": [
            "The refresh token is required.",
            "The refresh token must be at least 6 characters."
        ]
    }
}
 

Example response (403):


{
    "status": 0,
    "message": "Refresh token expired"
}
 

Example response (404):


{
    "status": 0,
    "message": "Refresh Token does not exist"
}
 

Request      

POST api/auth/refresh-token

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

refresh_token   string   

The refresh token to be used for token refresh. Example: "your_refresh_token_here"

State

Get all State

Get state by country id .

Example request:
curl --request GET \
    --get "https://sabisave.com/api/states" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/states"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (201):


{
    "data": {
        "id": 4,
        "name": "State Name",
        "country_id": "1"
    }
}
 

Example response (422):


{
    "message": "Invalid data sent",
    "details": {
        "country_id": [
            "The country_id field is required."
        ]
    }
}
 

Request      

GET api/states

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

country_id   string  optional  

The ID of the country. Example: 1

Trader Management

List all traders

requires authentication

Retrieves a paginated list of all traders along with summary statistics, trader status overview, savings plans overview, and monthly analytics data.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/traders?page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/traders"
);

const params = {
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Traders data retrieved successfully",
    "data": {
        "summary": {
            "total_savings": 500000,
            "total_withdrawals": 200000,
            "earned_interest": 40000,
            "total_traders": 50
        },
        "traders_overview": {
            "total": 50,
            "active": 45,
            "inactive": 5,
            "active_percentage": 90,
            "inactive_percentage": 10
        },
        "savings_plans_overview": {
            "daily": 30,
            "weekly": 20
        },
        "analytics": {
            "labels": [
                "Jan",
                "Feb",
                "Mar",
                "Apr",
                "May",
                "Jun",
                "Jul",
                "Aug",
                "Sep",
                "Oct",
                "Nov",
                "Dec"
            ],
            "datasets": [
                {
                    "label": "Deposits",
                    "data": [
                        10000,
                        15000,
                        20000,
                        25000,
                        30000,
                        35000,
                        40000,
                        45000,
                        50000,
                        55000,
                        60000,
                        65000
                    ],
                    "backgroundColor": "#F6C000"
                },
                {
                    "label": "Withdrawals",
                    "data": [
                        5000,
                        7500,
                        10000,
                        12500,
                        15000,
                        17500,
                        20000,
                        22500,
                        25000,
                        27500,
                        30000,
                        32500
                    ],
                    "backgroundColor": "#000000"
                }
            ]
        },
        "traders": {
            "data": [
                {
                    "id": 1,
                    "first_name": "John",
                    "last_name": "Doe",
                    "email": "[email protected]",
                    "phone": "+1234567890",
                    "status": {
                        "id": 1,
                        "name": "active"
                    },
                    "location": {
                        "country": "Nigeria",
                        "state": "Lagos",
                        "lga": "Ikeja"
                    },
                    "created_at": "2023-01-01T12:00:00.000000Z"
                }
            ],
            "links": {
                "first": "http://example.com/api/admin/traders?page=1",
                "last": "http://example.com/api/admin/traders?page=5",
                "prev": null,
                "next": "http://example.com/api/admin/traders?page=2"
            },
            "meta": {
                "current_page": 1,
                "from": 1,
                "last_page": 5,
                "path": "http://example.com/api/admin/traders",
                "per_page": 10,
                "to": 10,
                "total": 50
            }
        }
    }
}
 

Example response (500):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Internal server error",
    "data": null
}
 

Request      

GET api/admin/traders

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

page   integer  optional  

Page number for pagination. Example: 1

Get trader details

requires authentication

Retrieves detailed information about a specific trader including their personal details, financial summary, savings plan, and transaction history.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/traders/trader/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/traders/trader/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Trader details retrieved successfully",
    "data": {
        "trader": {
            "id": 1,
            "first_name": "John",
            "last_name": "Doe",
            "email": "[email protected]",
            "phone": "+1234567890",
            "status": {
                "id": 1,
                "name": "active"
            },
            "location": {
                "country": "Nigeria",
                "state": "Lagos",
                "lga": "Ikeja",
                "address": "123 Main Street"
            },
            "business_details": {
                "business_name": "Example Business",
                "business_type": "Retail",
                "business_address": "456 Market Street"
            },
            "bank_details": {
                "bank_name": "Example Bank",
                "account_number": "1234567890",
                "account_name": "John Doe"
            },
            "identification": {
                "id_type": "National ID",
                "id_number": "ID12345678",
                "id_image": "identifications/id.jpg"
            },
            "created_at": "2023-01-01T12:00:00.000000Z",
            "updated_at": "2023-01-01T12:00:00.000000Z"
        },
        "financial_summary": {
            "balance": 50000,
            "total_deposits": 100000,
            "total_withdrawals": 50000,
            "earned_interest": 0
        },
        "savings_plan": {
            "id": 1,
            "frequency": "daily",
            "amount": 1000,
            "start_date": "2023-01-01",
            "end_date": "2023-12-31",
            "status": "active"
        },
        "transactions": {
            "data": [
                {
                    "id": 1,
                    "type": "deposit",
                    "amount": 10000,
                    "status": {
                        "id": 1,
                        "name": "completed"
                    },
                    "created_at": "2023-01-01T12:00:00.000000Z"
                }
            ],
            "links": {
                "first": "http://example.com/api/admin/traders/1?page=1",
                "last": "http://example.com/api/admin/traders/1?page=1",
                "prev": null,
                "next": null
            },
            "meta": {
                "current_page": 1,
                "from": 1,
                "last_page": 1,
                "path": "http://example.com/api/admin/traders/1",
                "per_page": 10,
                "to": 1,
                "total": 1
            }
        }
    }
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Trader not found",
    "data": null
}
 

Request      

GET api/admin/traders/trader/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the trader. Example: 1

Toggle trader status

requires authentication

Blocks or unblocks a trader account. When blocked, the trader cannot access the system or perform any transactions.

Example request:
curl --request POST \
    "https://sabisave.com/api/admin/traders/1/toggle-block" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"reason\": \"Suspicious activity detected\"
}"
const url = new URL(
    "https://sabisave.com/api/admin/traders/1/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "reason": "Suspicious activity detected"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, Blocked):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Trader blocked successfully",
    "data": {
        "id": 1,
        "first_name": "John",
        "last_name": "Doe",
        "status": {
            "id": 2,
            "name": "inactive"
        },
        "block_reason": "Suspicious activity detected",
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (200, Unblocked):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Trader unblocked successfully",
    "data": {
        "id": 1,
        "first_name": "John",
        "last_name": "Doe",
        "status": {
            "id": 1,
            "name": "active"
        },
        "block_reason": null,
        "updated_at": "2023-01-01T12:00:00.000000Z"
    }
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Trader not found",
    "data": null
}
 

Request      

POST api/admin/traders/{id}/toggle-block

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the trader. Example: 1

Body Parameters

reason   string   

Reason for blocking/unblocking the trader. Example: Suspicious activity detected

Delete trader

requires authentication

Permanently deletes a trader account and all associated data. This action cannot be undone.

Example request:
curl --request DELETE \
    "https://sabisave.com/api/admin/traders/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/traders/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Trader deleted successfully",
    "data": null
}
 

Example response (400):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Cannot delete trader with active balance",
    "data": null
}
 

Example response (404):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Trader not found",
    "data": null
}
 

Request      

DELETE api/admin/traders/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the trader. Example: 1

Trader Transactions

List trader transactions

requires authentication

Retrieves a paginated list of trader transactions with optional filtering by trader ID, date range, transaction type, and status.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/traders/transactions?trader_id=1&start_date=2023-01-01&end_date=2023-12-31&type=deposit&status_id=1&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/traders/transactions"
);

const params = {
    "trader_id": "1",
    "start_date": "2023-01-01",
    "end_date": "2023-12-31",
    "type": "deposit",
    "status_id": "1",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Transactions retrieved successfully",
    "data": {
        "transactions": {
            "current_page": 1,
            "data": [
                {
                    "id": 1,
                    "trader": {
                        "id": 1,
                        "name": "John Doe"
                    },
                    "type": "deposit",
                    "amount": 10000,
                    "status": {
                        "id": 1,
                        "name": "completed"
                    },
                    "created_at": "2023-01-01T12:00:00.000000Z"
                }
            ],
            "first_page_url": "http://example.com/api/admin/traders/transactions?page=1",
            "from": 1,
            "last_page": 5,
            "last_page_url": "http://example.com/api/admin/traders/transactions?page=5",
            "links": [],
            "next_page_url": "http://example.com/api/admin/traders/transactions?page=2",
            "path": "http://example.com/api/admin/traders/transactions",
            "per_page": 10,
            "prev_page_url": null,
            "to": 10,
            "total": 50
        },
        "summary": {
            "total_amount": 500000,
            "total_count": 50
        }
    }
}
 

Example response (500):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Internal server error",
    "data": null
}
 

Request      

GET api/admin/traders/transactions

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

trader_id   integer  optional  

ID of the trader to filter transactions. Example: 1

start_date   string  optional  

date Start date for filtering transactions (YYYY-MM-DD). Example: 2023-01-01

end_date   string  optional  

date End date for filtering transactions (YYYY-MM-DD). Example: 2023-12-31

type   string  optional  

Transaction type (deposit/withdrawal). Example: deposit

status_id   integer  optional  

Status ID for filtering transactions. Example: 1

page   integer  optional  

Page number for pagination. Example: 1

Traders

APIs for Traders

update trader address details

Example request:
curl --request POST \
    "https://sabisave.com/api/address/update" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"country_id\": \"1\",
    \"state_id\": \"1\",
    \"lga_id\": \"1\",
    \"address\": \"\\\"123 Street, City, State\\\"\",
    \"post_code\": \"\\\"100001\\\"\"
}"
const url = new URL(
    "https://sabisave.com/api/address/update"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "country_id": "1",
    "state_id": "1",
    "lga_id": "1",
    "address": "\"123 Street, City, State\"",
    "post_code": "\"100001\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (114):


{
    "message": "address details update failed",
    "details": []
}
 

Example response (200):


{
    "message": "Trader step 2 registration completed",
    "data": {
        "country_id": "1",
        "state_id": "1",
        "lga_id": "1",
        "address": "abuja",
        "post_code": "1234"
    }
}
 

Example response (404):


{
    "message": "not found ",
    "details": []
}
 

Request      

POST api/address/update

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

country_id   numeric   

The ID of the country. Example: 1

state_id   numeric   

The ID of the state. Example: 1

lga_id   numeric   

The ID of the local government area. Example: 1

address   string   

The address of the agent. Example: "123 Street, City, State"

post_code   string   

The postal code of the agent's address. Example: "100001"

Create Trader Step 1.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/register" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"+2348013221673\",
    \"full_name\": \"John Smith\",
    \"other_name\": \"Abraham\",
    \"gender\": \"male\",
    \"dob\": \"2000-01-15\",
    \"has_cooperative\": true,
    \"cooperative\": \"Ikokun Cooperative\",
    \"password\": \"12345678\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/register"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+2348013221673",
    "full_name": "John Smith",
    "other_name": "Abraham",
    "gender": "male",
    "dob": "2000-01-15",
    "has_cooperative": true,
    "cooperative": "Ikokun Cooperative",
    "password": "12345678"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201):


{
    "data": {
        "id": 4,
        "full_name": "John Smith",
        "other_name": "Abraham",
        "phone": "+2348013221673",
        "gender": "male",
        "dob": "2000-01-15",
        "has_cooperative": true,
        "cooperative": "Ikokun Cooperative"
    }
}
 

Example response (422):


{
    "message": "Invalid data sent",
    "details": {
        "email": [
            "The email field is required."
        ],
        "password": [
            "The password must be at least 8 characters."
        ]
    }
}
 

Request      

POST api/traders/register

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The phone number of the user. Example: +2348013221673

full_name   string   

The full name of the user. Example: John Smith

other_name   string  optional  

optional The other name of the user. Example: Abraham

gender   string   

The gender of the user (male or female). Example: male

dob   date   

The date of birth of the user. Example: 2000-01-15

has_cooperative   boolean  optional  

optional Whether the user belongs to a cooperative. Example: true

cooperative   string  optional  

optional The cooperative name (required if has_cooperative is true). Example: Ikokun Cooperative

password   string   

The password of the user. Example: 12345678

Complete trader registration step 2.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/register-step-2" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"trader_id\": \"1\",
    \"country_id\": \"1\",
    \"state_id\": \"1\",
    \"lga_id\": \"1\",
    \"address\": \"\\\"123 Street, City, State\\\"\",
    \"post_code\": \"100001\",
    \"business_type\": \"retail\",
    \"is_registered_with_CAC\": true,
    \"business_name\": \"SABISAVE\",
    \"reg_number\": \"1234567\",
    \"savings_frequency\": \"daily\",
    \"savings_amount\": \"1000\",
    \"account_type\": \"current\",
    \"bank_name\": \"GTB\",
    \"bank_code\": \"\\\"058\\\"\",
    \"account_number\": \"100001300\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/register-step-2"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "trader_id": "1",
    "country_id": "1",
    "state_id": "1",
    "lga_id": "1",
    "address": "\"123 Street, City, State\"",
    "post_code": "100001",
    "business_type": "retail",
    "is_registered_with_CAC": true,
    "business_name": "SABISAVE",
    "reg_number": "1234567",
    "savings_frequency": "daily",
    "savings_amount": "1000",
    "account_type": "current",
    "bank_name": "GTB",
    "bank_code": "\"058\"",
    "account_number": "100001300"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (112):


{
    "message": "unable to register user",
    "details": []
}
 

Example response (200):


{
  "message": "Trader step 2 registration completed",
  "data": {
      "id": 1,
      "cooperative": "user cooperative",
      "email": "[email protected]",
      "password": "12345678",
      "first_name": "John",
      "mid_name":Doe
      "last_name": "mark",
      "phone": "08013221673",
      "gender": "male",
      "dob": "2024-03-09",
      "country_id": "Nigeria",
      "state_id": "Abia State",
      "lga_id": "Ikwuano",
      "address": "5 cape ville",
      "post_code": "10090"
      "frequency": "daily",
      "amount": "1000"
  }
}
 

Example response (403):


{
    "message": "User not verified",
    "details": []
}
 

Example response (404):


{
    "message": "not found ",
    "details": []
}
 

Request      

POST api/traders/register-step-2

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

trader_id   numeric   

The ID of the trader. Example: 1

country_id   numeric   

The ID of the country. Example: 1

state_id   numeric   

The ID of the state. Example: 1

lga_id   numeric   

The ID of the local government area. Example: 1

address   string   

The address of the trader. Example: "123 Street, City, State"

post_code   string   

The postal code of the trader's address. Example: 100001

business_type   string  optional  

type of business being run by trader. Example: retail

is_registered_with_CAC   boolean   

is users business registered with CAC . Example: true

business_name   users  optional  

business name if any. Example: SABISAVE

reg_number   string   

user business reg number. Example: 1234567

savings_frequency   string  optional  

type of frequency of savings plan. Example: daily

savings_amount   string  optional  

amount of savings plan. Example: 1000

account_type   enum   

type of account used by trader. Example: current

bank_name   string  optional  

users bank name. Example: GTB

bank_code   string  optional  

bank code used for creating recipients to enable traders recieve paymnet user. Example: "058"

account_number   string  optional  

account number of user. Example: 100001300

Trader Login.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/login" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"08013221673\",
    \"pin\": \"1234\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/login"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "08013221673",
    "pin": "1234"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "status": 1,
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "refresh_token": "def50200ea86c5d6161c...",
  "expire_at": "29-06-24 14:57:10",
  "token_type": "Bearer",
  "message": "Successfully logged in",
  "trader": {
      "id": 1,
      "name": "John Doe",
      "email": "[email protected]",
      ...
  }
}
 

Example response (422):


{
    "message": "Invalid data sent",
    "details": {
        "phone": [
            "phone field is required."
        ],
        "pin": [
            "The pin must be at least 4 characters."
        ]
    }
}
 

Request      

POST api/traders/login

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The agent number of the agent. Example: 08013221673

pin   string   

The pin of the agent. Minimum and maximum length of 4 characters. Example: 1234

Verify the token for the trader.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/verify-phone" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"+2348012345678\",
    \"token\": \"123456\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/verify-phone"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+2348012345678",
    "token": "123456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Verification successful",
    "data": [],
    "meta-links": []
}
 

Example response (400):


{
    "success": false,
    "message": "Invalid or expired verification code",
    "errors": []
}
 

Example response (404):


{
    "success": false,
    "message": "trader not found",
    "errors": []
}
 

Example response (500):


{
    "success": false,
    "message": "Failed to verify token",
    "errors": []
}
 

Request      

POST api/traders/verify-phone

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The phone number of the trader. Example: +2348012345678

token   string   

The verification token. Example: 123456

Resend the verification token to the trader's phone number.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/resend-verification" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"+2348012345678\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/resend-verification"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+2348012345678"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "success": true,
    "message": "Verification code resent successfully",
    "data": [],
    "meta-links": []
}
 

Example response (404):


{
    "success": false,
    "message": "trader not found",
    "errors": []
}
 

Example response (500):


{
    "success": false,
    "message": "Failed to resend verification code",
    "errors": []
}
 

Request      

POST api/traders/resend-verification

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The phone number of the trader. Example: +2348012345678

Profile image upload.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/upload/id" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "type=passport"\
    --form "trader_id=1"\
    --form "document=@/tmp/phpKwpVIv" 
const url = new URL(
    "https://sabisave.com/api/traders/upload/id"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('type', 'passport');
body.append('trader_id', '1');
body.append('document', document.querySelector('input[name="document"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
  "message": "ID uploaded successfully",

}
 

Example response (500):


{
    "message": "Failed to create ID",
    "error": "Error message"
}
 

Request      

POST api/traders/upload/id

Headers

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

type   string   

The type of ID. Example: passport

document   file   

The file of the ID. Example: /tmp/phpKwpVIv

trader_id   string   

The ID of the trader. Example: 1

Trader pin create.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/create/pin" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"pin\": \"1234\",
    \"pin_confirmation\": \"1234\",
    \"trader_id\": \"consequuntur\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/create/pin"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "pin": "1234",
    "pin_confirmation": "1234",
    "trader_id": "consequuntur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "message": "trader pin created successfully",

}
 

Example response (404):


{
  "message": "trader not found",
  "details": []
}
 @response 500 {
  "message": "internal server error",
  "details": []
}
 

Request      

POST api/traders/create/pin

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

pin   numeric   

.Minimum and maximum length of 4 characters.. Example: 1234

pin_confirmation   same  optional  

with pin . Example: 1234

trader_id   string   

Example: consequuntur

Display the specified resource.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/traders/transactions/totam" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/transactions/totam"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (403):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: http://localhost:3000
access-control-allow-credentials: true
 

{
    "status": false,
    "message": "Unauthorize"
}
 

Request      

GET api/traders/transactions/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the transaction. Example: totam

Trader pin confirmation .

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/confirm/pin" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"pin\": \"1234\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/confirm/pin"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "pin": "1234"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "message": "trader pin confirmed",

}
 

Example response (404):


{
  "message": "trader not found",
  "details": []
}
 @response 500 {
  "message": "internal server error",
  "details": []
}
 

Request      

POST api/traders/confirm/pin

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

pin   numeric  optional  

required. Minimum and maximum length of 4 characters.. Example: 1234

Verify phone number with OTP for PIN change

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/reset-pin/send-otp" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"09031922234\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/reset-pin/send-otp"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "09031922234"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "OTP sent to your phone number",
    "data": {
        "phone": "09031922234"
    }
}
 

Example response (404):


{
    "message": "Trader not found",
    "details": []
}
 

Request      

POST api/traders/reset-pin/send-otp

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The phone number of the trader. Example: 09031922234

Create new PIN after verification

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/reset-pin/create-new-pin" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"09031922234\",
    \"otp\": \"123456\",
    \"pin\": \"1234\",
    \"pin_confirmation\": \"1234\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/reset-pin/create-new-pin"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "09031922234",
    "otp": "123456",
    "pin": "1234",
    "pin_confirmation": "1234"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "PIN changed successfully",
    "data": {
        "success": true
    }
}
 

Example response (404):


{
    "message": "Trader not found",
    "details": []
}
 

Request      

POST api/traders/reset-pin/create-new-pin

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The phone number of the trader. Example: 09031922234

otp   string   

The OTP received on the phone. Example: 123456

pin   numeric   

Minimum and maximum length of 4 characters. Example: 1234

pin_confirmation   same  optional  

with pin. Example: 1234

POST api/traders/bankdetails/update

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/bankdetails/update" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"bank_name\": \"GTB\",
    \"account_type\": \"savings\",
    \"account_number\": \"1234567890\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/bankdetails/update"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "bank_name": "GTB",
    "account_type": "savings",
    "account_number": "1234567890"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (114):


{
    "message": "bank details update failed",
    "details": []
}
 

Example response (200):


{
  "message": "Trader step 2 registration completed",
  "data": {
      "bank_name": "GTB",
      "account_type": "savings",
      "account_number": "1234567890",
      "trader_id": 1,
  }
}
 

Example response (404):


{
    "message": "not found ",
    "details": []
}
 

Request      

POST api/traders/bankdetails/update

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

bank_name   string.  optional  

name of traders bank. Example: GTB

account_type   enum   

Enum('savings','current') ........ Example: savings

account_number   strinng   

The account number of trader. Example: 1234567890

update trader address details

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/address/update" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"country_id\": \"1\",
    \"state_id\": \"1\",
    \"lga_id\": \"1\",
    \"address\": \"\\\"123 Street, City, State\\\"\",
    \"post_code\": \"\\\"100001\\\"\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/address/update"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "country_id": "1",
    "state_id": "1",
    "lga_id": "1",
    "address": "\"123 Street, City, State\"",
    "post_code": "\"100001\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (114):


{
    "message": "address details update failed",
    "details": []
}
 

Example response (200):


{
    "message": "Trader step 2 registration completed",
    "data": {
        "country_id": "1",
        "state_id": "1",
        "lga_id": "1",
        "address": "abuja",
        "post_code": "1234"
    }
}
 

Example response (404):


{
    "message": "not found ",
    "details": []
}
 

Request      

POST api/traders/address/update

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

country_id   numeric   

The ID of the country. Example: 1

state_id   numeric   

The ID of the state. Example: 1

lga_id   numeric   

The ID of the local government area. Example: 1

address   string   

The address of the agent. Example: "123 Street, City, State"

post_code   string   

The postal code of the agent's address. Example: "100001"

Initiate Trader PIN reset by phone number.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/reset-pin/initiate" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"09031922234\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/reset-pin/initiate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "09031922234"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "OTP sent to your phone number",
    "data": {
        "phone": "09031922234"
    }
}
 

Example response (404):


{
    "message": "trader not found",
    "details": []
}
 

Request      

POST api/traders/reset-pin/initiate

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The phone number of the trader. Example: 09031922234

Complete Trader pin reset.

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/reset-pin/complete" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"phone\": \"09031922234\",
    \"otp\": \"123456\",
    \"pin\": \"1234\",
    \"pin_confirmation\": \"1234\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/reset-pin/complete"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "09031922234",
    "otp": "123456",
    "pin": "1234",
    "pin_confirmation": "1234"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (114):


{
    "message": "pin update failed",
    "details": []
}
 

Example response (200):


{
    "message": "PIN changed successfully",
    "data": {
        "success": true
    }
}
 

Example response (404):


{
    "message": "trader not found",
    "details": []
}
 

Example response (500):


{
    "message": "internal server error",
    "details": []
}
 

Request      

POST api/traders/reset-pin/complete

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

phone   string   

The phone number of the trader. Example: 09031922234

otp   string   

The OTP received on the phone. Example: 123456

pin   numeric   

.Minimum and maximum length of 4 characters.. Example: 1234

pin_confirmation   same  optional  

with pin . Example: 1234

Logout trader

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/logout" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/logout"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Successfully logged out",
    "data": {
        "success": true
    }
}
 

Request      

POST api/traders/logout

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Get trader's bank details

Example request:
curl --request GET \
    --get "https://sabisave.com/api/traders/banks" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/banks"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Bank details retrieved successfully",
    "data": [
        {
            "id": 1,
            "bank_name": "GTB",
            "account_type": "savings",
            "account_number": "1234567890",
            "bank_code": "058"
        }
    ]
}
 

Request      

GET api/traders/banks

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Get trader profile

Example request:
curl --request GET \
    --get "https://sabisave.com/api/traders/profile" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/profile"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Profile retrieved successfully",
    "data": {
        "id": 1,
        "full_name": "Ibraheem Razaq",
        "email": "[email protected]",
        "phone": "+2348016067",
        "gender": "Male",
        "dob": "12/08/1990",
        "address": "No 18 Allen Str Ikeja",
        "customer_id": "802430840",
        "trader_level": "Silver Level",
        "account_status": "verified",
        "saving_plan": "Daily Saving Plan",
        "profile_image": "/storage/profile/image.jpg"
    }
}
 

Request      

GET api/traders/profile

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Update trader profile information

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/profile/update" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"address\": \"No 18 Allen Str Ikeja\",
    \"gender\": \"Male\",
    \"email\": \"[email protected]\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/profile/update"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "address": "No 18 Allen Str Ikeja",
    "gender": "Male",
    "email": "[email protected]"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Profile updated successfully",
    "data": {
        "id": 1,
        "full_name": "Ibraheem Razaq",
        "email": "[email protected]",
        "phone": "+2348016067",
        "gender": "Male",
        "dob": "12/08/1990",
        "address": "No 18 Allen Str Ikeja"
    }
}
 

Request      

POST api/traders/profile/update

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

address   string  optional  

The trader's address. Example: No 18 Allen Str Ikeja

gender   string  optional  

The trader's gender. Example: Male

email   string  optional  

The trader's email. Example: [email protected]

Get all bank details for the authenticated trader

Example request:
curl --request GET \
    --get "https://sabisave.com/api/traders/bank-details" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/bank-details"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Bank details retrieved successfully",
    "data": [
        {
            "id": 1,
            "bank_name": "GTB",
            "account_type": "savings",
            "account_number": "1234567890",
            "bank_code": "058"
        }
    ]
}
 

Example response (404):


{
    "message": "No bank details found",
    "details": []
}
 

Request      

GET api/traders/bank-details

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Get list of banks from Paystack

Example request:
curl --request GET \
    --get "https://sabisave.com/api/traders/bank-details/banks-list" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/bank-details/banks-list"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Banks retrieved successfully",
    "data": [
        {
            "id": 1,
            "name": "Access Bank",
            "slug": "access-bank",
            "code": "044",
            "longcode": "044150149",
            "gateway": "emandate",
            "pay_with_bank": true,
            "active": true,
            "country": "Nigeria",
            "currency": "NGN",
            "type": "nuban",
            "is_deleted": false,
            "createdAt": "2016-07-14T10:04:29.000Z",
            "updatedAt": "2020-02-18T08:06:44.000Z"
        }
    ]
}
 

Request      

GET api/traders/bank-details/banks-list

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Verify a bank account

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/bank-details/verify" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"account_number\": \"1234567890\",
    \"bank_code\": \"058\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/bank-details/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "account_number": "1234567890",
    "bank_code": "058"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Account verified successfully",
    "data": {
        "account_number": "1234567890",
        "account_name": "John Doe",
        "bank_id": 1
    }
}
 

Example response (400):


{
    "message": "Could not verify account",
    "details": []
}
 

Request      

POST api/traders/bank-details/verify

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

account_number   string   

The account number. Example: 1234567890

bank_code   string   

The bank code. Example: 058

Get a specific bank detail by ID

Example request:
curl --request GET \
    --get "https://sabisave.com/api/traders/bank-details/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/bank-details/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Bank detail retrieved successfully",
    "data": {
        "id": 1,
        "bank_name": "GTB",
        "account_type": "savings",
        "account_number": "1234567890",
        "bank_code": "058"
    }
}
 

Example response (404):


{
    "message": "Bank detail not found",
    "details": []
}
 

Request      

GET api/traders/bank-details/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the bank detail. Example: 1

Store a new bank detail for the trader

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/bank-details" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"bank_name\": \"GTB\",
    \"account_type\": \"savings\",
    \"account_number\": \"1234567890\",
    \"bank_code\": \"058\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/bank-details"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "bank_name": "GTB",
    "account_type": "savings",
    "account_number": "1234567890",
    "bank_code": "058"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201):


{
    "message": "Bank detail created successfully",
    "data": {
        "id": 1,
        "bank_name": "GTB",
        "account_type": "savings",
        "account_number": "1234567890",
        "bank_code": "058",
        "recipient_code": "RCP_1a2b3c4d5e6f"
    }
}
 

Example response (400):


{
    "message": "Validation error",
    "details": {
        "bank_name": [
            "The bank name field is required."
        ]
    }
}
 

Request      

POST api/traders/bank-details

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

bank_name   string   

The name of the bank. Example: GTB

account_type   string   

The type of account (savings/current). Example: savings

account_number   string   

The account number. Example: 1234567890

bank_code   string   

The bank code. Example: 058

Update a bank detail

Example request:
curl --request PUT \
    "https://sabisave.com/api/traders/bank-details/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"bank_name\": \"GTB\",
    \"account_type\": \"savings\",
    \"account_number\": \"1234567890\",
    \"bank_code\": \"058\"
}"
const url = new URL(
    "https://sabisave.com/api/traders/bank-details/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "bank_name": "GTB",
    "account_type": "savings",
    "account_number": "1234567890",
    "bank_code": "058"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Bank detail updated successfully",
    "data": {
        "id": 1,
        "bank_name": "GTB",
        "account_type": "savings",
        "account_number": "1234567890",
        "bank_code": "058",
        "recipient_code": "RCP_1a2b3c4d5e6f"
    }
}
 

Example response (404):


{
    "message": "Bank detail not found",
    "details": []
}
 

Request      

PUT api/traders/bank-details/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the bank detail. Example: 1

Body Parameters

bank_name   string  optional  

The name of the bank. Example: GTB

account_type   string  optional  

The type of account (savings/current). Example: savings

account_number   string  optional  

The account number. Example: 1234567890

bank_code   string  optional  

The bank code. Example: 058

Delete a bank detail

Example request:
curl --request DELETE \
    "https://sabisave.com/api/traders/bank-details/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/traders/bank-details/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Bank detail deleted successfully"
}
 

Example response (404):


{
    "message": "Bank detail not found",
    "details": []
}
 

Request      

DELETE api/traders/bank-details/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the bank detail. Example: 1

Process a withdrawal request

Example request:
curl --request POST \
    "https://sabisave.com/api/traders/withdraw" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"amount\": \"1000\",
    \"type\": \"cash\",
    \"pin\": \"1234\",
    \"bank_id\": 1
}"
const url = new URL(
    "https://sabisave.com/api/traders/withdraw"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "amount": "1000",
    "type": "cash",
    "pin": "1234",
    "bank_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Withdrawal request processed successfully",
    "data": {
        "success": true
    }
}
 

Example response (400):


{
    "message": "Insufficient funds",
    "details": []
}
 

Example response (401):


{
    "message": "Invalid PIN",
    "details": []
}
 

Example response (404):


{
    "message": "Trader not found",
    "details": []
}
 

Request      

POST api/traders/withdraw

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

amount   numeric   

The amount to withdraw. Example: 1000

type   string   

The type of withdrawal (cash/transfer). Example: cash

pin   string   

The trader's transaction PIN. Example: 1234

bank_id   integer   

The trader's bank details id. Example: 1

Transactions

List all transactions

requires authentication

Retrieves a paginated list of all transactions (both trader and agent) with optional filtering.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/transactions?user_type=trader&user_id=1&start_date=2023-01-01&end_date=2023-12-31&transaction_type=deposit&collection_type=cash&status=1&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/transactions"
);

const params = {
    "user_type": "trader",
    "user_id": "1",
    "start_date": "2023-01-01",
    "end_date": "2023-12-31",
    "transaction_type": "deposit",
    "collection_type": "cash",
    "status": "1",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Transactions retrieved successfully",
    "data": {
        "transactions": {
            "data": [
                {
                    "id": 1,
                    "amount": 10000,
                    "type": "deposit",
                    "ref_id": "TRX123456",
                    "trader_id": 1,
                    "agent_id": 2,
                    "status_id": 1,
                    "status": {
                        "id": 1,
                        "name": "completed"
                    },
                    "recipient": null,
                    "reason": null,
                    "ref_type": "deposit",
                    "created_at": "2023-01-01 12:00:00",
                    "updated_at": "2023-01-01 12:00:00",
                    "trader": {
                        "id": 1,
                        "name": "John Doe"
                    },
                    "agent": {
                        "id": 2,
                        "name": "Jane Smith"
                    }
                }
            ],
            "links": {
                "first": "http://example.com/api/admin/transactions?page=1",
                "last": "http://example.com/api/admin/transactions?page=5",
                "prev": null,
                "next": "http://example.com/api/admin/transactions?page=2"
            },
            "meta": {
                "current_page": 1,
                "from": 1,
                "last_page": 5,
                "path": "http://example.com/api/admin/transactions",
                "per_page": 10,
                "to": 10,
                "total": 50
            }
        }
    }
}
 

Example response (422):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "The user type must be one of the following types: trader, agent",
    "data": null
}
 

Example response (500):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Internal server error",
    "data": null
}
 

Request      

GET api/admin/transactions

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

user_type   string  optional  

Filter by user type (trader, agent, or all). Example: trader

user_id   integer  optional  

Filter by specific user ID. Example: 1

start_date   string  optional  

date Start date for filtering transactions (YYYY-MM-DD). Example: 2023-01-01

end_date   string  optional  

date End date for filtering transactions (YYYY-MM-DD). Example: 2023-12-31

transaction_type   string  optional  

Filter by transaction type (deposit/withdrawal). Example: deposit

collection_type   string  optional  

Filter by collection type. Example: cash

status   integer  optional  

Filter by status ID. Example: 1

page   integer  optional  

Page number for pagination. Example: 1

Get transaction statistics

requires authentication

Retrieves summary statistics for all transactions, including monthly trends and totals.

Example request:
curl --request GET \
    --get "https://sabisave.com/api/admin/transactions/statistics" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://sabisave.com/api/admin/transactions/statistics"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": true,
    "message": "Transaction statistics retrieved successfully",
    "data": {
        "summary": {
            "total_deposits": 500000,
            "total_withdrawals": 200000,
            "net_balance": 300000,
            "trader_count": 50,
            "agent_count": 20,
            "transaction_count": 500
        },
        "monthly_trends": {
            "labels": [
                "Jan",
                "Feb",
                "Mar",
                "Apr",
                "May",
                "Jun",
                "Jul",
                "Aug",
                "Sep",
                "Oct",
                "Nov",
                "Dec"
            ],
            "datasets": [
                {
                    "label": "Trader Deposits",
                    "data": [
                        10000,
                        15000,
                        20000,
                        25000,
                        30000,
                        35000,
                        40000,
                        45000,
                        50000,
                        55000,
                        60000,
                        65000
                    ]
                },
                {
                    "label": "Trader Withdrawals",
                    "data": [
                        5000,
                        7500,
                        10000,
                        12500,
                        15000,
                        17500,
                        20000,
                        22500,
                        25000,
                        27500,
                        30000,
                        32500
                    ]
                },
                {
                    "label": "Agent Deposits",
                    "data": [
                        8000,
                        12000,
                        16000,
                        20000,
                        24000,
                        28000,
                        32000,
                        36000,
                        40000,
                        44000,
                        48000,
                        52000
                    ]
                },
                {
                    "label": "Agent Withdrawals",
                    "data": [
                        4000,
                        6000,
                        8000,
                        10000,
                        12000,
                        14000,
                        16000,
                        18000,
                        20000,
                        22000,
                        24000,
                        26000
                    ]
                }
            ]
        },
        "status_breakdown": {
            "completed": 450,
            "pending": 30,
            "failed": 20
        }
    }
}
 

Example response (500):


{
    "timestamp": "2023-01-01T12:00:00.000000Z",
    "status": false,
    "message": "Internal server error",
    "data": null
}
 

Request      

GET api/admin/transactions/statistics

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Withdrawals

Withdraw funds from trader to agent.

requires authentication

Requires Bearer Token Authentication.

Example request:
curl --request POST \
    "https://sabisave.com/api/withdrawals" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"amount\": \"10000\",
    \"type\": \"\\\"cash\\\"\",
    \"account_number\": \"\\\"8012345678\\\"\",
    \"reason\": \"\\\"Savings withdrawal\\\"\",
    \"pin\": \"\\\"1234\\\"\"
}"
const url = new URL(
    "https://sabisave.com/api/withdrawals"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "amount": "10000",
    "type": "\"cash\"",
    "account_number": "\"8012345678\"",
    "reason": "\"Savings withdrawal\"",
    "pin": "\"1234\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "Withdrawal request is being processed.",
    "data": [],
    "meta-links": []
}
 

Example response (400):


{
    "message": "Insufficient balance in Trader account"
}
 

Example response (400):


{
    "message": "Insufficient balance in Agent account"
}
 

Example response (404):


{
    "message": "Trader or Agent not found"
}
 

Example response (422):


{
    "message": "Validation Error",
    "errors": {
        "amount": [
            "The amount field is required."
        ],
        "type": [
            "The type field is required."
        ]
    }
}
 

Example response (500):


{
    "message": "Internal Server Error"
}
 

Request      

POST api/withdrawals

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

amount   numeric   

Amount to withdraw. Example: 10000

type   string   

Type of withdrawal: "cash" or "bank". Example: "cash"

account_number   string   

Trader's account number. Example: "8012345678"

reason   string   

Reason for withdrawal. Example: "Savings withdrawal"

pin   string   

Trader's transaction PIN if cash and agent's transaction PIN if transfer. Example: "1234"