Net Manager API nm.apnanetwork.net/backend/api/v1
GET · docs / overview

API Overview

RESTful API for the Net Manager ISP customer portal.

45
Endpoints
9
Categories
JWT
Auth
v1.0
Version

Response format

Every response follows a consistent envelope:

{
  "success": true,
  "data": { ... },
  "message": "Success message",
  "timestamp": "2026-08-03T10:30:00Z"
}

Authentication

Most endpoints require a bearer token: Authorization: Bearer {access_token}

Sandbox

Base URL: nm.apnanetwork.net/backend/api/v1/sandbox
Test credentials — Customer ID: TEST001, Password: test1234

Conventions for the backend team

Verbs

GET read · POST create/action · PUT full replace · PATCH partial update · DELETE remove. Every path below is relative to the base URL.

Live network data lives under /mikrotik-api

Anything read live from the router (status, traffic, speedtest, diagnostics) is prefixed /mikrotik-api — matching the confirmed sample /mikrotik-api/status. Stored/portal data (billing, tickets, shop, profile) uses its own resource prefix.

Prayer times are external — do not build

The app fetches prayer timings straight from api.aladhan.com. No backend endpoint is required. Proxy it only if you want to hide it behind your own domain.

docs / authentication

Authentication

User authentication and session management.

POST /auth/login User Login

Request Body

{
  "customer_id": "CK2206",
  "password": "user_password"
}

Parameters

ParameterTypeRequiredDescription
customer_idstringRequiredUnique customer identifier
passwordstringRequiredUser password

Success Response (200)

{
  "success": true,
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "user": {
      "id": "user_uuid",
      "customer_id": "CK2206",
      "name": "Arif Hossain",
      "email": "arif@example.com",
      "mobile": "01712345678"
    }
  },
  "message": "Login successful"
}

Error Codes

INVALID_CREDENTIALSWrong customer ID or password
ACCOUNT_SUSPENDEDAccount is suspended
ACCOUNT_LOCKEDToo many failed login attempts
POST /auth/logout User Logout

Authentication required

Requires a valid bearer token in the Authorization header.

{
  "success": true,
  "message": "Logged out successfully"
}
POST /auth/refresh Refresh Access Token

Get a new access token using the refresh token when the current one expires.

Request Body

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response (200)

{
        "success": true,
        "data": {
          "access_token": "eyJhbGci...",
          "token_type": "Bearer",
          "expires_in": 3600
        },
        "message": "Token refreshed"
      }
POST /auth/forgot-password Request Password Reset

Request a password reset via SMS to the registered mobile number.

{
  "customer_id": "CK2206"
}

Response (200)

{
        "success": true,
        "message": "Password sent by SMS to your registered mobile number"
      }
POST /auth/change-password Change Password

Password requirements

At least 8 characters · one uppercase letter · one number

{
  "current_password": "old_password",
  "new_password": "new_password",
  "confirm_password": "new_password"
}

Response (200)

{
        "success": true,
        "message": "Password changed successfully"
      }
POST /auth/register Sign Up

Create an account. Backs the sign-up mode on the login screen.

Request Body

{
  "customer_id": "CK2206",
  "mobile": "01712345678",
  "password": "user_password"
}

Note

Customer ID is issued by the ISP at installation; sign-up links an app login to an existing subscriber, it does not create a new subscriber.

Response (200)

{
        "success": true,
        "message": "Account created. You can now sign in."
      }
DELETE /auth/sessions/{session_id} Revoke Session

Sign out a specific device/session. Use current as the id to revoke the calling session (logout).

{
  "success": true,
  "message": "Session revoked"
}
docs / network

Network & Connection

Real-time network status, speed tests, and diagnostics.

GET /mikrotik-api/status Get Connection Status

Real-time data

Returns current connection status including speeds, session info, and usage.

