API Reference
Every REST endpoint the CargoPRO backend serves at
/api β the same API the customer and driver apps are built on.
Overview
| Convention | Value |
| Base URL | https://your-domain.com/api (paths below are relative to it) |
| Authentication | Laravel Sanctum personal access tokens, sent as Authorization: Bearer <token> |
| Content type | application/json (also send Accept: application/json) |
| Response envelope | { "success": bool, "message": string, "data": ... } |
| Validation errors | HTTP 422 with { "success": false, "message": ..., "errors": {...} } |
| Unauthenticated | HTTP 401 with { "message": "Unauthenticated." } |
| Pagination | List endpoints accept page / per_page (the apps request 20 per page, max 100) |
| Method | Endpoint | Purpose |
| GET | /health | Health check (status, timestamp, version) |
| GET | /version | API, Laravel and PHP version info |
| GET | /avatar/{filename} | Serve a user avatar image (public) |
Where the apps point
The customer app sets ApiConstants.baseUrl in
cargoproapp/lib/constants/api_constants.dart; the driver app
sets ApiConfig.baseUrl in
cargoprodriver/lib/core/api_config.dart (overridable with
--dart-define=CARGOPRO_API_BASE=...). Both must end in
/api.
Authentication flow
Protected routes sit behind the auth:sanctum middleware.
POST /auth/login issues a Sanctum personal access token
(token_type: "Bearer"); the login, register and password
endpoints are rate-limited by the throttle:login middleware.
When a token is missing, expired or revoked the API returns
401 Unauthenticated. β the apps then clear the stored token
and return to the login screen.
sequenceDiagram
autonumber
participant A as Mobile app
participant S as CargoPRO API
A->>S: POST /api/auth/login (username or email + password)
S-->>A: 200 success, data.token (Bearer)
A->>S: GET /api/packages/customer with Authorization Bearer token
S-->>A: 200 success with data rows
Note over A,S: Token expired, revoked or missing
A->>S: GET /api/notifications with Authorization Bearer token
S-->>A: 401 Unauthenticated.
A->>A: Discard stored token and show login screen
Example requests
# 1) Login - username OR email, plus password (min 6 chars)
curl -X POST https://your-domain.com/api/auth/login \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"username": "demo@devtrixx.com", "password": "secret123"}'
# Response (trimmed)
{
"success": true,
"message": "Login successful",
"data": {
"token": "1|9abcdefghijKLMNopqrsTUVwxyZ",
"token_type": "Bearer"
}
}
# 2) Any authenticated call - send the token as a Bearer header
curl https://your-domain.com/api/packages/customer \
-H "Accept: application/json" \
-H "Authorization: Bearer 1|9abcdefghijKLMNopqrsTUVwxyZ"
{
"success": true,
"message": "Packages retrieved successfully",
"data": [ ... ]
}
401 vs 403
401 means the token is bad or missing (re-login).
403 means the account is fine but inactive, or the role
lacks the permission: / role: middleware the
route demands β check the account in the admin panel.
Authentication & profile
| Method | Endpoint | Purpose |
| POST | /auth/login | Login with username or email; returns the Sanctum Bearer token (throttled) |
| POST | /auth/register | Register an account (driver accounts are created inactive for approval) |
| POST | /auth/forgot-password | Request a password reset link |
| POST | /auth/reset-password | Reset the password with the emailed token |
| POST | /auth/verify-email | Verify the email address |
| Method | Endpoint | Purpose |
| POST | /auth/logout | Revoke the current token |
| GET | /auth/user | Current account with roles and permission names |
| GET | /auth/profile | Current profile (driver app also gets delivery statistics) |
| PUT | /auth/profile | Update the profile (name, phone, etc.) |
| POST | /auth/profile/avatar | Upload or replace the avatar (multipart) |
| DELETE | /auth/account | Delete the signed-in account (requires password) |
| POST | /auth/refresh | Refresh the current token |
| POST | /auth/change-password | Change the account password |
| POST | /auth/resend-verification | Resend the email verification message |
| GET | /auth/permissions | Flat list of the account's permission names |
| GET | /auth/roles | Roles of the signed-in account |
| Method | Endpoint | Purpose |
| GET | /users/profile | Profile of the signed-in customer |
| PUT | /users/profile | Update the customer profile |
| POST | /users/profile/avatar | Update the profile picture (multipart) |
| GET | /users/profile/addresses | List saved addresses |
| POST | /users/profile/addresses | Create an address |
| PUT | /users/profile/addresses/{id} | Update an address |
| DELETE | /users/profile/addresses/{id} | Delete an address |
| GET | /users/profile/order-history | Past orders of the signed-in customer |
| GET | /users/profile/countries | Countries for address forms |
| GET | /users/profile/countries/{id}/states | States of a country |
| GET | /users/profile/states/{id}/cities | Cities of a state |
Packages
| Method | Endpoint | Purpose |
| GET | /packages/customer | List the signed-in customer's packages |
| POST | /packages/customer | Create a package for the signed-in customer |
| GET | /packages/customer/{id} | Package detail |
| GET | /packages/customer/{id}/lifecycle | Package lifecycle / status history |
| GET | /packages/customer/{id}/invoice | Fetch the package invoice |
| POST | /packages/customer/{id}/invoice | Upload a customer invoice for the package |
| POST | /packages/customer/{id}/self-pickup | Book warehouse self-pickup for the package |
| GET | /packages/customer/warehouses | Warehouse options for the package form |
| GET | /packages/customer/statuses | Package status options |
| GET | /packages/customer/senders | Search sender customers (staff) |
| GET | /packages/customer/sender-addresses | Saved sender addresses for the form |
| POST | /packages/customer/{id}/assign-warehouse | Assign the package to a warehouse (staff) |
| POST | /packages/customer/bulk-action | Bulk status action (staff) |
| POST | /packages/customer/bulk-warehouse | Bulk warehouse move (staff) |
| POST | /packages/customer/{id}/payment-verify | Verify package payment (staff, permission-gated) |
| PUT | /packages/customer/{id} | Update a package (staff) |
| DELETE | /packages/customer/{id} | Delete a package (staff) |
| Method | Endpoint | Purpose |
| GET | /packages/locker | List the customer's virtual-locker packages |
| POST | /packages/locker | Create a locker package |
| GET | /packages/locker/{id} | Locker package detail |
| PUT | /packages/locker/{id} | Update a locker package |
| DELETE | /packages/locker/{id} | Delete a locker package |
| GET | /packages/locker/warehouses | Warehouse options for locker packages |
| POST | /packages/locker/{id}/assign-warehouse | Assign a locker package to a warehouse (staff) |
| Method | Endpoint | Purpose |
| GET | /packages/track/{tracking_number} | Public tracking lookup (no auth; also used by the driver app for unknown labels) |
| POST | /packages/upload-invoice | Upload a package invoice file |
| GET | /packages/statuses | Package status catalogue (pending, processing, in transit, ...) |
Shipments
| Method | Endpoint | Purpose |
| GET | /shipments | List shipments β customers and drivers only see their own rows; drivers also get stats |
| POST | /shipments | Create a shipment (permission courier.create) |
| GET | /shipments/{id} | Shipment detail: line items, charges, tracking, sender and recipient |
| PUT | /shipments/{id} | Update a shipment (staff) |
| DELETE | /shipments/{id} | Delete a shipment (staff) |
| POST | /shipments/{id}/complete | Mark a shipment completed (staff) |
| POST | /shipments/{id}/cancel | Cancel a shipment (staff) |
| GET | /shipments/{id}/invoice | Fetch the shipment invoice |
| POST | /shipments/{id}/invoice | Upload a customer invoice for the shipment |
| POST | /shipments/{id}/self-pickup | Book warehouse self-pickup for the shipment |
| GET | /shipments/{id}/label | Fetch the shipping label |
| POST | /shipments/{id}/deliver | Close a delivery with proof β signature, photos, collected amount (driver app) |
| POST | /shipments/{id}/exception | Report a failed delivery attempt with reason and photos (driver app) |
| POST | /shipments/{id}/assign-driver | Assign a driver (staff) |
| POST | /shipments/{id}/update-status | Update the shipment status (staff) |
| Method | Endpoint | Purpose |
| GET | /tracking/types | Tracking event types |
| GET | /tracking/{id}/history | Tracking events for an order (used by both apps) |
| POST | /tracking/{id}/update | Add a tracking update (staff) |
| GET | /courier/recipients | Search recipients for shipment creation |
| POST | /courier/recipients | Create a recipient |
| GET | /courier/recipient-addresses | Saved recipient addresses |
| POST | /courier/recipient-addresses | Create a recipient address |
Pickups
| Method | Endpoint | Purpose |
| GET | /pickups | List pickup jobs β drivers only see their own |
| POST | /pickups | Schedule a pickup |
| GET | /pickups/{id} | Pickup detail |
| PUT | /pickups/{id} | Update a pickup |
| DELETE | /pickups/{id} | Cancel / delete a pickup |
| GET | /pickups/drivers | Driver options for the pickup form (staff) |
| POST | /pickups/{id}/assign-driver | Assign a driver to the pickup (staff) |
Driver tip
Pickups are closed out through POST /shipments/{id}/deliver β
the same endpoint as shipments; the backend checks the
pickups.deliver permission when the row is a pickup.
Pre-alerts
| Method | Endpoint | Purpose |
| GET | /pre-alerts | List pre-alerts |
| POST | /pre-alerts | Create a pre-alert |
| GET | /pre-alerts/recent | Most recent pre-alerts |
| GET | /pre-alerts/couriers | Courier options for the pre-alert form |
| GET | /pre-alerts/{id} | Pre-alert detail |
| PUT | /pre-alerts/{id} | Update a pre-alert |
| DELETE | /pre-alerts/{id} | Delete a pre-alert |
| GET | /pre-alerts/{id}/invoice | Fetch the pre-alert invoice file |
| POST | /pre-alerts/{id}/invoice | Upload the pre-alert invoice (multipart) |
Notifications
| Method | Endpoint | Purpose |
| GET | /notifications | List notifications for the signed-in account |
| GET | /notifications/recent | Most recent notifications |
| GET | /notifications/unread-count | Unread notification count (badge) |
| GET | /notifications/stats | Notification statistics |
| POST | /notifications/{id}/read | Mark one notification as read |
| POST | /notifications/mark-all-read | Mark every notification as read |
| DELETE | /notifications/{id} | Delete a notification |
| POST | /notifications/device-token | Register this device's FCM push token (alias of POST /device-tokens) |
| POST | /notifications/device-token/remove | Remove this device's push token at sign-out (alias of DELETE /device-tokens) |
Device tokens (push)
| Method | Endpoint | Purpose |
| GET | /device-tokens | List the account's registered devices |
| POST | /device-tokens | Register an FCM token for the signed-in account |
| DELETE | /device-tokens | Delete the account's device tokens |
| POST | /device-tokens/sync | Sync a batch of device tokens |
| POST | /device-tokens/last-used | Update a token's last-used timestamp |
| POST | /device-tokens/{id}/deactivate | Deactivate one device token |
Transactions & invoices
| Method | Endpoint | Purpose |
| GET | /transactions | List transactions (staff, permission transactions.view) |
| GET | /transactions/summary | Transaction totals summary (staff) |
| GET | /transactions/{id} | Transaction detail (staff) |
| POST | /transactions/{id}/refund | Refund a transaction (permission payments.process) |
| GET | /invoices | List invoices β customers only see their own |
| GET | /invoices/{id} | Invoice detail |
| POST | /invoices/{id}/send | Email an invoice to the customer |
| GET | /invoices/{id}/pdf | Download the invoice PDF |
Payments
| Method | Endpoint | Purpose |
| POST | /payments/stripe | Process a Stripe payment (permission payments.process) |
| POST | /payments/paypal | Process a PayPal payment |
| POST | /payments/paystack | Process a Paystack payment |
| GET | /payments/gateways/active | Active payment gateways for checkout |
| GET | /payments/methods | List payment methods |
| GET | /payments/methods/active | Active payment methods |
| GET | /payments/methods/by-type/{type} | Payment methods filtered by type |
| GET | /payments/modes | List payment modes |
| GET | /payments/modes/active | Active payment modes |
Gateway management is separate
The CRUD routes under /payments/gateways (except
/active) expose secret keys and are locked to staff with the
tools.payment-gateways.manage permission.
Catalog & location data
| Method | Endpoint | Purpose |
| GET | /catalog/categories | Package categories |
| GET | /catalog/delivery-times | Delivery time options |
| GET | /catalog/packaging | Packaging options |
| GET | /catalog/incoterms | Incoterm options |
| GET | /catalog/styles | Shipment status catalogue (id, label, colour) |
| GET | /catalog/agencies | Agencies |
| GET | /catalog/couriers | Couriers |
| GET | /catalog/service-options | Shipping service options |
| GET | /catalog/payment-methods | Payment methods for checkout |
| GET | /catalog/offices | Offices |
| GET | /catalog/statuses | Shipment statuses |
| GET | /catalog/drivers | Driver options |
Mirrored dropdown data
The same dropdown lists are also served under
/courier/statuses,
/courier/drivers,
/courier/agencies,
/courier/offices,
/courier/warehouses,
/courier/packaging,
/courier/categories,
/courier/couriers,
/courier/shipping-modes and
/courier/delivery-times β the driver app uses
/courier/statuses. Country / state / city cascades for
address forms live under
/users/profile/countries (see
Authentication & profile).
Dashboard, files & driver documents
| Method | Endpoint | Purpose |
| GET | /dashboard/stats | Dashboard statistics (company revenue hidden from customers) |
| GET | /dashboard/recent-activities | Recent activity feed |
| GET | /dashboard/charts/revenue | Revenue chart data |
| GET | /dashboard/charts/packages | Package chart data |
| GET | /dashboard/charts/shipments | Shipment chart data |
| POST | /files/upload | Upload a generic file |
| GET | /files/{id} | File metadata |
| GET | /files/{id}/download | Download a file |
| DELETE | /files/{id} | Delete a file |
| GET | /driver/documents | The signed-in driver's requested documents |
| POST | /driver/documents/{docId} | Upload or replace one requested document (multipart) |
Staff-only groups (not shown above)
routes/api.php also defines permission-gated management
APIs used by the admin panel itself: /users/customers,
/users/drivers, /users/management,
/lockers provisioning, /consolidations,
/templates, /newsletter, /reports,
/analytics, /google and everything under
/admin/* (settings, locations, offices, catalog, shipping
lines/tariffs, backups). They follow the same envelope and auth rules.