Kobo PLM API Documentation
The Kobo PLM API provides programmatic access to your product lifecycle management data. Use it to integrate with ERPs, build custom workflows, or sync data with external systems.
Base URL
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.
Authentication
All API requests require authentication using an API key. Include your API key in theX-API-Key header with every request.
curl -X GET "https://api.kobolabs.io/api/v1/styles" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json"Getting an API Key
- Log in to Kobo PLM
- Go to Account Settings → API Keys
- Click Create API Key
- Select the scopes (permissions) you need
- Copy and securely store your key - it won't be shown again
API Key Scopes
| Scope | Description |
|---|---|
* | Full access to all resources |
styles:read | Read styles/products |
styles:write | Create, update, delete styles |
components:read | Read components/materials |
components:write | Create, update, delete components |
suppliers:read | Read suppliers |
suppliers:write | Create, update, delete suppliers |
purchase_orders:read | Read purchase orders |
purchase_orders:write | Create, update, delete purchase orders |
inventory:read | Read inventory levels |
inventory:write | Update inventory |
customers:read | Read customers |
customers:write | Create, update, delete customers |
sales_orders:read | Read sales orders |
sales_orders:write | Create, update, delete sales orders |
deliveries:read | Read deliveries |
bom:read | Read bill of materials |
bom:write | Manage bill of materials |
pom:read | Read points of measure |
pom:write | Manage points of measure |
tasks:read | Read tasks |
tasks:write | Create, update, delete tasks |
notes:read | Read notes |
notes:write | Create, update, delete notes |
projects:read | Read projects |
projects:write | Create, update, delete projects |
cancellations:read | Read cancellations |
cancellations:write | Manage cancellations |
returns:read | Read returns |
returns:write | Manage returns |
payments:read | Read payments |
payments:write | Create, update payments |
stock_takes:read | Read stock takes |
stock_takes:write | Manage stock takes |
workflows:read | Read workflows |
workflows:write | Manage workflows |
notifications:read | Read notifications |
notifications:write | Manage notifications |
webhooks:read | Read webhook configurations |
webhooks:write | Manage webhooks |
api_keys:read | Read API keys |
api_keys:write | Manage API keys |
Rate Limiting
API requests are rate limited based on your subscription tier:
| Tier | Requests per Minute |
|---|---|
| Basic | 100 |
| Professional | 500 |
| Enterprise | 2,000 |
Rate limit headers are included in every response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699574400429 Too Many Requests response. Implement exponential backoff to handle this gracefully.Pagination
List endpoints return paginated results. Use these query parameters:
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
Response includes pagination metadata:
{
"data": [...],
"meta": {
"current_page": 1,
"from": 1,
"last_page": 10,
"per_page": 25,
"to": 25,
"total": 250
},
"links": {
"first": "https://api.kobolabs.io/api/v1/styles?page=1",
"last": "https://api.kobolabs.io/api/v1/styles?page=10",
"prev": null,
"next": "https://api.kobolabs.io/api/v1/styles?page=2"
}
}Filtering
Most list endpoints support filtering for incremental sync:
| Parameter | Type | Description |
|---|---|---|
updated_since | datetime | ISO 8601 datetime (e.g., 2024-01-01T00:00:00Z) |
created_since | datetime | ISO 8601 datetime (e.g., 2024-01-01T00:00:00Z) |
# Get styles updated in the last 24 hours
curl "https://api.kobolabs.io/api/v1/styles?updated_since=2024-01-14T00:00:00Z" \
-H "X-API-Key: your_api_key"Error Handling
The API uses standard HTTP status codes:
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful delete) |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found |
| 422 | Validation Error |
| 429 | Rate Limited |
| 500 | Server Error |
Error responses include details:
{
"message": "The given data was invalid.",
"errors": {
"name": ["The name field is required."],
"style_code": ["The style code has already been taken."]
}
}Styles
Styles represent your products/designs in Kobo PLM.
/stylesList all styles with optional filtering and pagination
/styles/{id}Get a specific style by ID
/stylesCreate a new style
/styles/{id}Update an existing style
/styles/{id}Delete a style
List Styles
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page (max 100) |
updated_since | datetime | Filter by update time |
created_since | datetime | Filter by creation time |
status | string | Filter by status |
season_id | integer | Filter by season |
Example Request
curl "https://api.kobolabs.io/api/v1/styles?per_page=50&status=active" \
-H "X-API-Key: your_api_key"Example Response
{
"data": [
{
"id": 1,
"style_code": "SS24-001",
"name": "Classic Cotton Tee",
"description": "Premium cotton t-shirt",
"status": "active",
"category": {
"id": 1,
"name": "Tops"
},
"season": {
"id": 1,
"name": "Spring/Summer 2024"
},
"brand": {
"id": 1,
"name": "Main Brand"
},
"wholesale_price": "45.00",
"retail_price": "89.00",
"cost_price": "22.50",
"currency": "USD",
"sizes": ["XS", "S", "M", "L", "XL"],
"colors": [
{"id": 1, "name": "White", "hex": "#FFFFFF"},
{"id": 2, "name": "Black", "hex": "#000000"}
],
"images": [
{
"id": 1,
"url": "https://storage.koboplm.com/styles/1/main.jpg",
"type": "main"
}
],
"skus": [
{
"id": 1,
"sku": "SS24-001-WHT-S",
"size": "S",
"color": "White",
"barcode": "1234567890123"
}
],
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T14:45:00Z"
}
],
"meta": {
"current_page": 1,
"total": 150
}
}Create Style
curl -X POST "https://api.kobolabs.io/api/v1/styles" \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"style_code": "SS24-002",
"name": "Slim Fit Chinos",
"description": "Modern slim fit chinos",
"category_id": 2,
"season_id": 1,
"status": "development",
"wholesale_price": 65.00,
"retail_price": 129.00,
"cost_price": 32.50,
"currency": "USD",
"sizes": ["28", "30", "32", "34", "36"]
}'Components
Components represent materials, trims, and other items used in production.
/componentsList all components
/components/{id}Get a specific component
/componentsCreate a new component
/components/{id}Update an existing component
/components/{id}Delete a component
List Components
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
type | string | Filter by component type |
supplier_id | integer | Filter by supplier |
Example Response
{
"data": [
{
"id": 1,
"code": "FAB-001",
"name": "Organic Cotton Jersey",
"type": "fabric",
"description": "180gsm organic cotton jersey",
"supplier": {
"id": 1,
"name": "Premium Textiles Ltd"
},
"unit": "meter",
"unit_price": "8.50",
"currency": "USD",
"minimum_order_quantity": 100,
"lead_time_days": 14,
"specifications": {
"weight": "180gsm",
"width": "150cm",
"composition": "100% Organic Cotton"
},
"created_at": "2024-01-10T09:00:00Z",
"updated_at": "2024-01-12T11:30:00Z"
}
]
}Suppliers
/suppliersList all suppliers
/suppliers/{id}Get a specific supplier
/suppliersCreate a new supplier
/suppliers/{id}Update an existing supplier
/suppliers/{id}Delete a supplier
List Suppliers
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
country | string | Filter by country code |
type | string | Filter by supplier type |
Example Response
{
"data": [
{
"id": 1,
"name": "Premium Textiles Ltd",
"code": "SUP-001",
"type": "manufacturer",
"email": "contact@premiumtextiles.com",
"phone": "+1-555-0100",
"website": "https://premiumtextiles.com",
"address": {
"street": "123 Industrial Way",
"city": "Los Angeles",
"state": "CA",
"postal_code": "90001",
"country": "US"
},
"contacts": [
{
"name": "John Smith",
"email": "john@premiumtextiles.com",
"phone": "+1-555-0101",
"role": "Sales Manager"
}
],
"payment_terms": "Net 30",
"currency": "USD",
"rating": 4.5,
"certifications": ["GOTS", "OEKO-TEX"],
"created_at": "2024-01-05T08:00:00Z",
"updated_at": "2024-01-14T16:20:00Z"
}
]
}Purchase Orders
/purchase-ordersList all purchase orders
/purchase-orders/{id}Get a specific purchase order
/purchase-ordersCreate a new purchase order
/purchase-orders/{id}Update an existing purchase order
/purchase-orders/{id}Delete a draft purchase order
Status Values
draft, pending,confirmed, in_production,shipped, delivered,cancelled
Example Response
{
"data": [
{
"id": 1,
"po_number": "PO-2024-0001",
"status": "confirmed",
"supplier": {
"id": 1,
"name": "Premium Textiles Ltd"
},
"order_date": "2024-01-15",
"expected_delivery_date": "2024-02-15",
"ship_to": {
"name": "Main Warehouse",
"address": "789 Warehouse Blvd, Chicago, IL 60601"
},
"currency": "USD",
"subtotal": "5000.00",
"tax": "0.00",
"shipping": "250.00",
"total": "5250.00",
"line_items": [
{
"id": 1,
"style": {
"id": 1,
"style_code": "SS24-001",
"name": "Classic Cotton Tee"
},
"sku": "SS24-001-WHT-M",
"size": "M",
"color": "White",
"quantity": 100,
"unit_price": "22.50",
"total": "2250.00"
}
],
"notes": "Rush order - priority shipping required",
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T14:30:00Z"
}
]
}Inventory
/inventoryList inventory items
/inventory/{id}Get a specific inventory item
/inventory/{id}Update inventory levels
/inventory/bulk-updateBulk update inventory
List Inventory
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
style_id | integer | Filter by style |
location_id | integer | Filter by location |
low_stock | boolean | Filter low stock items |
Bulk Update Example
{
"updates": [
{
"sku": "SS24-001-WHT-M",
"location_id": 1,
"qty_on_hand": 175
},
{
"sku": "SS24-001-WHT-L",
"location_id": 1,
"qty_on_hand": 200
}
]
}Customers
/customersList all customers
/customers/{id}Get a specific customer
/customersCreate a new customer
/customers/{id}Update an existing customer
/customers/{id}Delete a customer
List Customers
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
type | string | Filter by type (wholesale, retail) |
Bill of Materials (BOM)
The BOM represents the list of components and materials used to manufacture a style.
/bomList all BOM items
/bom/{id}Get a specific BOM item
/bom/{id}Update a BOM item
/bom/{id}Delete a BOM item
/styles/{styleId}/bomGet BOM for a specific style
/styles/{styleId}/bomAdd component to style BOM
List BOM Items
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
style_id | integer | Filter by style ID |
component_id | integer | Filter by component ID |
Add BOM Item Example
{
"component_id": 123,
"quantity": 1.5,
"unit": "meter",
"placement": "Body",
"notes": "Main fabric"
}Points of Measure (POM)
Points of Measure define the measurement specifications for a style.
/pomList all POM items
/pom/{id}Get a specific POM item
/pom/{id}Update a POM item
/pom/{id}Delete a POM item
/styles/{styleId}/pomGet POM for a specific style
/styles/{styleId}/pomAdd POM item to style
List POM Items
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
style_id | integer | Filter by style ID |
Add POM Item Example
{
"name": "Chest Width",
"code": "A",
"tolerance_plus": 0.5,
"tolerance_minus": 0.5,
"measurements": {
"S": 48,
"M": 51,
"L": 54,
"XL": 57
}
}Variants & SKUs
Manage style variants (color/size combinations), SKUs, and colorways.
Variants
/styles/{id}/variantsGet style variants
/styles/{id}/variantsCreate a style variant
/styles/{id}/variants/{variantId}Update a variant
/styles/{id}/variants/{variantId}Delete a variant
SKUs
/styles/{id}/skusGet style SKUs
/styles/{id}/skusCreate a SKU
/styles/{id}/skus/{skuId}Update a SKU
/styles/{id}/skus/{skuId}Delete a SKU
Colorways
/styles/{id}/colorwaysGet style colorways
Create Variant Example
{
"color_id": 5,
"size_range_id": 2,
"is_active": true
}Sales Orders
/sales-ordersList all sales orders
/sales-orders/{id}Get a specific sales order
/sales-ordersCreate a new sales order
/sales-orders/{id}Update an existing sales order
/sales-orders/{id}Delete a sales order
Status Values
draft, pending,confirmed, processing,shipped, delivered,cancelled
Deliveries
Deliveries are read-only via the API.
/deliveriesList all deliveries
/deliveries/{id}Get a specific delivery
List Deliveries
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
status | string | Filter by status |
purchase_order_id | integer | Filter by PO |
/deliveries/by-delivery-id/{deliveryId}Get delivery by delivery ID (not internal ID)
Cancellations
Manage purchase order cancellation requests with approval workflows.
/cancellationsList all cancellations
/cancellations/{id}Get a specific cancellation
/cancellationsCreate a cancellation request
/cancellations/{id}Update a cancellation
/cancellations/{id}Delete a cancellation
/cancellations/{id}/approveApprove a cancellation
/cancellations/{id}/rejectReject a cancellation
Status Values
draft, pending,approved, rejected
List Cancellations
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
status | string | Filter by status |
purchase_order_id | integer | Filter by purchase order ID |
Returns
Manage purchase order returns for defective or incorrect goods.
/returnsList all returns
/returns/{id}Get a specific return
/returnsCreate a return
/returns/{id}Update a return
/returns/{id}Delete a return
/returns/{id}/confirmConfirm a return
Status Values
draft, confirmed,processing, completed
List Returns
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
status | string | Filter by status |
purchase_order_id | integer | Filter by purchase order ID |
Payments
Track payments against purchase orders.
/paymentsList all payments
/payments/{id}Get a specific payment
/paymentsCreate a payment
/payments/{id}Update a payment
/payments/{id}Delete a payment
/payments/summary/{poId}Get payment summary for a PO
List Payments
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
status | string | Filter by status |
purchase_order_id | integer | Filter by purchase order ID |
payment_method | string | Filter by payment method |
date_from | date | Filter payments from date |
date_to | date | Filter payments to date |
Create Payment Example
{
"purchase_order_id": 123,
"amount": 5000.00,
"currency": "USD",
"payment_method": "bank_transfer",
"payment_date": "2024-01-15",
"reference": "TT-2024-001",
"notes": "First payment - 30% deposit"
}Inventory Operations
Advanced inventory management operations including transfers, reservations, and check-ins.
/inventory/summaryGet inventory summary across all locations
/inventory/low-stockGet items below reorder threshold
/inventory/{id}/transactionsGet transaction history for an inventory item
/inventory/{id}/transferTransfer inventory between locations
/inventory/{id}/reserveReserve inventory for an order
/inventory/{id}/unreserveRelease reserved inventory
/inventory/{id}/check-inCheck in inventory from a delivery
Low Stock Query
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
threshold | integer | Low stock threshold (default: 10) |
Transfer Inventory Example
{
"to_location_id": 2,
"quantity": 50,
"notes": "Transfer to retail warehouse"
}Reserve Inventory Example
{
"quantity": 100,
"reference_type": "sales_order",
"reference_id": 456,
"notes": "Reserved for SO-2024-0050"
}Stock Takes
Manage physical inventory counts and reconciliation.
/stock-takesList all stock takes
/stock-takes/{id}Get a specific stock take
/stock-takesCreate a stock take
/stock-takes/{id}Update a stock take
/stock-takes/{id}Delete a stock take
/stock-takes/statusesGet available stock take statuses
/stock-takes/{id}/startStart a stock take
/stock-takes/{id}/completeComplete a stock take
/stock-takes/{id}/finalizeFinalize and apply stock take adjustments
/stock-takes/{id}/itemsGet stock take items
/stock-takes/{id}/itemsAdd item to stock take
Status Values
draft, in_progress,completed, cancelled
List Stock Takes
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
status | string | Filter by status |
location_id | integer | Filter by location ID |
Add Stock Take Item Example
{
"inventory_id": 123,
"counted_quantity": 95,
"notes": "5 units damaged"
}Tasks
Manage tasks and to-dos for team collaboration.
/tasksList all tasks
/tasks/{id}Get a specific task
/tasksCreate a task
/tasks/{id}Update a task
/tasks/{id}Delete a task
/tasks/{id}/completeMark task as completed
List Tasks
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
status | string | Filter by status (pending, in_progress, completed, cancelled) |
priority | string | Filter by priority (low, medium, high, urgent) |
assignee_id | integer | Filter by assignee user ID |
due_before | date | Filter tasks due before date |
due_after | date | Filter tasks due after date |
Create Task Example
{
"title": "Review fabric samples",
"description": "Check quality of cotton jersey samples from new supplier",
"priority": "high",
"due_date": "2024-01-20",
"assignee_id": 5,
"related_type": "style",
"related_id": 123
}Notes
Add notes and comments to any resource in the system.
/notesList all notes
/notes/{id}Get a specific note
/notesCreate a note
/notes/{id}Update a note
/notes/{id}Delete a note
List Notes
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
notable_type | string | Filter by resource type (style, component, supplier, customer, purchase_order, sales_order) |
notable_id | integer | Filter by resource ID |
Create Note Example
{
"notable_type": "style",
"notable_id": 123,
"content": "Customer requested wider fit for this style.",
"is_internal": false
}Projects
Organize styles and work into projects for better management.
/projectsList all projects
/projects/{id}Get a specific project
/projectsCreate a project
/projects/{id}Update a project
/projects/{id}Delete a project
List Projects
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
status | string | Filter by status |
Create Project Example
{
"name": "Fall 2024 Collection",
"description": "Main fall collection development",
"start_date": "2024-03-01",
"end_date": "2024-06-30",
"status": "active"
}Notifications
Access and manage user notifications.
/notificationsList notifications
/notifications/{id}Get a specific notification
/notifications/{id}Delete a notification
/notifications/{id}/readMark notification as read
/notifications/mark-all-readMark all notifications as read
/notifications/unread-countGet unread notification count
List Notifications
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
is_read | boolean | Filter by read status |
type | string | Filter by notification type |
Workflows
Automate processes with workflow rules and triggers.
/workflowsList all workflows
/workflows/{id}Get a specific workflow
/workflowsCreate a workflow
/workflows/{id}Update a workflow
/workflows/{id}Delete a workflow
/workflows/{id}/executeManually execute a workflow
/workflows/{id}/executionsGet workflow execution history
/workflows/templatesGet available workflow templates
List Workflows
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
is_active | boolean | Filter by active status |
trigger_type | string | Filter by trigger type |
Execute Workflow Example
{
"context": {
"style_id": 123,
"action": "status_change"
}
}Supplier Scoring
Access supplier performance scores and metrics.
/suppliers/{id}/scoreGet supplier overall score
/suppliers/{id}/metricsGet detailed supplier metrics
/suppliers/rankingsGet supplier rankings
Supplier Metrics Query
| Parameter | Type | Description |
|---|---|---|
period | string | Metrics period: 30d, 90d, 1y, all (default: 90d) |
Supplier Rankings Query
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
sort_by | string | Sort by: overall_score, quality_score, delivery_score, communication_score |
sort_dir | string | Sort direction: asc, desc |
Example Response
{
"data": {
"supplier_id": 1,
"overall_score": 4.2,
"quality_score": 4.5,
"delivery_score": 3.8,
"communication_score": 4.3,
"total_orders": 45,
"on_time_delivery_rate": 0.85,
"defect_rate": 0.02,
"average_lead_time_days": 21
}
}Lookups
Access reference data for use in forms and integrations.
/lookups/size-rangesGet available size ranges
/lookups/currenciesGet supported currencies
/lookups/component-categoriesGet component categories
/lookups/unitsGet units of measure
Example Response - Currencies
{
"success": true,
"data": [
{ "code": "USD", "name": "US Dollar", "symbol": "$" },
{ "code": "EUR", "name": "Euro", "symbol": "€" },
{ "code": "GBP", "name": "British Pound", "symbol": "£" },
{ "code": "AUD", "name": "Australian Dollar", "symbol": "A$" }
]
}API Keys
Manage API keys programmatically (requires api_keys:write scope).
/api-keysList all API keys
/api-keys/{id}Get a specific API key
/api-keys/{id}/usageGet API key usage statistics
/api-keys/{id}/revokeRevoke an API key
Usage Statistics Response
{
"data": {
"api_key_id": 1,
"total_requests": 15420,
"requests_today": 342,
"requests_this_month": 8750,
"last_used_at": "2024-01-15T14:30:00Z",
"rate_limit_hits": 3
}
}Webhooks
Webhooks allow you to receive real-time notifications when events occur in Kobo PLM. When you configure a webhook, Kobo PLM will send an HTTP POST request to your specified URL whenever the subscribed events occur.
Available Events
Style Events
| Event | Description |
|---|---|
style.created | A new style was created |
style.updated | A style was updated |
style.deleted | A style was deleted |
style.status_changed | A style's status changed |
Component Events
| Event | Description |
|---|---|
component.created | A new component was created |
component.updated | A component was updated |
component.deleted | A component was deleted |
Supplier Events
| Event | Description |
|---|---|
supplier.created | A new supplier was created |
supplier.updated | A supplier was updated |
supplier.deleted | A supplier was deleted |
Purchase Order Events
| Event | Description |
|---|---|
purchase_order.created | A new PO was created |
purchase_order.updated | A PO was updated |
purchase_order.status_changed | A PO's status changed |
purchase_order.confirmed | A PO was confirmed |
purchase_order.cancelled | A PO was cancelled |
Inventory Events
| Event | Description |
|---|---|
inventory.updated | Inventory levels changed |
inventory.low_stock | Inventory fell below reorder point |
Customer Events
| Event | Description |
|---|---|
customer.created | A new customer was created |
customer.updated | A customer was updated |
customer.deleted | A customer was deleted |
Sales Order Events
| Event | Description |
|---|---|
sales_order.created | A new sales order was created |
sales_order.updated | A sales order was updated |
sales_order.status_changed | A sales order's status changed |
Delivery Events
| Event | Description |
|---|---|
delivery.created | A new delivery was created |
delivery.checked_in | A delivery was received |
delivery.status_changed | A delivery's status changed |
BOM Events
| Event | Description |
|---|---|
bom.created | A BOM item was added |
bom.updated | A BOM item was updated |
bom.deleted | A BOM item was removed |
Task Events
| Event | Description |
|---|---|
task.created | A new task was created |
task.updated | A task was updated |
task.completed | A task was marked complete |
task.assigned | A task was assigned |
Project Events
| Event | Description |
|---|---|
project.created | A new project was created |
project.updated | A project was updated |
project.status_changed | A project's status changed |
Payment Events
| Event | Description |
|---|---|
payment.created | A new payment was recorded |
payment.updated | A payment was updated |
Stock Take Events
| Event | Description |
|---|---|
stock_take.created | A stock take was created |
stock_take.started | A stock take was started |
stock_take.completed | A stock take was completed |
stock_take.finalized | A stock take was finalized |
Workflow Events
| Event | Description |
|---|---|
workflow.executed | A workflow was executed |
workflow.failed | A workflow execution failed |
Webhook Payload
All webhooks send a JSON payload with the following structure:
{
"event": "style.updated",
"created_at": "2024-01-15T14:30:00Z",
"data": {
"id": 1,
"type": "Style",
"attributes": {
"id": 1,
"style_code": "SS24-001",
"name": "Classic Cotton Tee",
"status": "active"
}
},
"meta": {
"api_version": "v1",
"change": {
"field": "status",
"previous_value": "development",
"new_value": "active"
}
}
}Webhook Headers
| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | KOBO-PLM-Webhooks/1.0 |
X-Webhook-Event | Event type (e.g., style.updated) |
X-Webhook-Event-Id | Unique event ID (UUID) |
X-Webhook-Timestamp | Unix timestamp |
X-Webhook-Signature | HMAC-SHA256 signature |
Signature Verification
To verify that a webhook came from Kobo PLM, validate the signature:
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, timestamp, secret) {
const signedPayload = `${timestamp}.${payload}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}
// In your webhook handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const timestamp = req.headers['x-webhook-timestamp'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, timestamp, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
console.log('Received event:', req.body.event);
res.status(200).send('OK');
});import hmac
import hashlib
def verify_webhook_signature(payload, signature, timestamp, secret):
signed_payload = f"{timestamp}.{payload}"
expected_signature = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(
signature,
f"sha256={expected_signature}"
)function verifyWebhookSignature($payload, $signature, $timestamp, $secret) {
$signedPayload = "{$timestamp}.{$payload}";
$expectedSignature = 'sha256=' . hash_hmac('sha256', $signedPayload, $secret);
return hash_equals($expectedSignature, $signature);
}Retry Policy
Failed webhook deliveries are automatically retried with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
Managing Webhooks
/webhooks/eventsList available webhook events
/webhooksList all webhooks
/webhooksCreate a new webhook
/webhooks/{id}Get a specific webhook
/webhooks/{id}Update a webhook
/webhooks/{id}Delete a webhook
/webhooks/{id}/rotate-secretRotate webhook signing secret
/webhooks/{id}/testSend a test event
/webhooks/{id}/resetReset webhook failure count
/webhooks/{id}/statsGet webhook delivery statistics
/webhooks/{id}/deliveriesGet delivery history
/webhooks/{id}/deliveries/{deliveryId}/retryRetry a failed delivery
Create Webhook
{
"name": "ERP Sync",
"url": "https://your-system.com/webhooks/kobo",
"events": ["style.created", "style.updated", "inventory.updated"],
"is_active": true
}Best Practices
Incremental Sync
For efficient data synchronization, use the updated_since filter:
# Store the last sync timestamp
LAST_SYNC="2024-01-15T00:00:00Z"
# Fetch only changed records
curl "https://api.kobolabs.io/api/v1/styles?updated_since=$LAST_SYNC" \
-H "X-API-Key: your_api_key"Pagination
Always paginate through results to avoid timeouts:
async function getAllStyles(apiKey) {
let allStyles = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await fetch(
`https://api.kobolabs.io/api/v1/styles?page=${page}&per_page=100`,
{ headers: { 'X-API-Key': apiKey } }
);
const data = await response.json();
allStyles = allStyles.concat(data.data);
hasMore = page < data.meta.last_page;
page++;
}
return allStyles;
}Rate Limit Handling
Implement exponential backoff when rate limited:
async function apiRequest(url, options, retries = 3) {
for (let i = 0; i < retries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
await sleep(retryAfter * 1000 * Math.pow(2, i));
continue;
}
return response;
}
throw new Error('Rate limit exceeded after retries');
}Idempotency
Use idempotency keys for create operations to prevent duplicates:
curl -X POST "https://api.kobolabs.io/api/v1/purchase-orders" \
-H "X-API-Key: your_api_key" \
-H "Idempotency-Key: unique-request-id-12345" \
-H "Content-Type: application/json" \
-d '{"supplier_id": 1, ...}'SDK & Tools
Official Libraries
- Coming Soon: JavaScript/TypeScript SDK
- Coming Soon: Python SDK
- Coming Soon: PHP SDK
OpenAPI Specification
Download our OpenAPI 3.0 specification for use with code generators:
Postman Collection
Import our Postman collection to quickly test the API:
Support
- Email: api-support@koboplm.com
- Documentation: https://docs.koboplm.com
- Status Page: https://status.koboplm.com
Last updated: December 2025