{
  "success": true,
  "data": {
    "status": "online",
    "package": {
      "name": "Premium 50 Mbps",
      "speed": "50 Mbps",
      "price": 800
    },
    "connection": {
      "download_speed": 48.6,
      "upload_speed": 49.1,
      "ping": 12,
      "packet_loss": 0.2
    },
    "session": {
      "public_ip": "103.245.123.45",
      "uptime": "2d 14h 23m"
    }
  }
}
GET /mikrotik-api/traffic/live Live Traffic Sample

Polled ~1×/sec by the app

The home hero and Realtime Traffic screen redraw the download/upload graph continuously. Return the current instantaneous throughput; the client keeps its own rolling 30-sample window. A WebSocket push at /mikrotik-api/traffic/stream is preferred if feasible — it removes the polling load.

Success Response (200)

{
  "success": true,
  "data": {
    "timestamp": "2026-08-03T10:30:12Z",
    "download_mbps": 42.7,
    "upload_mbps": 8.3
  }
}
POST /mikrotik-api/speedtest Run Speed Test

Initiate a speed test. Use the returned test_id to fetch results.

{
  "success": true,
  "data": {
    "test_id": "test_uuid",
    "status": "initiated",
    "estimated_duration": 15
  }
}
POST /mikrotik-api/diagnostics Run Network Diagnostics

Run comprehensive network diagnostic tests (7 checks).

Diagnostic tests include

Router reachability · ISP gateway · DNS resolution · Internet connectivity · Bandwidth test · Packet loss · Network stability

Response (200)

{
        "success": true,
        "data": {
          "overall": "healthy",
          "checks": [
            {
              "name": "Router reachability",
              "status": "pass"
            },
            {
              "name": "ISP gateway",
              "status": "pass"
            },
            {
              "name": "DNS resolution",
              "status": "pass"
            },
            {
              "name": "Internet connectivity",
              "status": "pass"
            },
            {
              "name": "Bandwidth test",
              "status": "pass"
            },
            {
              "name": "Packet loss",
              "status": "warn",
              "detail": "0.2%"
            },
            {
              "name": "Network stability",
              "status": "pass"
            }
          ]
        }
      }
GET /network/usage/monthly Get Monthly Usage

Get monthly data usage statistics with download/upload breakdown.

{
  "success": true,
  "data": {
    "month": "2026-08",
    "download": {
      "amount": 1200,
      "unit": "GB",
      "percentage": 62
    },
    "upload": {
      "amount": 320,
      "unit": "GB",
      "percentage": 28
    }
  }
}
docs / billing

Billing & Payments

Invoice management, payments, and package handling.

GET /billing/invoices Get Invoices List

Query Parameters

ParameterTypeRequiredDescription
statusstringOptionalFilter: all, paid, pending, overdue
pagenumberOptionalPage number (default: 1)
limitnumberOptionalItems per page (default: 20)

Response (200)

{
        "success": true,
        "data": {
          "invoices": [
            {
              "invoice_id": "inv_uuid_1",
              "month": "June 2026",
              "amount": 800,
              "status": "overdue",
              "due_date": "2026-06-30"
            },
            {
              "invoice_id": "inv_uuid_2",
              "month": "May 2026",
              "amount": 800,
              "status": "paid",
              "paid_at": "2026-05-28"
            }
          ],
          "pagination": {
            "page": 1,
            "limit": 20,
            "total": 14
          }
        }
      }
POST /billing/payments/initiate Initiate Payment

Initiate payment for one or multiple invoices.

Request Body

{
  "invoice_ids": ["inv_uuid_1", "inv_uuid_2"],
  "payment_method": "bkash",
  "return_url": "https://app.example.com/payment/callback"
}

Supported Payment Methods

bkash · nagad · rocket · card · bank_transfer

Response (200)

{
        "success": true,
        "data": {
          "payment_id": "pay_uuid",
          "gateway_url": "https://bkash.example/checkout/pay_uuid",
          "status": "pending",
          "amount": 1600
        },
        "message": "Redirect the user to gateway_url"
      }
GET /billing/packages List Available Packages

All plans the customer can switch to. Powers the Packages / Upgrade screen.

