Documentation Index
Fetch the complete documentation index at: https://docs.jethings.com/llms.txt
Use this file to discover all available pages before exploring further.
Customer API
The Customer API provides endpoints for retrieving paginated lists of customers linked to stores that the authenticated user has access to.
All Customer API endpoints require authentication and a valid x-store-id header to identify the store context.
Overview
Customers can be:
- Linked to a store (created automatically when a store is created)
- Linked to a user account (created when a user signs up)
- Created manually with a local name and optional default price list
- Assigned or updated with a default price list
- Filtered and sorted by various criteria
- Retrieved in paginated lists
- Bulk deleted from a store (remove multiple customer-store relations)
Endpoint Details
Base URL: /customers
Content-Type: application/json
Authorization: Bearer <token>
x-store-id: <store_id>
All routes require a valid x-store-id header. Users must have an active relation with the store to access its customers.
Get Customers
GET /customers
Retrieve a paginated list of customers linked to a store that the authenticated user has access to.
Requires Authentication: Bearer token in Authorization header
| Key | Value | Required | Description |
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Query Parameters
| Parameter | Type | Required | Description | Default |
search | string | No | Filter customers by name (partial match) | — |
name | string | No | Filter customers by exact or partial name | — |
isActive | boolean | No | Filter by active/inactive status | — |
page | number | No | Page number (1-based) | 1 |
limit | number | No | Number of items per page (1–100) | 10 |
sortBy | string | No | Sort field (name, isActive, updatedAt, createdAt) | createdAt |
sortOrder | string | No | Sort direction (asc or desc) | desc |
Success Response
Status Code: 200 OK
{
"data": [
{
"id": "cst_12345",
"name": "Abdellah Chehri",
"userId": "usr_789",
"isActive": true,
"createdAt": "2025-11-03T10:00:00.000Z",
"updatedAt": "2025-11-03T10:30:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 12,
"totalPages": 2,
"hasNext": true,
"hasPrev": false
}
}
Response Fields
Customer Object
| Field | Type | Description |
id | string | Unique customer ID |
name | string | Customer display name |
localName | string? | Local name of the customer (if set) |
defaultPriceListId | string? | Default price list ID (if assigned) |
userId | string? | Related user ID (if created by user) |
isActive | boolean | Active status of customer |
createdAt | string | Creation timestamp (ISO 8601) |
updatedAt | string | Last update timestamp (ISO 8601) |
| Field | Type | Description |
page | number | Current page number |
limit | number | Number of items per page |
total | number | Total number of records |
totalPages | number | Total pages available |
hasNext | boolean | Whether a next page exists |
hasPrev | boolean | Whether a previous page exists |
Possible Errors
| Code | Message |
| 400 | Bad Request - Invalid query params or validation errors |
| 403 | Forbidden - User does not have access to this store |
| 500 | Internal Server Error - Failed to fetch customers |
Example Requests
Get all customers with default pagination:
curl -X GET "https://jethings-backend.fly.dev/customers" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here"
Search customers by name:
curl -X GET "https://jethings-backend.fly.dev/customers?search=john&page=1&limit=10&sortBy=name&sortOrder=asc" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here"
Filter by active status:
curl -X GET "https://jethings-backend.fly.dev/customers?isActive=true&page=1&limit=20" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here"
Filter by exact name:
curl -X GET "https://jethings-backend.fly.dev/customers?name=John%20Doe" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here"
Create Customer
POST /customers
Create a new customer and link them to the current store. You can optionally assign a default price list.
Requires Authentication: Bearer token in Authorization header
| Key | Value | Required | Description |
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Request Body
{
"localName": "Ali's Boutique",
"defaultPriceListId": "pl_abc123"
}
Request Body Fields
| Field | Type | Required | Description |
localName | string | Yes | The local name of the customer |
defaultPriceListId | string (UUID) | No | Optional price list ID to assign |
Success Response
Status Code: 200 OK
{
"customer": {
"id": "cst_abc123",
"localName": "Ali's Boutique",
"defaultPriceListId": "pl_abc123",
"isActive": true,
"createdAt": "2025-11-03T10:00:00.000Z",
"updatedAt": "2025-11-03T10:00:00.000Z"
},
"customerStore": {
"id": "csr_987",
"customerId": "cst_abc123",
"storeId": "str_12345",
"createdAt": "2025-11-03T10:00:00.000Z"
}
}
Response Fields
Customer Object
| Field | Type | Description |
id | string | Unique customer ID |
localName | string | Local name of the customer |
defaultPriceListId | string? | Default price list ID (if assigned) |
isActive | boolean | Active status of customer |
createdAt | string | Creation timestamp (ISO 8601) |
updatedAt | string | Last update timestamp (ISO 8601) |
CustomerStore Object
| Field | Type | Description |
id | string | Unique customer-store relation ID |
customerId | string | Customer ID |
storeId | string | Store ID |
createdAt | string | Creation timestamp (ISO 8601) |
Possible Errors
| Code | Message |
| 400 | Bad Request - Invalid request data or validation errors |
| 403 | Forbidden - User does not have access to this store |
| 404 | Not Found - Price list not found (if defaultPriceListId provided) |
| 500 | Internal Server Error - Failed to create customer |
Example Request
curl -X POST "https://jethings-backend.fly.dev/customers" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here" \
-d '{
"localName": "Ali'\''s Boutique",
"defaultPriceListId": "pl_abc123"
}'
Create customer without price list:
curl -X POST "https://jethings-backend.fly.dev/customers" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here" \
-d '{
"localName": "New Customer"
}'
Set Customer Price List
PUT /customers/:customerId/price-list
Assign or update the default price list of a customer. Optionally update the customer’s name at the same time.
Requires Authentication: Bearer token in Authorization header
| Key | Value | Required | Description |
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Path Parameters
| Parameter | Type | Required | Description |
customerId | string | Yes | The ID of the customer |
Request Body
{
"priceListId": "pl_789xyz",
"name": "Updated Customer Name"
}
Request Body Fields
| Field | Type | Required | Description |
priceListId | string (UUID) | Yes | The price list ID to assign to this customer |
name | string | No | Optional name to update for the customer |
Success Response
Status Code: 200 OK
{
"success": true,
"message": "Customer price list has been updated",
"customer": {
"id": "cst_abc123",
"localName": "Ali's Boutique",
"defaultPriceListId": "pl_789xyz",
"isActive": true,
"updatedAt": "2025-11-03T11:00:00.000Z"
}
}
Response Fields
| Field | Type | Description |
success | boolean | Operation success status |
message | string | Success message |
customer | object | Updated customer object |
customer.id | string | Unique customer ID |
customer.localName | string | Local name of the customer |
customer.defaultPriceListId | string? | Default price list ID (if assigned) |
customer.isActive | boolean | Active status of customer |
customer.updatedAt | string | Last update timestamp (ISO 8601) |
Possible Errors
| Code | Message |
| 400 | Bad Request - Invalid request data or validation errors |
| 403 | Forbidden - User does not have access to this store |
| 404 | Not Found - Customer or price list not found |
| 500 | Internal Server Error - Failed to update customer price list |
Example Requests
Set price list only:
curl -X PUT "https://jethings-backend.fly.dev/customers/cst_abc123/price-list" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here" \
-d '{
"priceListId": "pl_789xyz"
}'
Set price list with customer name update:
curl -X PUT "https://jethings-backend.fly.dev/customers/cst_abc123/price-list" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here" \
-d '{
"priceListId": "pl_789xyz",
"name": "Updated Customer Name"
}'
Remove Customer Price List
DELETE /customers/:customerId/price-list
Remove the default price list from a customer.
Requires Authentication: Bearer token in Authorization header
| Key | Value | Required | Description |
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Path Parameters
| Parameter | Type | Required | Description |
customerId | string | Yes | The ID of the customer |
Success Response
Status Code: 200 OK
{
"success": true,
"message": "Customer price list has been removed",
"customer": {
"id": "cst_abc123",
"localName": "Ali's Boutique",
"defaultPriceListId": null,
"isActive": true,
"updatedAt": "2025-11-03T11:15:00.000Z"
}
}
Response Fields
| Field | Type | Description |
success | boolean | Operation success status |
message | string | Success message |
customer | object | Updated customer object |
customer.id | string | Unique customer ID |
customer.localName | string | Local name of the customer |
customer.defaultPriceListId | null | Price list removed (set to null) |
customer.isActive | boolean | Active status of customer |
customer.updatedAt | string | Last update timestamp (ISO 8601) |
Possible Errors
| Code | Message |
| 403 | Forbidden - User does not have access to this store |
| 404 | Not Found - Customer not found |
| 500 | Internal Server Error - Failed to remove customer price list |
Example Request
curl -X DELETE "https://jethings-backend.fly.dev/customers/cst_abc123/price-list" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here"
Bulk Delete Customers
DELETE /customers/bulk
Remove multiple customers from the current store in one request. This deletes the customer-store relations for the provided IDs; it does not delete the underlying customer records globally.
Requires Authentication: Bearer token in Authorization header
| Key | Value | Required | Description |
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Request Body
{
"ids": ["cst_123", "cst_456", "cst_789"]
}
Request Body Fields
| Field | Type | Required | Description |
ids | string[] UUID | Yes | List of customer IDs linked to this store to remove |
Success Response
Status Code: 200 OK
{
"message": "Customers removed from store",
"deletedCount": 3
}
Possible Errors
| Code | Message |
| 400 | No customer IDs provided |
| 403 | User does not have access to this store |
| 500 | Internal Server Error |
Example Request
curl -X DELETE "https://jethings-backend.fly.dev/customers/bulk" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-store-id: store_id_here" \
-d '{
"ids": ["cst_123", "cst_456"]
}'
Data Models
CustomerResponseDto
| Field | Type | Description |
id | string | Unique customer ID |
name | string | Customer display name |
localName | string? | Local name of the customer (if set) |
defaultPriceListId | string? | Default price list ID (if assigned) |
userId | string? | Related user ID (if created by user) |
isActive | boolean | Active status of customer |
createdAt | Date | Creation timestamp |
updatedAt | Date | Last update timestamp |
| Field | Type | Description |
page | number | Current page number |
limit | number | Number of items per page |
total | number | Total number of records |
totalPages | number | Total pages available |
hasNext | boolean | Whether a next page exists |
hasPrev | boolean | Whether a previous page exists |
PaginatedCustomersResponseDto
{
data: CustomerResponseDto[];
pagination: PaginationDto;
}
Summary
| Endpoint | Method | Description |
/customers | GET | Retrieve paginated list of customers for a store |
/customers | POST | Create a new customer and link to store |
/customers/:customerId/price-list | PUT | Assign or update customer’s default price list |
/customers/:customerId/price-list | DELETE | Remove customer’s default price list |
/customers/bulk | DELETE | Bulk remove customers from the current store |
Security & Validation
- All routes require a valid
x-store-id header
- User must have an active relation with the store to access its customers
- Store ID validation prevents unauthorized access
- Pagination limits are enforced (max 100 items per page)
Business Logic
Customer Creation
- Customers can be created manually via POST
/customers with a localName
- When creating a customer, you can optionally assign a
defaultPriceListId
- Creating a customer automatically creates a
CustomerStore relation linking the customer to the store
- The price list must exist and be active if provided
Customer Price List Management
- Customers can have a default price list assigned via PUT
/customers/:customerId/price-list
- The price list must exist and be active (verified by
verifyPriceList())
- Optionally, you can update the customer’s name when setting the price list by including the
name field in the request
- Price lists can be removed via DELETE
/customers/:customerId/price-list
- Removing a price list sets
defaultPriceListId to null
Customer Retrieval
- Returns paginated lists of customers for a specific store
- Supports filtering by name (exact or partial match) and active status
- Supports sorting by name, isActive, updatedAt, or createdAt
- Default sorting is by createdAt in descending order (newest first)
- Pagination is 1-based (first page is page 1)
Internal Methods
These methods are part of the internal business logic and are not exposed as public endpoints:
| Method | Purpose |
verifyPriceList() | Checks if a price list exists and is active |
createCustomerFromStore(storeId, storeName) | Auto-creates customer entities for new stores |
createCustomerFromUser(userId, firstName, lastName) | Creates a customer linked to a user account |
getCustomerByUserId(userId) | Fetches the customer record for a specific user |
getCustomerByStoreId(storeId) | Returns the customer representing a store |
Validation Rules
- Page number must be >= 1
- Limit must be between 1 and 100
- SortBy must be one of:
name, isActive, updatedAt, createdAt
- SortOrder must be either
asc or desc
- User must have access to the specified store
localName is required when creating a customer
priceListId must be a valid UUID and reference an existing, active price list
- Bulk delete requires at least one valid UUID in
ids
- Only customers linked to the specified store will be removed
Error Responses
Common Error Codes
| Code | Description |
| 400 | Bad Request - Invalid input or validation |
| 403 | Forbidden - User does not have access to this store |
| 500 | Internal Server Error - Database or server error |
{
"message": "Error description",
"statusCode": 400
}
Example Error Responses
403 Forbidden:
{
"message": "You do not have access to this store",
"statusCode": 403
}
400 Bad Request:
{
"message": "Invalid page number",
"statusCode": 400
}
500 Internal Server Error:
{
"message": "Failed to fetch customers",
"statusCode": 500
}