Bosta
Overview
The Bosta Core API mirrors Bosta's own shipping REST API 1:1 — deliveries, pickups, shipping analytics, and support tickets. Every endpoint below has been live-verified against a real connected Bosta account.
| Base path | /api/core/bosta |
| Auth | the calling organization's own connected Bosta API key (raw Authorization: <apiKey> header — Bosta does not use the Bearer scheme). You never pass this key yourself; Core API resolves it from the organization's stored integration |
| Every request | requires ?organizationId=<uuid> on GET routes, or an organizationId alongside the body on write routes |
API Endpoints
| Endpoint | Bosta Real Endpoint | Description |
|---|---|---|
GET /cities | GET /cities | List all Bosta-covered cities |
GET /pickups | GET /pickups | List scheduled pickups |
POST /pickups | POST /pickups | Schedule a new pickup |
GET /pickups/available-dates | GET /pickups/available-dates | Valid dates for a new pickup |
GET /analytics/live | GET /deliveries/analytics/total-deliveries | Live delivery-state counts |
GET /analytics/success-rate | GET /analytics/delivery-success-rate | Success / return / lost breakdown |
GET /analytics/geographical | GET /analytics/geographical-analysis | Per-city order breakdown |
GET /analytics/cash-cycles | GET /analytics/cash-cycles | Weekly COD cash collected + Bosta fees |
GET /analytics/attempt | GET /analytics/delivery-attempt-analysis | Deliveries by attempt count |
POST /deliveries/search | POST /deliveries/search | Search / list deliveries |
POST /deliveries/count | POST /deliveries/count | Count deliveries matching a filter |
GET /deliveries/{trackingNumber} | GET /deliveries/business/{trackingNumber} | Get one delivery |
POST /deliveries | POST /deliveries | Create a delivery |
DELETE /deliveries/{trackingNumber} | DELETE /deliveries/{id} | Terminate a delivery |
GET /tickets | GET /tickets/business | List support tickets |
POST /tickets | POST /tickets/business | Create a support ticket |
GET /tickets/{ticketId}/conversations | GET /tickets/business/{id}/conversations | Get a ticket's message thread |
Cities
GET /api/core/bosta/cities
GET /api/core/bosta/citiesReference list of every city Bosta covers, with hub and pickup/drop-off availability.
curl "https://analify.scalyax.ai/api/core/bosta/cities?organizationId={organizationId}" \
-H "Authorization: Bearer {anlfy_token}"{
"success": true,
"data": {
"success": true,
"data": {
"list": [
{
"_id": "FceDyHXwpSYYF9zGW",
"name": "Cairo",
"nameAr": "القاهره",
"code": "EG-01",
"sector": 1,
"pickupAvailability": true,
"dropOffAvailability": true
}
]
}
},
"timestamp": "2026-08-16T17:45:23.503Z"
}Pickups
GET /api/core/bosta/pickups
GET /api/core/bosta/pickupsParams: page (required by Bosta), limit, state (REQUESTED/CANCELLED/SUCCESS/FAILED), dateFrom, dateTo.
curl "https://analify.scalyax.ai/api/core/bosta/pickups?organizationId={organizationId}&page=1&limit=5" \
-H "Authorization: Bearer {anlfy_token}"{
"success": true,
"data": {
"success": true,
"data": {
"total": 49,
"list": [
{
"_id": "070004534160",
"type": "Business Pickup",
"scheduledDate": "04-22-2026, 20:45:58",
"scheduledTimeSlot": "10:00 to 13:00",
"business": { "name": "JokeyJoy Games" }
}
]
}
},
"timestamp": "2026-08-16T17:46:31.089Z"
}POST /api/core/bosta/pickups
POST /api/core/bosta/pickupsBody: exactly Bosta's own — scheduledDate (from available-dates), scheduledTimeSlot ("10:00 to 13:00" or "13:00 to 16:00"), contactPerson: { phone, name? }, businessLocationId?, notes?.
curl -X POST "https://analify.scalyax.ai/api/core/bosta/pickups?organizationId={organizationId}" \
-H "Authorization: Bearer {anlfy_token}" -H "Content-Type: application/json" \
-d '{
"scheduledDate": "2026-08-20",
"scheduledTimeSlot": "10:00 to 13:00",
"contactPerson": { "phone": "+201030258087", "name": "Adham Mahmoud" }
}'
This creates a real pickup request — a courier will be dispatched. There is no cancel-pickup endpoint; cancel from the Bosta dashboard.
GET /api/core/bosta/pickups/available-dates
GET /api/core/bosta/pickups/available-datesParams: days (required by Bosta — omitting it returns days is required).
curl "https://analify.scalyax.ai/api/core/bosta/pickups/available-dates?organizationId={organizationId}&days=7" \
-H "Authorization: Bearer {anlfy_token}"{
"success": true,
"data": {
"success": true,
"data": ["2026-08-17", "2026-08-18", "2026-08-19", "2026-08-20", "2026-08-22"]
},
"timestamp": "2026-08-16T17:46:43.225Z"
}Analytics
All 5 analytics endpoints take date_from and date_to (YYYY-MM-DD).
GET /api/core/bosta/analytics/live
GET /api/core/bosta/analytics/livecurl "https://analify.scalyax.ai/api/core/bosta/analytics/live?organizationId={organizationId}&date_from=2026-07-01&date_to=2026-08-16" \
-H "Authorization: Bearer {anlfy_token}"{
"success": true,
"data": {
"success": true,
"data": {
"pickedUp": 16,
"completed": 5,
"inTransit": 3,
"outForDelivery": 1,
"receivedAtWarehouse": 22,
"successfulOrders": 2,
"unsuccessfulOrders": 7181
}
},
"timestamp": "2026-08-16T17:46:55.308Z"
}GET /api/core/bosta/analytics/success-rate
GET /api/core/bosta/analytics/success-rate{
"success": true,
"data": {
"success": true,
"message": "Done Successfully.",
"data": {
"deliveriesTotalReport": {
"totalSuccessfulOrders": 427,
"returns": 66,
"unsuccessfulOrders": 68,
"lostAndDamaged": 2,
"cancelled": 0
},
"completedFiveOrders": true
}
},
"timestamp": "2026-08-16T17:47:01.089Z"
}GET /api/core/bosta/analytics/geographical
GET /api/core/bosta/analytics/geographicalParams: also accepts Bosta's filterBy — this Core API route pins it to cities.
{
"success": true,
"data": {
"success": true,
"data": {
"cities": [
{ "_id": "FceDyHXwpSYYF9zGW", "name": "Cairo", "totalOrders": 280, "successfulOrders": 244, "unsuccessfulOrders": 36 }
]
}
},
"timestamp": "2026-08-16T17:47:06.724Z"
}GET /api/core/bosta/analytics/cash-cycles
GET /api/core/bosta/analytics/cash-cycles{
"success": true,
"data": {
"success": true,
"data": {
"cashCycles": [
{ "label": "Aug 06 - Aug 11", "cashCollected": 45352.6, "bostaFees": 10126.62 },
{ "label": "Aug 12 - Aug 16", "cashCollected": 25721.4, "bostaFees": 6623.4 }
]
}
},
"timestamp": "2026-08-16T17:47:16.573Z"
}GET /api/core/bosta/analytics/attempt
GET /api/core/bosta/analytics/attempt{
"success": true,
"data": {
"success": true,
"data": {
"deliveriesCountPerAttempt": { "1": 390, "2": 23, "3": 14 }
}
},
"timestamp": "2026-08-16T17:47:21.833Z"
}Deliveries
POST /api/core/bosta/deliveries/search
POST /api/core/bosta/deliveries/searchBody: exactly Bosta's own — common fields: page, limit, sortBy, dateRangeStates, dateRangeStart, dateRangeEnd, search.
curl -X POST "https://analify.scalyax.ai/api/core/bosta/deliveries/search?organizationId={organizationId}" \
-H "Authorization: Bearer {anlfy_token}" -H "Content-Type: application/json" \
-d '{"limit": 3}'{
"success": true,
"data": {
"success": true,
"data": {
"deliveries": [
{
"trackingNumber": "4402102836",
"type": { "code": 10, "value": "Send" },
"state": { "value": "Processing", "code": 24 },
"cod": 624,
"receiver": { "fullName": "Retaj Mansor", "phone": "+201064983945" }
}
],
"count": 0,
"page": 1,
"limit": 3
}
},
"timestamp": "2026-08-16T20:58:48.424Z"
}POST /api/core/bosta/deliveries/count
POST /api/core/bosta/deliveries/count{
"success": true,
"data": { "success": true, "data": { "count": 40477 } },
"timestamp": "2026-08-16T20:58:56.592Z"
}GET /api/core/bosta/deliveries/{trackingNumber}
GET /api/core/bosta/deliveries/{trackingNumber}curl "https://analify.scalyax.ai/api/core/bosta/deliveries/2237746870?organizationId={organizationId}" \
-H "Authorization: Bearer {anlfy_token}"Returns the full raw Bosta delivery object (pickupAddress, dropOffAddress, state, sender, receiver, sla, ...). A tracking number the org doesn't own returns Bosta's own error:
{
"success": false,
"error": {
"message": "Bosta API error (400): Delivery not found.",
"code": "BOSTA_API_ERROR",
"details": { "errorCode": 1066 }
}
}POST /api/core/bosta/deliveries
POST /api/core/bosta/deliveriesBody: exactly Bosta's own. type (10=Send, 15=Cash Collection, 25=Customer Return Pickup, 30=Exchange), specs.size (SMALL / MEDIUM / LARGE — Bosta's real enum; do not use Normal/Light Bulky/Heavy Bulky, those are documented in some client tooling but rejected by the live API), receiver: { firstName, phone }, dropOffAddress (either { city, districtId, firstLine } or { city, cityId, districtName, firstLine } — firstLine must be > 5 characters).
curl -X POST "https://analify.scalyax.ai/api/core/bosta/deliveries?organizationId={organizationId}" \
-H "Authorization: Bearer {anlfy_token}" -H "Content-Type: application/json" \
-d '{
"type": 10,
"specs": { "size": "SMALL" },
"receiver": { "firstName": "Test Receiver", "phone": "+201000000000" },
"dropOffAddress": { "city": "Cairo", "districtId": "JSfFhvnU8iC", "firstLine": "Test address line" }
}'{
"success": true,
"data": {
"success": true,
"message": "Delivery created successfully!",
"data": {
"trackingNumber": "9532176487",
"state": { "code": 10, "value": "Pickup requested" }
}
},
"timestamp": "2026-08-16T21:00:45.556Z"
}DELETE /api/core/bosta/deliveries/{trackingNumber}
DELETE /api/core/bosta/deliveries/{trackingNumber}curl -X DELETE "https://analify.scalyax.ai/api/core/bosta/deliveries/9532176487?organizationId={organizationId}" \
-H "Authorization: Bearer {anlfy_token}"{
"success": true,
"data": { "success": true, "data": { "_id": "9532176487" } },
"timestamp": "2026-08-16T21:00:50.956Z"
}Tickets
Bosta's support-ticket system (backed by Freshdesk). Useful for surfacing or filing delivery/customer complaints programmatically.
GET /api/core/bosta/tickets
GET /api/core/bosta/ticketsParams: page, limit, status (Open, etc.), category (Delivery Issue, Star Behavior, etc.), search — search also doubles as the working single-ticket lookup (see note below).
curl "https://analify.scalyax.ai/api/core/bosta/tickets?organizationId={organizationId}&page=1&limit=4&status=Open&category=Delivery+Issue" \
-H "Authorization: Bearer {anlfy_token}"{
"success": true,
"data": {
"success": true,
"data": {
"list": [
{
"_id": "YRUbJvkNlAbOYP4jTEam6",
"reason": "Losted order / 2772805142",
"status": "Open",
"category": "Delivery Issue",
"trackingNumber": "2772805142",
"externalId": "7233354"
}
],
"total": 682,
"page": 1,
"limit": 4,
"pages": 171
}
},
"timestamp": "2026-08-16T21:06:11.292Z"
}Bosta's GET /tickets/business/{id} does not work as a single-ticket lookup — verified live against multiple real tickets (including a freshly-created one), by both Bosta's Mongo _id and Freshdesk externalId. It always returns Ticket is not found for this business. The working substitute is GET /tickets/business?search=<query>&limit=1.
POST /api/core/bosta/tickets
POST /api/core/bosta/ticketsBody: required category, reason, description. Optional trackingNumber — links the ticket to a specific order (Bosta appends it to the description and stores it as its own field).
curl -X POST "https://analify.scalyax.ai/api/core/bosta/tickets?organizationId={organizationId}" \
-H "Authorization: Bearer {anlfy_token}" -H "Content-Type: application/json" \
-d '{
"category": "Delivery Issue",
"reason": "Lost order",
"description": "Order never arrived, customer reporting missing package.",
"trackingNumber": "2237746870"
}'{
"success": true,
"data": {
"success": true,
"message": "Done successfully.",
"data": {
"_id": "xmILcbWzJHH6KhKLe4a7N",
"externalId": "7358337",
"status": "Open",
"category": "Delivery Issue",
"trackingNumber": "2237746870"
}
},
"timestamp": "2026-08-16T21:10:07.001Z"
}Bosta appears to deduplicate tickets by category + trackingNumber within a time window — a second create with the same tracking number and category can return the existing open ticket instead of a new one.
GET /api/core/bosta/tickets/{ticketId}/conversations
GET /api/core/bosta/tickets/{ticketId}/conversationsParams: page.
curl "https://analify.scalyax.ai/api/core/bosta/tickets/YRUbJvkNlAbOYP4jTEam6/conversations?organizationId={organizationId}&page=1" \
-H "Authorization: Bearer {anlfy_token}"Returns the full message thread for the ticket (list[], each with body HTML, sender, timestamps) — sourced from Freshdesk under the hood.
Error Shape
Every failure returns Bosta's real error message and code, wrapped in Analify's envelope — nothing is translated or generalized:
{
"success": false,
"error": {
"message": "Bosta API error (400): reason is required",
"code": "BOSTA_API_ERROR",
"details": { "errorCode": 777 }
}
}Updated about 2 months ago
