Skip to main content

Supplier Group API

The Supplier Group API enables optical stores to organize suppliers into groups, manage group memberships, and maintain store-specific group details.
All Supplier Group API endpoints require authentication. Routes that operate in a store context also require a valid x-store-id header.

Overview

Supplier groups can be:
  • Created per store with unique names
  • Listed with pagination, filtering, and sorting
  • Retrieved individually or as a simplified list
  • Updated for name or metadata
  • Deleted individually or in bulk (if empty)
  • Used to bulk assign or remove suppliers

Endpoint Details

Base URL: https://joptic.jethings.com
Content-Type: application/json

Required Headers

x-store-id: <store_id>
Authorization: Bearer <token>
Endpoints that require x-store-id enforce store-level access control. Ensure the requesting user has an active relation with the store.

Create Supplier Group

POST /supplier-groups Create a new supplier group scoped to the current store. Requires Authentication: Bearer token in Authorization header
Requires Header: x-store-id
Rate Limited: 10 requests per minute

Required Headers

KeyValueRequiredDescription
x-store-idstringYesStore identifier (used by @StoreId() decorator)

Request Body

FieldTypeRequiredDescription
namestring✅ YesUnique supplier group name (max 255 characters)

Request Body Example

{
  "name": "Electronics Group"
}

Success Response

Status Code: 201 Created
{
  "id": "sgrp_abc123",
  "name": "Electronics Group",
  "supplierCount": 0,
  "createdAt": "2025-11-03T10:00:00.000Z",
  "updatedAt": "2025-11-03T10:00:00.000Z",
  "deletedAt": null
}

Possible Errors

CodeMessage
400Bad Request - Invalid input data
401Unauthorized
409Conflict - Supplier group with this name already exists
500Internal Server Error

Example Requests

curl -X POST "https://joptic.jethings.com/supplier-groups" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Electronics Group" }'
Supplier group names must be unique within a store. If a group with the same name already exists for the store, a 409 Conflict error is returned.

Get All Supplier Groups

GET /supplier-groups Retrieve a paginated list of supplier groups for the current store with optional filters. Requires Authentication: Bearer token in Authorization header
Requires Header: x-store-id
Rate Limited: 60 requests per minute

Required Headers

KeyValueRequiredDescription
x-store-idstringYesStore identifier (used by @StoreId() decorator)

Query Parameters

ParameterTypeRequiredDescriptionDefault
searchstringNoPartial match for group name
namestringNoPartial match for group name (alias of search)
pagenumberNoPage number (1-based)1
limitnumberNoItems per page (1–100)10
sortBystringNoSort field (id, name, updatedAt, createdAt)createdAt
sortOrderstringNoSort direction (asc or desc)desc

Success Response