{
  "success": true,
  "data": [
    {
      "package_id": "pkg_uuid_3",
      "name": "Premium 100 Mbps",
      "speed": "100 Mbps",
      "price": 1500,
      "is_current": false,
      "features": ["BDIX", "OTT", "Free installation"]
    }
  ]
}
GET /billing/package/current Get Current Package

Get the user's currently active internet package details.

{
  "success": true,
  "data": {
    "package_id": "pkg_uuid",
    "name": "Premium 50 Mbps",
    "speed": "50 Mbps",
    "price": 800,
    "status": "active",
    "expiry_date": "2026-08-15",
    "days_remaining": 12
  }
}
POST /billing/package/change Request Package Change

Request to upgrade or change the internet package.

{
  "new_package_id": "pkg_uuid_3",
  "effective_date": "immediate"
}

Response (200)

{
        "success": true,
        "data": {
          "request_id": "req_uuid",
          "new_package_id": "pkg_uuid_3",
          "effective_date": "immediate",
          "status": "pending_approval"
        },
        "message": "Package change requested"
      }
docs / support

Support & Tickets

Customer support ticket system and FAQs.

GET /support/categories Get Ticket Categories

Get the list of support ticket categories with priority and resolution times.

Available categories

No Internet · Billing Issue · Package Change · Relocation · Router Problem · Fiber Problem · Device Issue · Other

Response (200)

{
        "success": true,
        "data": [
          {
            "category_id": "cat_no_internet",
            "name": "No Internet",
            "priority": "High",
            "est_resolution_hours": 4
          },
          {
            "category_id": "cat_billing",
            "name": "Billing Issue",
            "priority": "Medium",
            "est_resolution_hours": 24
          },
          {
            "category_id": "cat_router",
            "name": "Router Problem",
            "priority": "Medium",
            "est_resolution_hours": 12
          }
        ]
      }
POST /support/tickets Create Support Ticket

File upload

Content-Type must be multipart/form-data when attaching files.

Form Data

FieldTypeRequiredDescription
category_idstringRequiredTicket category ID
titlestringRequiredBrief title
descriptionstringRequiredDetailed description
attachmentfileOptionalImage attachment (max 10MB)

Response (200)

{
        "success": true,
        "data": {
          "ticket_id": "tkt_uuid",
          "number": "TKT-2606-118",
          "status": "open",
          "created_at": "2026-06-22T09:12:00Z"
        },
        "message": "Ticket created"
      }
GET /support/tickets/{ticket_id} Get Ticket Detail

Get detailed ticket information including full chat history.

Includes

Ticket details · status and priority · complete chat history · assigned engineer info · attachments

Response (200)

{
        "success": true,
        "data": {
          "ticket_id": "tkt_uuid",
          "number": "TKT-2606-118",
          "category": "Slow Internet",
          "status": "in_progress",
          "priority": "High",
          "created_at": "2026-06-22T09:12:00Z",
          "engineer": {
            "name": "Rakib Hasan",
            "phone": "01700000000"
          },
          "messages": [
            {
              "from": "customer",
              "text": "My internet has been very slow since this morning.",
              "at": "11:58 AM"
            },
            {
              "from": "engineer",
              "text": "Checking the OLT port for your zone now.",
              "at": "12:04 PM"
            }
          ]
        }
      }
POST /support/tickets/{ticket_id}/messages Reply to Ticket

Post a message into the ticket chat thread. multipart/form-data when attaching a file.

{
  "message": "Still no internet after restarting the router.",
  "attachment": "(optional file)"
}

Response (200)

{
        "success": true,
        "data": {
          "message_id": "msg_uuid",
          "from": "customer",
          "text": "Still no internet after restarting the router.",
          "at": "12:10 PM"
        }
      }
PATCH /support/tickets/{ticket_id} Update Ticket Status

Close or reopen a ticket from the customer side.

{
  "status": "closed"
}

Values

open · closed. Reopening a resolved ticket may be restricted server-side — return TICKET_ALREADY_CLOSED if not allowed.

Response (200)

{
        "success": true,
        "data": {
          "ticket_id": "tkt_uuid",
          "status": "closed"
        },
        "message": "Ticket closed"
      }
docs / shop

