E-Commerce Search Engine
Base URL: https://api.nextgate.com/api/v1
Short Description: Public search endpoints for discovering shops, products, and active purchase groups on the Nexgate e-commerce platform. These endpoints power the main search functionality, product discovery, and group buying features across the application.
Hints:
- Search query must be at least 2 characters
- Results are ordered alphabetically by name
- Filter by type using the
typeparameter:SHOP,PRODUCT, orPURCHASE_GROUP - Purchase groups are searched by both name and group code (e.g.,
GP-ABC123) - All endpoints are public and do not require authentication
- Maximum page size is 50 results
- Rate limiting applies to prevent abuse
Standard Response Format
All API responses follow a consistent structure using our Globe Response Builder pattern:
Success Response Structure
{
"success": true,
"httpStatus": "OK",
"message": "Operation completed successfully",
"action_time": "2025-12-30T10:30:45",
"data": {
// Actual response data goes here
}
}
Error Response Structure
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Error description",
"action_time": "2025-12-30T10:30:45",
"data": null
}
Search Result Types
Each search result contains a type field indicating the result category:
| Type | Description | Specific Fields |
|---|---|---|
SHOP |
Active shop/store | shop object |
PRODUCT |
Active product | product object |
PURCHASE_GROUP |
Open group purchase | purchaseGroup object |
Endpoints
1. Global Search
Purpose: Search across all types (shops, products, and purchase groups) with optional type filtering
Endpoint: GET {base_url}/api/v1/e-commerce/search
Access Level: 🌐 Public (No Authentication Required)
Query Parameters:
| Parameter | Type | Required | Default | Description | Validation |
|---|---|---|---|---|---|
| query | string | Yes | - | Search term | Min 2 characters |
| type | string | No | null (all) | Filter by type | SHOP, PRODUCT, PURCHASE_GROUP |
| page | int | No | 1 | Page number | Min 1 |
| size | int | No | 20 | Results per page | Max 50 |
Request Examples:
# Search all types
GET /api/v1/e-commerce/search?query=iphone&page=1&size=20
# Search shops only
GET /api/v1/e-commerce/search?query=fashion&type=SHOP
# Search products only
GET /api/v1/e-commerce/search?query=dress&type=PRODUCT
# Search purchase groups only
GET /api/v1/e-commerce/search?query=GP-ABC123&type=PURCHASE_GROUP
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Search results retrieved successfully",
"action_time": "2025-12-30T10:30:45",
"data": {
"content": [
{
"type": "SHOP",
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Fashion Hub TZ",
"imageUrl": "https://storage.example.com/shops/logo1.jpg",
"shop": {
"slug": "fashion-hub-tz",
"isVerified": true,
"rating": 4.8,
"productsCount": 156,
"location": "Dar es Salaam"
}
},
{
"type": "PRODUCT",
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Summer Fashion Dress",
"imageUrl": "https://storage.example.com/products/dress1.jpg",
"product": {
"slug": "summer-fashion-dress",
"price": 45000.00,
"discountPrice": 38000.00,
"currency": "TZS",
"inStock": true,
"rating": 4.5,
"shopName": "Fashion Hub TZ",
"shopIsVerified": true
}
},
{
"type": "PURCHASE_GROUP",
"id": "770e8400-e29b-41d4-a716-446655440002",
"name": "Fashion Week Special Deal",
"imageUrl": "https://storage.example.com/products/bundle.jpg",
"purchaseGroup": {
"groupCode": "GP-FWS123",
"regularPrice": 150000.00,
"groupPrice": 120000.00,
"savingsPercentage": 20,
"seatsRemaining": 3,
"totalSeats": 10,
"expiresAt": "2025-12-31T23:59:59",
"shopName": "Fashion Hub TZ"
}
}
],
"page": 0,
"size": 20,
"totalElements": 3,
"totalPages": 1,
"hasNext": false,
"hasPrevious": false,
"shopsCount": 1,
"productsCount": 1,
"purchaseGroupsCount": 1
}
}
Response Fields:
| Field | Type | Description |
|---|---|---|
| content | array | List of search result items |
| page | int | Current page number (0-indexed) |
| size | int | Page size |
| totalElements | long | Total number of results |
| totalPages | int | Total number of pages |
| hasNext | boolean | Whether more pages exist |
| hasPrevious | boolean | Whether previous pages exist |
| shopsCount | long | Total shops matching query |
| productsCount | long | Total products matching query |
| purchaseGroupsCount | long | Total purchase groups matching query |
Error Response JSON Samples:
Query too short:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Search query must be at least 2 characters",
"action_time": "2025-12-30T10:30:45",
"data": null
}
Invalid type:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Invalid type. Must be: SHOP, PRODUCT, or PURCHASE_GROUP",
"action_time": "2025-12-30T10:30:45",
"data": null
}
2. Search Shops
Purpose: Search for active shops by name
Endpoint: GET {base_url}/api/v1/e-commerce/search/shops
Access Level: 🌐 Public (No Authentication Required)
Query Parameters:
| Parameter | Type | Required | Default | Description | Validation |
|---|---|---|---|---|---|
| query | string | Yes | - | Shop name search term | Min 2 characters |
| page | int | No | 1 | Page number | Min 1 |
| size | int | No | 20 | Results per page | Max 50 |
Request Example:
GET /api/v1/e-commerce/search/shops?query=fashion&page=1&size=20
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Shops retrieved successfully",
"action_time": "2025-12-30T10:30:45",
"data": {
"content": [
{
"type": "SHOP",
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Fashion Hub TZ",
"imageUrl": "https://storage.example.com/shops/logo1.jpg",
"shop": {
"slug": "fashion-hub-tz",
"isVerified": true,
"rating": 4.8,
"productsCount": 156,
"location": "Dar es Salaam"
}
},
{
"type": "SHOP",
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Fashion Zone",
"imageUrl": "https://storage.example.com/shops/logo2.jpg",
"shop": {
"slug": "fashion-zone",
"isVerified": false,
"rating": 4.2,
"productsCount": 89,
"location": "Arusha"
}
}
],
"page": 0,
"size": 20,
"totalElements": 2,
"totalPages": 1,
"hasNext": false,
"hasPrevious": false,
"shopsCount": 2,
"productsCount": 0,
"purchaseGroupsCount": 0
}
}
Shop Info Fields:
| Field | Type | Description |
|---|---|---|
| slug | string | URL-friendly shop identifier |
| isVerified | boolean | Whether shop is verified |
| rating | double | Shop rating (0-5) |
| productsCount | int | Number of active products |
| location | string | Shop location |
3. Search Products
Purpose: Search for active products by name
Endpoint: GET {base_url}/api/v1/e-commerce/search/products
Access Level: 🌐 Public (No Authentication Required)
Query Parameters:
| Parameter | Type | Required | Default | Description | Validation |
|---|---|---|---|---|---|
| query | string | Yes | - | Product name search term | Min 2 characters |
| page | int | No | 1 | Page number | Min 1 |
| size | int | No | 20 | Results per page | Max 50 |
Request Example:
GET /api/v1/e-commerce/search/products?query=dress&page=1&size=20
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Products retrieved successfully",
"action_time": "2025-12-30T10:30:45",
"data": {
"content": [
{
"type": "PRODUCT",
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Summer Dress Collection",
"imageUrl": "https://storage.example.com/products/dress1.jpg",
"product": {
"slug": "summer-dress-collection",
"price": 45000.00,
"discountPrice": 38000.00,
"currency": "TZS",
"inStock": true,
"rating": 4.5,
"shopName": "Fashion Hub TZ",
"shopIsVerified": true
}
},
{
"type": "PRODUCT",
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Evening Dress",
"imageUrl": "https://storage.example.com/products/dress2.jpg",
"product": {
"slug": "evening-dress",
"price": 85000.00,
"discountPrice": null,
"currency": "TZS",
"inStock": true,
"rating": 4.8,
"shopName": "Elegance Store",
"shopIsVerified": true
}
},
{
"type": "PRODUCT",
"id": "770e8400-e29b-41d4-a716-446655440002",
"name": "Casual Dress",
"imageUrl": "https://storage.example.com/products/dress3.jpg",
"product": {
"slug": "casual-dress",
"price": 35000.00,
"discountPrice": 30000.00,
"currency": "TZS",
"inStock": false,
"rating": 4.0,
"shopName": "Budget Fashion",
"shopIsVerified": false
}
}
],
"page": 0,
"size": 20,
"totalElements": 3,
"totalPages": 1,
"hasNext": false,
"hasPrevious": false,
"shopsCount": 0,
"productsCount": 3,
"purchaseGroupsCount": 0
}
}
Product Info Fields:
| Field | Type | Description |
|---|---|---|
| slug | string | URL-friendly product identifier |
| price | decimal | Regular price |
| discountPrice | decimal | Discounted price (null if no discount) |
| currency | string | Price currency (e.g., TZS) |
| inStock | boolean | Whether product is in stock |
| rating | double | Product rating (0-5) |
| shopName | string | Name of the shop selling this product |
| shopIsVerified | boolean | Whether the shop is verified |
4. Search Purchase Groups
Purpose: Search for active (open, non-expired) purchase groups by name or group code
Endpoint: GET {base_url}/api/v1/e-commerce/search/groups
Access Level: 🌐 Public (No Authentication Required)
Query Parameters:
| Parameter | Type | Required | Default | Description | Validation |
|---|---|---|---|---|---|
| query | string | Yes | - | Group name or code | Min 2 characters |
| page | int | No | 1 | Page number | Min 1 |
| size | int | No | 20 | Results per page | Max 50 |
Request Examples:
# Search by group name
GET /api/v1/e-commerce/search/groups?query=iPhone Deal&page=1&size=20
# Search by group code
GET /api/v1/e-commerce/search/groups?query=GP-ABC123&page=1&size=20
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Purchase groups retrieved successfully",
"action_time": "2025-12-30T10:30:45",
"data": {
"content": [
{
"type": "PURCHASE_GROUP",
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "iPhone 15 Pro - Dar es Salaam Deal",
"imageUrl": "https://storage.example.com/products/iphone15.jpg",
"purchaseGroup": {
"groupCode": "GP-ABC123",
"regularPrice": 2500000.00,
"groupPrice": 2200000.00,
"savingsPercentage": 12,
"seatsRemaining": 2,
"totalSeats": 5,
"expiresAt": "2025-12-31T08:00:00",
"shopName": "TechZone TZ"
}
},
{
"type": "PURCHASE_GROUP",
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "iPhone 15 Plus Group Buy",
"imageUrl": "https://storage.example.com/products/iphone15plus.jpg",
"purchaseGroup": {
"groupCode": "GP-XYZ789",
"regularPrice": 2200000.00,
"groupPrice": 1950000.00,
"savingsPercentage": 11,
"seatsRemaining": 4,
"totalSeats": 8,
"expiresAt": "2025-12-30T18:00:00",
"shopName": "Mobile World"
}
}
],
"page": 0,
"size": 20,
"totalElements": 2,
"totalPages": 1,
"hasNext": false,
"hasPrevious": false,
"shopsCount": 0,
"productsCount": 0,
"purchaseGroupsCount": 2
}
}
Purchase Group Info Fields:
| Field | Type | Description |
|---|---|---|
| groupCode | string | Unique group code (e.g., GP-ABC123) |
| regularPrice | decimal | Original product price |
| groupPrice | decimal | Discounted group price |
| savingsPercentage | int | Percentage saved |
| seatsRemaining | int | Available seats |
| totalSeats | int | Total seats in group |
| expiresAt | datetime | Group expiration time |
| shopName | string | Name of the shop |
Note: Only returns groups that are:
- Status:
OPEN - Not expired (
expiresAt> now) - Not deleted
Endpoints Summary
| # | Method | Endpoint | Purpose |
|---|---|---|---|
| 1 | GET | /api/v1/e-commerce/search |
Search all types |
| 2 | GET | /api/v1/e-commerce/search/shops |
Search shops only |
| 3 | GET | /api/v1/e-commerce/search/products |
Search products only |
| 4 | GET | /api/v1/e-commerce/search/groups |
Search purchase groups only |
Common Error Responses
| Status | Message | Cause |
|---|---|---|
400 BAD_REQUEST |
Search query must be at least 2 characters | Query too short |
400 BAD_REQUEST |
Invalid type. Must be: SHOP, PRODUCT, or PURCHASE_GROUP | Invalid type parameter |
429 TOO_MANY_REQUESTS |
Rate limit exceeded | Too many requests |
Frontend Usage Examples
JavaScript/TypeScript
// Global search
const searchAll = async (query, page = 1, size = 20) => {
const response = await fetch(
`/api/v1/e-commerce/search?query=${encodeURIComponent(query)}&page=${page}&size=${size}`
);
return response.json();
};
// Search with type filter
const searchByType = async (query, type, page = 1) => {
const response = await fetch(
`/api/v1/e-commerce/search?query=${encodeURIComponent(query)}&type=${type}&page=${page}`
);
return response.json();
};
// Search shops only
const searchShops = async (query) => {
const response = await fetch(
`/api/v1/e-commerce/search/shops?query=${encodeURIComponent(query)}`
);
return response.json();
};
// Search products only
const searchProducts = async (query) => {
const response = await fetch(
`/api/v1/e-commerce/search/products?query=${encodeURIComponent(query)}`
);
return response.json();
};
// Search groups by name or code
const searchGroups = async (query) => {
const response = await fetch(
`/api/v1/e-commerce/search/groups?query=${encodeURIComponent(query)}`
);
return response.json();
};
Rendering Results
const renderResults = (results) => {
results.content.forEach(item => {
switch (item.type) {
case 'SHOP':
renderShopCard(item);
break;
case 'PRODUCT':
renderProductCard(item);
break;
case 'PURCHASE_GROUP':
renderGroupCard(item);
break;
}
});
// Show counts
console.log(`Found: ${results.shopsCount} shops, ${results.productsCount} products, ${results.purchaseGroupsCount} groups`);
};