Status Code: 200 OK
{
  "data": [
    {
      "id": "sgrp_abc123",
      "name": "Electronics Group",
      "supplierCount": 5,
      "createdAt": "2025-10-01T09:00:00.000Z",
      "updatedAt": "2025-10-15T12:30:00.000Z",
      "deletedAt": null
    },
    {
      "id": "sgrp_def456",
      "name": "Local Suppliers",
      "supplierCount": 3,
      "createdAt": "2025-09-15T08:00:00.000Z",
      "updatedAt": "2025-09-20T10:00:00.000Z",
      "deletedAt": null
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 4,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  }
}

Response Fields

SupplierGroup Object

FieldTypeDescription
idstringUnique supplier group ID
namestringGroup name
supplierCountnumberNumber of active suppliers in the group
createdAtstringCreation timestamp (ISO 8601)
updatedAtstringLast update timestamp (ISO 8601)
deletedAtstring?Deletion timestamp (if soft deleted)

Pagination Object

FieldTypeDescription
pagenumberCurrent page number
limitnumberNumber of items per page
totalnumberTotal number of records
totalPagesnumberTotal pages available
hasNextbooleanWhether a next page exists
hasPrevbooleanWhether a previous page exists

Possible Errors

CodeMessage
401Unauthorized
500Internal Server Error

Example Requests

curl -X GET "https://joptic.jethings.com/supplier-groups?page=1&limit=10" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>"
Search by name:
curl -X GET "https://joptic.jethings.com/supplier-groups?search=electronics" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>"

Get Supplier Groups List

GET /supplier-groups/list Retrieve all supplier groups accessible to the authenticated user across stores they can access. This simplified list includes supplier count per group. Requires Authentication: Bearer token in Authorization header Rate Limited: 60 requests per minute

Success Response

Status Code: 200 OK
[
  {
    "id": "sgrp_abc123",
    "name": "Electronics Group",
    "supplierCount": 5,
    "createdAt": "2025-10-01T09:00:00.000Z",
    "updatedAt": "2025-10-15T12:30:00.000Z",
    "deletedAt": null
  },
  {
    "id": "sgrp_def456",
    "name": "Local Suppliers",
    "supplierCount": 3,
    "createdAt": "2025-09-15T08:00:00.000Z",
    "updatedAt": "2025-09-20T10:00:00.000Z",
    "deletedAt": null
  }
]

Possible Errors

CodeMessage
401Unauthorized
500Internal Server Error

Example Requests

curl -X GET "https://joptic.jethings.com/supplier-groups/list" \
  -H "Authorization: Bearer <token>"
This endpoint returns all supplier groups from stores the user has access to, sorted by name. It does not require the x-store-id header and is useful for dropdown lists or selection interfaces.

Get Supplier Group by ID

GET /supplier-groups/:id Retrieve a supplier group by ID. Requires Authentication: Bearer token in Authorization header Rate Limited: 60 requests per minute

Path Parameters

ParameterTypeRequiredDescription
idstring✅ YesSupplier group ID

Success Response

Status Code: 200 OK
{
  "id": "sgrp_abc123",
  "name": "Electronics Group",
  "supplierCount": 5,
  "createdAt": "2025-10-01T09:00:00.000Z",
  "updatedAt": "2025-10-15T12:30:00.000Z",
  "deletedAt": null
}

Possible Errors

CodeMessage
404Not Found - Supplier group not found
500Internal Server Error

Example Requests

curl -X GET "https://joptic.jethings.com/supplier-groups/sgrp_abc123" \
  -H "Authorization: Bearer <token>"

Update Supplier Group

PUT /supplier-groups/:id Update a supplier group’s name. Requires Authentication: Bearer token in Authorization header Rate Limited: 20 requests per minute

Path Parameters

ParameterTypeRequiredDescription
idstring✅ YesSupplier group ID

Request Body

FieldTypeRequiredDescription
namestringNoUpdated supplier group name (max 255 characters)

Request Body Example

{
  "name": "Electronics Group (Updated)"
}

Success Response

Status Code: 200 OK Returns the updated SupplierGroup object (same shape as in “Get Supplier Group by ID”).

Possible Errors

CodeMessage
400Bad Request - Validation errors
404Not Found - Supplier group not found
409Conflict - Supplier group with this name already exists
500Internal Server Error

Example Requests

curl -X PUT "https://joptic.jethings.com/supplier-groups/sgrp_abc123" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Electronics Group (Updated)" }'
If the new name conflicts with an existing supplier group name in the same store, a 409 Conflict error is returned. The name must be unique within the store scope.

Delete Supplier Group

DELETE /supplier-groups/:id Delete a supplier group. The group must not contain active suppliers. Requires Authentication: Bearer token in Authorization header Rate Limited: 5 requests per minute
If the group still contains suppliers, deletion will fail with a conflict error. Reassign or remove suppliers before deleting.

Path Parameters

ParameterTypeRequiredDescription
idstring✅ YesSupplier group ID

Success Response

Status Code: 200 OK
{
  "message": "Supplier group deleted successfully"
}

Possible Errors

CodeMessage
404Not Found - Supplier group not found
409Conflict - Supplier group has active suppliers
429Too Many Requests - Rate limit exceeded
500Internal Server Error

Example Requests

curl -X DELETE "https://joptic.jethings.com/supplier-groups/sgrp_abc123" \
  -H "Authorization: Bearer <token>"

Bulk Delete Supplier Groups

DELETE /supplier-groups Delete multiple supplier groups by IDs. Each group must be empty (no active suppliers). Requires Authentication: Bearer token in Authorization header Rate Limited: 3 requests per minute

Request Body

FieldTypeRequiredDescription
idsstring[] UUID✅ YesSupplier group IDs to delete

Request Body Example

{
  "ids": ["sgrp_123", "sgrp_456"]
}

Success Response

Status Code: 200 OK
{
  "message": "Successfully deleted 2 out of 2 supplier groups",
  "deletedCount": 2
}

Possible Errors

CodeMessage
400No supplier group IDs provided
404Supplier group not found
409Conflict - Group has active suppliers
429Too Many Requests - Rate limit exceeded
500Internal Server Error

Example Requests

curl -X DELETE "https://joptic.jethings.com/supplier-groups" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "ids": ["sgrp_123", "sgrp_456"] }'
This is a bulk delete operation. Only empty supplier groups (with no active suppliers) can be deleted. Groups with active suppliers will cause a 409 Conflict error. The operation processes each group individually and returns the count of successfully deleted groups. Rate limited to 3 requests per minute for safety.

Bulk Assign Suppliers to Group