Shop & Orders

E-commerce for routers, cables, and accessories.

GET /shop/products Get Products List

Get the list of available products with filtering options.

GET /shop/products?category=router&page=1&limit=20

Response (200)

{
        "success": true,
        "data": [
          {
            "product_id": "router",
            "name": "Dual-band Wi-Fi 6 Router",
            "category": "Wi-Fi router",
            "price": 4990,
            "image_url": "https://nm.apnanetwork.net/media/shop/router.jpeg",
            "features": [
              "Wi-Fi 6",
              "Dual-band",
              "1 year warranty"
            ],
            "in_stock": true
          },
          {
            "product_id": "mesh",
            "name": "Mesh Wi-Fi Extender",
            "category": "Coverage",
            "price": 2490,
            "in_stock": true
          },
          {
            "product_id": "cable",
            "name": "CAT6 Ethernet Cable",
            "category": "Accessories",
            "price": 390,
            "in_stock": true
          }
        ]
      }
POST /shop/orders Create Order

Request Body

{
  "items": [
    {
      "product_id": "prod_uuid_1",
      "quantity": 1
    }
  ],
  "delivery_details": {
    "full_name": "Arif Hossain",
    "phone": "01712345678",
    "address": "House 23, Road 7, Banani"
  },
  "payment_method": "cod",
  "promo_code": "NET10"
}

Response (200)

{
        "success": true,
        "data": {
          "order_id": "NM-004821",
          "status": "pending",
          "subtotal": 4990,
          "discount": 499,
          "total": 4491,
          "payment_method": "cod",
          "estimated_delivery": "2026-08-06"
        },
        "message": "Order placed"
      }
POST /shop/promo/validate Validate Promo Code

Validate a promo code and calculate the discount.

{
  "promo_code": "NET10",
  "subtotal": 3100
}

Response (200)

{
        "success": true,
        "data": {
          "promo_code": "NET10",
          "valid": true,
          "discount_type": "percentage",
          "discount_value": 10,
          "discount_amount": 310,
          "subtotal": 3100,
          "total": 2790
        }
      }
GET /shop/orders Get Order History

Customer's past orders with status. Query: status (all, pending, shipped, delivered, cancelled).

{
  "success": true,
  "data": [
    {
      "order_id": "NM-004821",
      "status": "shipped",
      "total": 4990,
      "placed_at": "2026-07-28T09:12:00Z"
    }
  ]
}
DELETE /shop/orders/{order_id} Cancel Order

Cancel an order that has not yet shipped.

{
  "success": true,
  "message": "Order cancelled"
}

Guard

Return ORDER_CANNOT_BE_CANCELLED if the order is already shipped or delivered.

docs / user

User Management

User profile and photo management.

GET /user/profile Get User Profile

Get the current user's profile information.

{
  "success": true,
  "data": {
    "id": "user_uuid",
    "customer_id": "CK2206",
    "name": "Arif Hossain",
    "email": "arif@example.com",
    "mobile": "01712345678",
    "address": "House 23, Road 7, Banani",
    "zone": "Banani",
    "joining_date": "2024-01-15"
  }
}
PUT /user/profile Update Profile

Update user profile information.

{
  "name": "Arif Hossain",
  "email": "newemail@example.com",
  "mobile": "01712345678",
  "address": "New Address"
}

Response (200)

{
        "success": true,
        "data": {
          "id": "user_uuid",
          "customer_id": "CK2206",
          "name": "Arif Hossain",
          "email": "newemail@example.com",
          "mobile": "01712345678",
          "address": "New Address"
        },
        "message": "Profile updated"
      }
POST /user/profile/photo Upload Profile Photo

Requirements

Content-Type: multipart/form-data · max file size 5MB · JPG or PNG

Response (200)

{
        "success": true,
        "data": {
          "photo_url": "https://nm.apnanetwork.net/media/profile/user_uuid.jpg"
        },
        "message": "Photo updated"
      }
docs / notifications

Notifications

Push notifications and announcements.

GET /notifications Get Notifications

Query Parameters

