Supplier API
The Supplier API provides endpoints for managing suppliers and their relations to stores, groups, addresses, and contacts in optical stores.All Supplier API endpoints require authentication and a valid
x-store-id header to identify the store context, unless stated otherwise.Overview
Suppliers can be:- Linked to one or more stores
- Assigned to one or more supplier groups
- Created with optional address and contact information
- Assigned or updated with a default price list
- Filtered and sorted by various criteria
- Retrieved in paginated lists
- Deleted individually or in bulk
Endpoint Details
Base URL:https://joptic.jethings.comContent-Type:
application/json
Required Headers
Get All Suppliers
GET/suppliers
Retrieve a paginated list of suppliers linked to the store that the authenticated user has access to.
Requires Authentication: Bearer token in Authorization header
Required Headers
| 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 by name or description (partial match) | — |
name | string | No | Filter by supplier name (partial match) | — |
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
Response Fields
Supplier Object
| Field | Type | Description |
|---|---|---|
id | string | Unique supplier ID |
storeIds | string[] | Store IDs this supplier is linked to |
supplierGroups | object[] | Groups assigned to the supplier |
supplierGroups[].id | string | Group ID |
supplierGroups[].name | string | Group name |
name | string | Supplier display name |
description | string? | Supplier description |
note | string? | Internal note |
defaultPriceListId | string? | Default price list ID |
address | Address? | Address information |
contact | Contact? | Contact information |
isActive | boolean | Active status |
createdAt | string | Creation timestamp (ISO 8601) |
updatedAt | string | Last update timestamp (ISO 8601) |
Address
| Field | Type | Description |
|---|---|---|
id | string | Address ID |
street | string | Street |
city | string | City |
state | string | State/Province |
postalCode | string | Postal/ZIP code |
country | string | Country |
Contact
| Field | Type | Description |
|---|---|---|
id | string | Contact ID |
phone | string | Phone number |
fax | string | Fax number |
email | string | Email address |
website | string | Website URL |
Pagination Object
| 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 |
|---|---|
| 403 | Forbidden - User does not have access to store |
| 500 | Internal Server Error |
Example Requests
Get Supplier by ID
GET/suppliers/:id
Retrieve a single supplier by ID. The supplier must be linked to the current store.
Requires Authentication: Bearer token in Authorization header
Required Headers
| Key | Value | Required | Description |
|---|---|---|---|
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The ID of the supplier |
Success Response
Status Code:200 OK
Possible Errors
| Code | Message |
|---|---|
| 403 | Forbidden - User does not have access to store or supplier |
| 404 | Not Found - Supplier not found or inaccessible |
| 500 | Internal Server Error |
Example Requests
Create Supplier
POST/suppliers
Create a new supplier and link it to the current store. You can optionally assign supplier groups, a default price list, address, and contact information.
Requires Authentication: Bearer token in Authorization header
Required Headers
| Key | Value | Required | Description |
|---|---|---|---|
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
supplierGroupIds | string[] | No | Supplier groups to associate |
name | string | ✅ Yes | Supplier name (max 255 characters) |
description | string | No | Description (max 1000 characters) |
note | string | No | Internal note (max 1000 characters) |
defaultPriceListId | string | No | Default price list to assign |
address | AddressInput | No | Address to create |
contact | ContactInput | No | Contact to create |
AddressInput
| Field | Type | Required | Description |
|---|---|---|---|
street | string | ✅ Yes | Street (max 255 characters) |
city | string | ✅ Yes | City (max 100 characters) |
state | string | ✅ Yes | State/Province (max 100 characters) |
postalCode | string | ✅ Yes | Postal/ZIP code (max 20 characters) |
country | string | ✅ Yes | Country (max 100 characters) |
ContactInput
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | No | Phone number (max 20 characters) |
fax | string | No | Fax number (max 20 characters) |
email | string | No | Email address (max 255 characters, must be valid email) |
website | string | No | Website URL (max 255 characters) |
Request Body Example
Success Response
Status Code:200 OK
Possible Errors
| Code | Message |
|---|---|
| 400 | Bad Request - Invalid request data |
| 403 | Forbidden - User does not have access to this store |
| 404 | Not Found - Price list or supplier group not found |
| 500 | Internal Server Error - Failed to create supplier |
Example Requests
When creating a supplier, the system automatically:
- Creates an address record if address information is provided
- Creates a contact record if contact information is provided
- Links the supplier to the authenticated user’s store
- Assigns the supplier to specified supplier groups if
supplierGroupIdsis provided - Validates that all supplier groups and price list exist before creating
Update Supplier
PUT/suppliers/:id
Update an existing supplier. You may update core fields, default price list, address, and contact. If address/contact do not exist, they will be created.
Requires Authentication: Bearer token in Authorization header
Required Headers
| Key | Value | Required | Description |
|---|---|---|---|
x-store-id | string | Yes | Store identifier (used by @StoreId() decorator) |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The ID of the supplier |
Request Body
All fields are optional (partial updates supported):| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Supplier name (max 255 characters) |
description | string | No | Description (max 1000 characters) |
note | string | No | Internal note (max 1000 characters) |
defaultPriceListId | string | No | Default price list to assign |
isActive | boolean | No | Active status |
address | AddressInput | No | Address to create/update |
contact | ContactInput | No | Contact to create/update |
Request Body Example
Success Response
Status Code:200 OK
Returns the updated Supplier object (same shape as in “Get Supplier by ID”).
Possible Errors
| Code | Message |
|---|---|
| 400 | Bad Request - Validation errors |
| 403 | Forbidden - User does not have access to this store or supplier |
| 404 | Not Found - Supplier or price list not found |
| 500 | Internal Server Error - Failed to update supplier |
Example Requests
When updating a supplier:
- Only provided fields are updated (partial updates supported)
- Address fields are updated in the linked address record, or a new address record is created if one doesn’t exist
- Contact fields are updated in the linked contact record, or a new contact record is created if one doesn’t exist
- The
updatedAttimestamp is automatically updated - Price list is validated if provided
Delete Single Supplier
DELETE/suppliers/:id
Delete a single supplier by its ID. This is a permanent deletion.
Requires Authentication: Bearer token in Authorization header
Rate Limited: 5 requests per minute
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The ID of the supplier |
Success Response
Status Code:200 OK
Possible Errors
| Code | Message |
|---|---|
| 404 | Not Found - Supplier not found |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
Example Requests
Bulk Delete Suppliers
DELETE/suppliers
Delete multiple suppliers by their IDs. This is a permanent deletion.
Requires Authentication: Bearer token in Authorization header
Rate Limited: 3 requests per minute
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
ids | string[] UUID | ✅ Yes | Supplier IDs to delete |
Request Body Example
Success Response
Status Code:200 OK
Possible Errors
| Code | Message |
|---|---|
| 400 | Bad Request - No supplier IDs provided |
| 404 | Not Found - No valid suppliers found to delete |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
Example Requests
Business Logic
Supplier Creation Flow
Store Linking
Store Linking
Store LinkingWhen creating a supplier:
- The supplier is automatically linked to the authenticated user’s store
- Store access is validated before creation
- The supplier can be linked to multiple stores via
storeIdsarray - Store linking is managed through
supplierStoreRelationtable
Supplier Group Assignment
Supplier Group Assignment
Supplier Group AssignmentSuppliers can be assigned to groups:
- Provide
supplierGroupIdsarray in the request - All supplier group IDs are validated before creation
- If any group doesn’t exist, creation fails with 404
- Groups are linked through
supplierGroupRelationtable - A supplier can belong to multiple groups
Address Management
Address Management
Address ManagementAddress information is optional:
- If address is provided, a new address record is created
- All address fields are required if address object is provided
- The address is automatically linked to the supplier via
addressId - Address can be updated independently when updating the supplier
- If address doesn’t exist and is provided in update, a new address is created
Contact Management
Contact Management
Contact ManagementContact information is optional:
- If contact is provided, a new contact record is created
- Contact fields (phone, fax, email, website) are all optional
- The contact is automatically linked to the supplier via
contactId - Contact can be updated independently when updating the supplier
- If contact doesn’t exist and is provided in update, a new contact is created
Default Price List
Default Price List
Default Price ListSuppliers can have a default price list:
- Provide
defaultPriceListIdin the request - Price list is validated before creation/update
- If price list doesn’t exist, operation fails with 404
- Default price list can be changed or removed (set to null) on update
Store Access Validation
Store Access Validation
Store Access ValidationAccess control is enforced:
- User must have an active relation with the store to access its suppliers
- Store access is validated on every request
- Users can only create/update/delete suppliers for stores they have access to
- Supplier operations are scoped to the authenticated user’s accessible stores
Partial Updates
Partial Updates
Partial UpdatesThe update endpoint supports flexible partial updates:
- Only provided fields are updated
- Address fields can be updated independently
- Contact fields can be updated independently
- Supplier fields (name, description, note, defaultPriceListId, isActive) can be updated independently
- This allows fine-grained control over what gets updated
Supplier States
Active Supplier
Active (
Supplier is currently in use and available for operations
isActive: true)Supplier is currently in use and available for operations
Grouped Supplier
Grouped (has supplierGroups)
Supplier belongs to one or more supplier groups
Supplier belongs to one or more supplier groups
With Address
Address Information
Supplier has associated address details
Supplier has associated address details
With Contact
Contact Information
Supplier has associated contact details (phone, email, website)
Supplier has associated contact details (phone, email, website)
Error Responses
All endpoints may return standard HTTP error codes:400 Bad Request- Invalid request parameters or body403 Forbidden- User does not have access to the store or supplier404 Not Found- Resource not found (supplier, store, price list, supplier group, etc.)429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Server error
Error Response Format
Common Error Scenarios
403 Forbidden - Store AccessUsage Examples
Example 1: Create a supplier with all information
Example 2: Create a supplier with minimal information
Example 3: Update supplier contact only
Example 4: Bulk delete suppliers
Best Practices
Supplier Organization
Supplier Organization
- Use supplier groups to organize suppliers by category or type
- Assign default price lists for easier price management
- Keep supplier names descriptive and consistent
- Use notes field for important supplier-specific information
Address and Contact
Address and Contact
- Provide complete address information for accurate location tracking
- Keep contact information up to date for easy communication
- Use consistent address formats across suppliers
- Update contact information when personnel changes
Pagination
Pagination
- Use pagination when fetching large lists of suppliers
- Default limit of 10 is suitable for most use cases
- Maximum limit of 100 should be used sparingly
- Always check
hasNextandhasPrevfor navigation
Filtering and Search
Filtering and Search
- Use
searchfor general name/description searches - Use
namefor specific name filtering - Combine filters for precise results
- Use
isActiveto filter active/inactive suppliers
Partial Updates
Partial Updates
- Only send fields that need to be updated
- Update address and contact information independently when possible
- Use partial updates to avoid overwriting unchanged data
- Verify supplier ID before updating
Deletion
Deletion
- Verify supplier ID before deletion
- Check for dependent records (purchase orders, invoices) before deleting
- Use bulk delete for multiple suppliers (rate limited to 3 per minute)
- Single delete is rate limited to 5 per minute
- Deletion is permanent and cannot be undone
Rate Limiting
Rate Limiting
- DELETE endpoints are rate limited for safety
- Single delete: 5 requests per minute
- Bulk delete: 3 requests per minute
- Implement retry logic with exponential backoff for rate limit errors
Related Endpoints
Suppliers work in conjunction with other inventory management endpoints:- Supplier Groups API (
/supplier-groups) - Manage supplier groups and assign suppliers - Price List API (
/price-lists) - Manage price lists that can be assigned to suppliers - Purchase Invoice API (
/purchase-invoices) - Create purchase invoices from suppliers - Purchase Order API (
/purchase-orders) - Create purchase orders with suppliers
Suppliers are essential for managing vendor relationships in optical stores. They can be organized into groups, assigned default price lists, and linked to multiple stores. Use suppliers to track vendor information and manage purchasing relationships.
Summary
| Endpoint | Method | Description |
|---|---|---|
/suppliers | GET | Retrieve paginated list of suppliers |
/suppliers/:id | GET | Retrieve a single supplier by ID |
/suppliers | POST | Create a new supplier |
/suppliers/:id | PUT | Update an existing supplier (partial updates) |
/suppliers/:id | DELETE | Delete a single supplier (rate limited: 5/min) |
/suppliers | DELETE | Bulk delete suppliers (rate limited: 3/min) |