POST /supplier-groups/:id/assign-suppliers Assign multiple suppliers to a supplier group. Existing assignments are skipped. Requires Authentication: Bearer token in Authorization header Rate Limited: 10 requests per minute

Path Parameters

ParameterTypeRequiredDescription
idstring✅ YesSupplier group ID

Request Body

FieldTypeRequiredDescription
supplierIdsstring[] UUID✅ YesSupplier IDs to assign to the group

Request Body Example

{
  "supplierIds": ["sup_123", "sup_456", "sup_789"]
}

Success Response

Status Code: 200 OK
{
  "message": "Successfully assigned 2 out of 3 suppliers to group",
  "assignedCount": 2
}

Possible Errors

CodeMessage
404Supplier group not found or supplier not found
429Too Many Requests - Rate limit exceeded
500Internal Server Error

Example Requests

curl -X POST "https://joptic.jethings.com/supplier-groups/sgrp_abc123/assign-suppliers" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "supplierIds": ["sup_123", "sup_456"] }'
The operation processes each supplier individually. If a supplier is already assigned to the group, it is skipped. If a supplier doesn’t exist, it is skipped. The response indicates how many suppliers were successfully assigned out of the total provided.

Bulk Remove Suppliers from Group

POST /supplier-groups/:id/remove-suppliers Remove multiple suppliers from a supplier group. Relations are marked inactive rather than deleted. Requires Authentication: Bearer token in Authorization header Rate Limited: 10 requests per minute

Path Parameters

ParameterTypeRequiredDescription
idstring✅ YesSupplier group ID

Request Body

FieldTypeRequiredDescription
supplierIdsstring[] UUID✅ YesSupplier IDs to remove from the group

Request Body Example

{
  "supplierIds": ["sup_123", "sup_456"]
}

Success Response

Status Code: 200 OK
{
  "message": "Successfully removed 2 out of 2 suppliers from group",
  "removedCount": 2
}

Possible Errors

CodeMessage
404Supplier group not found or supplier not found
429Too Many Requests - Rate limit exceeded
500Internal Server Error

Example Requests

curl -X POST "https://joptic.jethings.com/supplier-groups/sgrp_abc123/remove-suppliers" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "supplierIds": ["sup_123", "sup_456"] }'
The operation processes each supplier individually. If a supplier is not assigned to the group, it is skipped. The supplier-group relation is marked as inactive (soft delete) rather than being permanently deleted. The response indicates how many suppliers were successfully removed out of the total provided.

Business Logic

Supplier Group Management

Store ScopingSupplier groups are scoped to stores:
  1. Each supplier group belongs to a specific store
  2. Group names must be unique within a store (not globally)
  3. Users can only access groups from stores they have access to
  4. The x-store-id header determines the store context for operations
Unique Name ValidationGroup names are validated per store:
  1. When creating a group, the name must be unique within the store
  2. When updating a group, the new name must be unique within the store
  3. If a duplicate name is found, a 409 Conflict error is returned
  4. This allows the same group name to exist in different stores
Supplier Count TrackingSupplier counts are automatically calculated:
  1. supplierCount shows the number of active suppliers in the group
  2. Count is calculated from active supplier-group relations
  3. Count is updated in real-time when suppliers are assigned/removed
  4. Used to determine if a group can be deleted (must be 0)
Deletion RestrictionsGroups with suppliers cannot be deleted:
  1. Before deletion, the system checks if the group has active suppliers
  2. If supplierCount > 0, deletion fails with 409 Conflict
  3. You must remove all suppliers from the group before deletion
  4. Use the bulk remove endpoint to clear suppliers first
Bulk AssignmentBulk assignment is fault-tolerant:
  1. Each supplier is processed individually
  2. Already-assigned suppliers are skipped (no error)
  3. Non-existent suppliers are skipped (no error)
  4. Only successfully assigned suppliers are counted
  5. Response indicates success count vs total provided
Bulk RemovalBulk removal uses soft delete:
  1. Each supplier is processed individually
  2. Not-assigned suppliers are skipped (no error)
  3. Relations are marked inactive (not permanently deleted)
  4. This preserves historical data for audit purposes
  5. Response indicates success count vs total provided

Supplier Group States

Empty Group

Empty (supplierCount: 0)
Group has no active suppliers and can be deleted

Active Group

Active (supplierCount > 0)
Group contains suppliers and cannot be deleted

Store-Scoped

Store-Scoped
Group belongs to a specific store

Unique Name

Unique Name
Name must be unique within the store

Error Responses