ParameterDescription
typeFilter: all, billing, package, maintenance, promotion
unread_onlyShow only unread notifications (true/false)

Response (200)

{
        "success": true,
        "data": {
          "notifications": [
            {
              "id": "ntf_uuid",
              "type": "billing",
              "title": "Invoice due",
              "body": "Your June invoice of ৳800 is due on 30 Jun.",
              "read": false,
              "created_at": "2026-06-25T08:00:00Z"
            }
          ],
          "unread_count": 3
        }
      }
PUT /notifications/read-all Mark All as Read

Mark all notifications as read for the current user.

Response (200)

{
        "success": true,
        "message": "All notifications marked read"
      }
PATCH /notifications/{notification_id} Mark One as Read

Mark a single notification read when the user opens it.

{
  "read": true
}

Response (200)

{
        "success": true,
        "data": {
          "id": "ntf_uuid",
          "read": true
        }
      }
DELETE /notifications/{notification_id} Delete Notification

Remove a notification from the user's list (swipe-to-dismiss).

{
  "success": true,
  "message": "Notification deleted"
}
GET /announcements Get Announcements

Get system-wide announcements like maintenance notices and promotions.

Response (200)

{
        "success": true,
        "data": [
          {
            "id": "anc_uuid",
            "type": "maintenance",
            "title": "Scheduled maintenance",
            "body": "Banani zone · 2:00–4:00 AM, 24 Jun",
            "date": "2026-06-20"
          },
          {
            "id": "anc_uuid2",
            "type": "promotion",
            "title": "Eid promotional offer",
            "body": "Faster BDIX & OTT for ৳1500/mo",
            "date": "2026-06-18"
          }
        ]
      }
docs / media

Media Content

Movies, TV series, and tutorials.

GET /media/movies/categories Get Movie Categories

Get the list of movie categories (Action, Drama, Bangla Cinema, etc.).

Response (200)

{
        "success": true,
        "data": [
          {
            "category_id": "cat_action",
            "name": "Action",
            "count": 24
          },
          {
            "category_id": "cat_drama",
            "name": "Drama",
            "count": 31
          },
          {
            "category_id": "cat_bangla",
            "name": "Bangla Cinema",
            "count": 18
          }
        ]
      }
GET /media/movies/categories/{category_id} Get Movies by Category

Get movies in a specific category with pagination.

Response (200)

{
        "success": true,
        "data": {
          "movies": [
            {
              "movie_id": "mov_uuid",
              "title": "Mission Strike",
              "year": 2024,
              "duration": "2h 14m",
              "rating": 8.1,
              "genre": "Action",
              "quality": "HD",
              "poster_url": "https://nm.apnanetwork.net/media/movies/mov_uuid.jpg"
            }
          ],
          "pagination": {
            "page": 1,
            "limit": 20,
            "total": 24
          }
        }
      }
GET /media/movies/{movie_id} Get Movie Detail

Get detailed movie information including cast, synopsis, and stream URL.

BDIX cache server

Movies are cached on local BDIX servers for faster streaming within Bangladesh.

Response (200)

{
        "success": true,
        "data": {
          "movie_id": "mov_uuid",
          "title": "Mission Strike",
          "year": 2024,
          "duration": "2h 14m",
          "rating": 8.1,
          "genre": "Action",
          "quality": "HD",
          "synopsis": "A rogue agent races against time to stop a bioweapon from reaching the capital.",
          "cast": [
            "Actor One",
            "Actor Two"
          ],
          "stream_url": "https://bdix.apnanetwork.net/stream/mov_uuid.m3u8"
        }
      }
GET /media/tv-series Get TV Series

Get the list of TV series with seasons and episodes.

Response (200)

{
        "success": true,
        "data": [
          {
            "series_id": "srs_uuid",
            "title": "Capital Lines",
            "seasons": 8,
            "genres": [
              "Drama",
              "Thriller"
            ],
            "poster_url": "https://nm.apnanetwork.net/media/tv/srs_uuid.jpg"
          }
        ]
      }
GET /media/tutorials Get Tutorials

Get setup guides and tutorial videos (router setup, Wi-Fi optimization, etc.).

Response (200)

{
        "success": true,
        "data": [
          {
            "tutorial_id": "tut_uuid",
            "title": "Improve Wi-Fi coverage",
            "duration": "4 min",
            "level": "Beginner",
            "video_url": "https://nm.apnanetwork.net/media/tutorials/tut_uuid.mp4"
          }
        ]
      }
docs / settings

Settings & Preferences

User settings, rewards, and referrals.

GET /settings Get User Settings

Get the user's app settings including notifications, appearance, and prayer times.

{
  "success": true,
  "data": {
    "notifications": {
      "push_enabled": true,
      "billing_alerts": true
    },
    "appearance": {
      "language": "en",
      "dark_mode": false,
      "primary_color": "#862BAE"
    }
  }
}
PATCH /settings Update Settings

Persist a settings change. Send only the keys that changed — language toggle, dark mode, notification switches, or the brand colour picker.

{
  "appearance": {
    "language": "bn",
    "primary_color": "#862BAE"
  },
  "notifications": {
    "billing_alerts": false
  }
}

Response (200)

{
        "success": true,
        "data": {
          "appearance": {
            "language": "bn",
            "primary_color": "#862BAE"
          },
          "notifications": {
            "billing_alerts": false
          }
        },
        "message": "Settings updated"
      }
GET /rewards Get Reward Balance

Current points balance and whether today's spin is still available. Read on app open to render the daily-reward card.

{
  "success": true,
  "data": {
    "points_balance": 240,
    "spin_available": true,
    "last_spin_date": "2026-08-02"
  }
}
GET /referrals Get Referral Info

Get the user's referral code, stats, and earnings.

Referral program

Earn ৳200 for each successful referral when they activate a monthly package.

Response (200)

{
        "success": true,
        "data": {
          "referral_code": "ARIF200",
          "successful_referrals": 3,
          "credit_earned": 600,
          "reward_per_referral": 200,
          "currency": "BDT"
        }
      }
POST /rewards/daily/spin Spin Daily Reward

Spin the daily reward wheel to earn points (once per day).

Response (200)

{
        "success": true,
        "data": {
          "points_earned": 20,
          "points_balance": 260,
          "next_spin_available": "2026-08-04T00:00:00Z"
        },
        "message": "Reward added"
      }
tools / health-check

API Health Check

Probe every read-only endpoint in one click. Fires GET requests only — never POST, PUT, PATCH, or DELETE — so it is safe to run against live.

docs / errors

Error Codes Reference

Complete list of API error codes and their meanings.

Authentication Errors
INVALID_CREDENTIALSWrong customer ID or password
ACCOUNT_SUSPENDEDAccount is suspended
ACCOUNT_LOCKEDToo many failed login attempts
TOKEN_EXPIREDAccess token has expired, use refresh token
TOKEN_INVALIDInvalid or malformed token
UNAUTHORIZEDAuthentication required
Validation Errors
VALIDATION_ERRORRequest validation failed
MISSING_REQUIRED_FIELDRequired field missing from request
INVALID_FORMATInvalid data format
INVALID_VALUEInvalid field value
Payment Errors
PAYMENT_FAILEDPayment transaction failed
INSUFFICIENT_BALANCEInsufficient wallet balance
PAYMENT_GATEWAY_ERRORPayment gateway error
INVALID_PAYMENT_METHODPayment method not supported
Business Logic Errors
INVOICE_ALREADY_PAIDInvoice has already been paid
PROMO_CODE_INVALIDInvalid or expired promo code
ORDER_CANNOT_BE_CANCELLEDOrder is already shipped or delivered
TICKET_ALREADY_CLOSEDSupport ticket is already closed
System Errors
INTERNAL_SERVER_ERRORInternal server error (500)
SERVICE_UNAVAILABLEService temporarily unavailable (503)
RATE_LIMIT_EXCEEDEDToo many requests, slow down
NOT_FOUNDResource not found (404)

Error Response Format

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {}
  },
  "timestamp": "2026-08-03T10:30:00Z"
}