All endpoints may return standard HTTP error codes:
  • 400 Bad Request - Invalid request parameters or body
  • 401 Unauthorized - Missing or invalid authentication token
  • 403 Forbidden - User does not have access to the store
  • 404 Not Found - Resource not found (supplier group, supplier, etc.)
  • 409 Conflict - Name duplicate or group has active suppliers
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

Error Response Format

{
  "statusCode": 409,
  "message": "Supplier group with this name already exists",
  "error": "Conflict"
}

Common Error Scenarios

409 Conflict - Duplicate Name
{
  "statusCode": 409,
  "message": "Supplier group with this name already exists"
}
Occurs when trying to create or update a group with a name that already exists in the store. 409 Conflict - Group Has Suppliers
{
  "statusCode": 409,
  "message": "Cannot delete supplier group that has suppliers. Please reassign or delete suppliers first."
}
Occurs when trying to delete a group that still has active suppliers. 404 Not Found - Supplier Group
{
  "statusCode": 404,
  "message": "Supplier group not found"
}
Occurs when the supplier group ID doesn’t exist. 400 Bad Request - Validation Error
{
  "statusCode": 400,
  "message": ["name must be a string", "ids must be an array"],
  "error": "Bad Request"
}
Occurs when required fields are missing or data types are incorrect.

Usage Examples

Example 1: Create a supplier group

curl -X POST "https://joptic.jethings.com/supplier-groups" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Premium Lens Suppliers" }'

Example 2: Get all supplier groups with pagination

curl -X GET "https://joptic.jethings.com/supplier-groups?page=1&limit=20&sortBy=name&sortOrder=asc" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>"

Example 3: Update supplier group name

curl -X PUT "https://joptic.jethings.com/supplier-groups/sgrp_123" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Updated Group Name" }'

Example 4: Assign suppliers to a group

curl -X POST "https://joptic.jethings.com/supplier-groups/sgrp_123/assign-suppliers" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "supplierIds": ["sup_123", "sup_456", "sup_789"] }'

Example 5: Remove suppliers from a group

curl -X POST "https://joptic.jethings.com/supplier-groups/sgrp_123/remove-suppliers" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "supplierIds": ["sup_123", "sup_456"] }'

Example 6: Delete empty supplier group

curl -X DELETE "https://joptic.jethings.com/supplier-groups/sgrp_123" \
  -H "Authorization: Bearer <token>"

Best Practices

  • Use descriptive group names that indicate the category or type
  • Organize suppliers by product category, location, or business relationship
  • Keep group names consistent across stores
  • Use groups to filter and manage suppliers efficiently
  • Ensure group names are unique within each store
  • Use consistent naming conventions
  • Update group names when business needs change
  • Check for name conflicts before creating groups
  • Use bulk assignment for efficiency when adding multiple suppliers
  • Assign suppliers to groups during creation for better organization
  • Use bulk removal to clear groups before deletion
  • Monitor supplier counts to understand group usage
  • Check supplierCount before attempting deletion
  • Remove all suppliers from a group before deleting it
  • Use bulk delete for multiple empty groups
  • Verify group IDs before deletion
  • Deletion is permanent and cannot be undone
  • DELETE endpoints are rate limited for safety
  • Single delete: 5 requests per minute
  • Bulk delete: 3 requests per minute
  • Bulk operations: 10 requests per minute
  • Implement retry logic with exponential backoff for rate limit errors
  • Bulk operations are fault-tolerant and skip invalid entries
  • Check the response count to see how many operations succeeded
  • Handle partial success scenarios appropriately
  • Use bulk operations for efficiency when managing multiple items

Supplier groups work in conjunction with other inventory management endpoints:
  • Supplier API (/suppliers) - Manage suppliers that can be assigned to groups
  • Price List API (/price-lists) - Manage price lists for suppliers in groups
Supplier groups help organize suppliers by category, making it easier to manage vendor relationships and filter suppliers. Groups are store-scoped, allowing different stores to have their own organizational structure.

Summary

EndpointMethodDescription
/supplier-groupsPOSTCreate a new supplier group (rate: 10/min)
/supplier-groupsGETPaginated list of supplier groups (rate: 60/min)
/supplier-groups/listGETList supplier groups accessible to the user (rate: 60/min)
/supplier-groups/:idGETRetrieve a supplier group by ID (rate: 60/min)
/supplier-groups/:idPUTUpdate a supplier group (rate: 20/min)
/supplier-groups/:idDELETEDelete a supplier group (rate: 5/min)
/supplier-groupsDELETEBulk delete supplier groups (rate: 3/min)
/supplier-groups/:id/assign-suppliersPOSTBulk assign suppliers to a group (rate: 10/min)
/supplier-groups/:id/remove-suppliersPOSTBulk remove suppliers from a group (rate: 10/min)