Kōbō PLM API Documentation
The Kōbō 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.
If your HTTP client prefers the standard Authorization header,Authorization: Bearer your_api_key is also accepted. Always send Accept: application/json so errors come back as JSON — validation failures return 422 with anerrors object.
curl -X GET "https://api.kobolabs.io/api/v1/styles" \
-H "X-API-Key: your_api_key_here" \
-H "Accept: application/json" \
-H "Content-Type: application/json"
# Or with the Authorization header:
curl -X GET "https://api.kobolabs.io/api/v1/styles" \
-H "Authorization: Bearer your_api_key_here" \
-H "Accept: application/json"Getting an API Key
- Log in to Kōbō 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 names must match exactly — note that some use a hyphen (purchase-orders:read, sales-orders:write,stock-takes:read) and others an underscore (credit_notes:read, sample_requests:write). Every scope a V1 route checks can be granted to a key; a request without the scope returns403 with error_code: insufficient_scope and the required_scopes it needed.
| Scope | Description |
|---|---|
* | Complete access to all API resources |
styles:read | View styles and their details |
styles:write | Create, update, and delete styles |
components:read | View components and materials |
components:write | Create, update, and delete components |
suppliers:read | View supplier information |
suppliers:write | Create, update, and delete suppliers |
customers:read | View customer information |
customers:write | Create, update, and delete customers |
purchase-orders:read | View purchase orders |
purchase-orders:write | Create, update, and manage purchase orders |
sales-orders:read | View sales orders |
sales-orders:write | Create, update, and manage sales orders |
inventory:read | View inventory levels and locations |
inventory:write | Adjust inventory levels |
deliveries:read | View delivery information |
deliveries:write | Create and manage deliveries |
api-keys:read | View API key information |
api-keys:write | Manage API keys |
webhooks:read | View webhook configurations |
webhooks:write | Manage webhook configurations |
bom:read | View bill of materials for styles |
bom:write | Create, update, and delete BOM entries |
pom:read | View points of measure for styles |
pom:write | Create, update, and delete POM entries |
sample_requests:read | View sample requests, their items and receipts |
sample_requests:write | Raise, update and cancel sample requests; record receipts, approvals and dispositions |
tasks:read | View tasks and assignments |
tasks:write | Create, update, and manage tasks |
notes:read | View notes and linked entities |
notes:write | Create, update, and delete notes |
projects:read | View projects and their tasks |
projects:write | Create, update, and delete projects |
cutting-tickets:read | View cutting tickets |
cutting-tickets:write | Create, issue and cancel cutting tickets |
cancellations:read | View PO cancellations |
cancellations:write | Create and manage PO cancellations |
returns:read | View PO returns |
returns:write | Create and manage PO returns |
payments:read | View PO payments |
payments:write | Record and manage PO payments |
stock-takes:read | View stock take sessions and counts |
stock-takes:write | Create, manage stock take sessions and record counts |
workflows:read | View workflow definitions and executions |
workflows:write | Create, manage, and execute workflows |
supplier-scores:read | View supplier scores, rankings, and metrics |
supplier-scores:write | Calculate scores and record performance metrics |
size-ranges:read | View size range configurations |
currencies:read | View currency configurations |
lookups:read | View reference data: style categories, style tags, markets, sales channels, payment terms, incoterms, tax rates |
files:read | List and download files/attachments on styles, orders, components and more |
files:write | Upload, update and delete files/attachments |
notifications:read | View notifications |
notifications:write | Send and manage notifications |
materials:read | View the materials/fabrics catalog |
materials:write | Create, update, and delete tenant-custom materials |
production-batches:read | View production batches and their purchase orders |
production-batches:write | Create, commit, and cancel production batches |
pricing:read | View style and component pricing |
pricing:write | Set style/component pricing and market pricing |
library:read | View library groups, POM diagrams/templates, and issue templates |
library:write | Create, update, and delete library items |
comments:read | View style comments |
comments:write | Create, update, and delete style comments |
compliance:read | View style and component compliance / DPP data |
compliance:write | Update style and component compliance / DPP data |
budgets:read | View season budgets and tracking entries |
budgets:write | Manage budgets and record tracking entries |
reports:read | View scheduled reports and executions |
reports:write | Create, manage, and run scheduled reports |
activities:read | View the activity / audit log |
seasons:read | View seasons and their drops (season deliveries) |
seasons:write | Create, update, reorder and delete seasons and their drops |
milestones:read | View milestones, critical-path templates and the T&A board |
milestones:write | Create, update, sign off and delete milestones and dependencies; manage and apply critical-path templates |
exchange_rates:read | View dated sales exchange rates |
exchange_rates:write | Create, update and delete sales exchange rates |
showroom:read | View showroom events, appointments, attendees and buyer/customer selections |
showroom:write | Book, update and move appointments through their statuses; manage attendees |
merch:read | View markdown batches, allocation runs and stock holds |
merch:write | Draft and apply markdown batches, run allocations, hold and release stock |
shipments:read | View inbound shipments / ASN (POs, deliveries, cartons, tracking), sales shipments, carrier accounts and shipping rules |
shipments:write | Attach, detach and move purchase orders on inbound shipments, manage sales shipments and shipping rules |
colors:read | View colours |
colors:write | Create, update and delete colours |
component-reservations:read | View component reservations |
component-reservations:write | Create, update and delete component reservations |
component_sourcing:read | View component sourcing |
component_sourcing:write | Create, update and delete component sourcing |
credit_notes:read | View credit notes |
credit_notes:write | Create, update and delete credit notes |
delivery_notes:read | View delivery notes |
delivery_notes:write | Create, update and delete delivery notes |
goods_receipts:read | View goods receipts |
goods_receipts:write | Create, update and delete goods receipts |
invoices:read | View invoices |
invoices:write | Create, update and delete invoices |
labdips:read | View lab dips |
labdips:write | Create, update and delete lab dips |
library-constructions:read | View library constructions |
library-constructions:write | Create, update and delete library constructions |
linesheets:read | View line sheets |
linesheets:write | Create, update and delete line sheets |
locations:read | View locations |
locations:write | Create, update and delete locations |
moodboards:read | View moodboards |
moodboards:write | Create, update and delete moodboards |
order_confirmations:read | View order confirmations |
order_confirmations:write | Create, update and delete order confirmations |
packing_lists:read | View packing lists |
packing_lists:write | Create, update and delete packing lists |
pick_tickets:read | View pick tickets |
pick_tickets:write | Create, update and delete pick tickets |
quality_control:read | View quality control |
quality_control:write | Create, update and delete quality control |
quotations:read | View quotations |
quotations:write | Create, update and delete quotations |
range_plans:read | View range plans |
range_plans:write | Create, update and delete range plans |
sales-cancellations:read | View sales cancellations |
sales-cancellations:write | Create, update and delete sales cancellations |
sales-returns:read | View sales returns |
sales-returns:write | Create, update and delete sales returns |
sample_reviews:read | View sample reviews |
sample_reviews:write | Create, update and delete sample reviews |
tech_packs:read | View tech packs |
tech_packs:write | Create, update and delete tech packs |
Rate Limiting
Requests are limited at two levels, and the first limit reached wins:
| Limit | Allowance |
|---|---|
| Per API key | The key’s own rate_limit per minute (100 by default) |
| Per company, per minute | 300 requests, summed across all of the company’s keys |
| Per company, per day | 20,000 requests, summed across all of the company’s keys |
The company limits mean extra keys do not multiply throughput. Rate limit headers are included in every response (they describe the key’s per-minute window):
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699574400429 Too Many Requests witherror_code: rate_limit_exceeded and aRetry-After header (seconds). Wait at least that long, then back off exponentially. Some actions have their own tighter limits — see Limits & Errors.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"Including Relations
More than forty endpoints can return related records inline with?include=, so you can avoid a second round trip for each row. Separate several with commas, and use a dot for one level of nesting.
# Inventory rows with the style and location attached
curl "https://api.kobolabs.io/api/v1/style-inventory?include=style,location" \
-H "X-API-Key: your_api_key"Each endpoint publishes its own allow-list. Asking for something that is not on it returns a 422 naming the relations that are valid, so you can discover them without guessing. A relation only appears when you ask for it.
| Parameter | Type | Description |
|---|---|---|
include | string | Comma-separated relations, e.g. style,location |
Two limits keep responses predictable: at most five relations per request, and at most one level of nesting (style.season is fine,style.season.brand is not).
What each endpoint can include
Relations not listed here are not includable. Where a relation has no public representation of its own it comes back as a compact summary (id, name/number and status) rather than the whole record. Includes are tenant-checked: a related record that belongs to another company is never returned.
| Endpoint | Relations you can include |
|---|---|
/budgets | trackingEntries |
/colors | labdips files components styles |
/component-inventory | style location component reservations variant |
/component-reservations | inventory |
/component-sourcing | files |
/components | componentPricing inventories purchaseOrders primaryImageFile boms componentUnits files variants sourcingRequests |
/credit-notes | styles |
/customers | salesOrders addresses contacts defaultBillingAddress defaultShippingAddress primaryContact invoices masterCustomer linkedCustomers accessibleStyles brands |
/deliveries | purchaseOrder brandLocation contact items parcelShipment discrepancies |
/files | style component supplier customer note issueTemplate section styleSection purchaseOrder salesOrder qcInspection |
/goods-receipts | supplier |
/inventory | style location component reservations variant |
/invoices | salesOrder customer items payments pickTicket shipment depositInvoice balanceInvoices |
/labdips | styles |
/library-issue-templates | files |
/library-pom-diagrams | styles |
/milestones | season |
/note-categories | notes |
/notes | seasons salesOrders attachments |
/packing-lists | fromLocation toLocation items |
/parcel-shipments | supplier deliveries |
/pick-tickets | styles |
/production-batches | sourceSalesOrder |
/projects | season sharedWithSuppliers |
/purchase-orders | cancellations productionBatch returns creditNotes files statusHistory bankAccount billToLocation incoterm checkIns styleCheckIns tags |
/quality-control | attachments |
/quotations | supplier styles priceHistory valueAddedServices |
/range-plans | season rangePlanStyles market |
/sales-orders | salesStyles brandLocation productionBatch files payments salesOrderPayments pickTickets deliveryNotes creditNotes returns cancellations orderConfirmation shippingMethod market statusHistory |
/sales-shipments | salesOrder pickTicket items invoice |
/sample-requests | style reviews |
/sample-reviews | style sampleRequest |
/season-deliveries | season |
/seasons | suppliers budgets activeBudget drops |
/style-compliance | style |
/style-inventory | style location component reservations variant |
/style-pricing | style budgetTracking |
/styles | season supplier notes boms labdips sections sampleReviews latestSampleReview stylePages salesOrders creditNotes stylePricing pickTickets inventory purchaseOrderItems pomDiagram tasks compliance referenceStyles brand shopifyLinks styleWorkflows seasonDelivery sourceStyle variant |
/styles/{styleId}/file-sections | files |
/styles/{styleId}/pom | diagram |
/styles/{styleId}/pricing-scenarios | quotationRequest |
/suppliers | styles locations purchaseOrders brands components performanceMetrics score users |
/tasks | status taskLabel project assignedTo assignedBy milestones customer |
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."]
}
}Limits & Errors
Besides the request rate limits, a few actions carry their own guards. Every limit answers with a JSON error that has an error_code; throttles answer 429 with a Retry-After header and a retry_after field in seconds.
| Area | Limit | When exceeded |
|---|---|---|
| Requests | Key’s rate_limit/min; 300/min and 20,000/day per company | 429 rate_limit_exceeded |
| Document send | 1–5 recipients; subject ≤ 191 chars; message ≤ 2,000 chars | 422 validation_error |
| Document send recipients | Each must be a user of your company or a contact of the document’s customer or supplier | 422 per-recipient error under errors.recipients.N |
| Document send throttle | 3 sends per document per 15 minutes; 50 sends per key per day | 429 rate_limit_exceeded |
| File uploads | Allowed extensions only; 25 MB per file; 500 uploads per company per day | 422 (type/size) or 429 upload_limit_exceeded |
| Webhooks | HTTPS public URL only; at most 10 webhooks per company | 422 |
| Scheduled reports | ≤ 10 recipients; body ≤ 2,000 chars; custom cron at most hourly; run-now / send-test once per 15 min; send-test only to company users | 422 / 429 |
| Customer portal invitations | 20 per key per day | 429 |
| Showroom booking mail | Confirmation emails from appointment actions: 50 per key per day | 429 |
Document send
Every POST .../send endpoint takes the same body and emails the same PDF the app sends. Kōbō never emails anyone outside your company and the document’s own customer or supplier contacts.
| Parameter | Type | Description |
|---|---|---|
recipientsRequired | string[] | 1–5 email addresses, no duplicates |
subject | string | Optional subject (max 191 characters) |
message | string | Optional message body (max 2,000 characters) |
curl -X POST "https://api.kobolabs.io/api/v1/invoices/412/send" \
-H "X-API-Key: your_api_key" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"recipients": ["accounts@buyer-store.com"], "subject": "Invoice INV-0412", "message": "Please find your invoice attached."}'
# 422 when a recipient is not allowed
{
"success": false,
"message": "One or more recipients are not allowed for this document",
"error_code": "validation_error",
"errors": {
"recipients.0": ["Recipients must be users of your company or contacts of this document's customer or supplier."]
}
}File uploads
Multipart uploads (files, QC photos, labdip images and other attachments) accept up to 25 MB per file and these extensions: jpg jpeg png gif webp heic tif tiff bmp pdf doc docx xls xlsx ppt pptx csv txt rtf zip ai eps psd dxf dwg. Executables, scripts, HTML and SVG are refused. A company can upload 500 files a day through the API; past that you get 429 with upload_limit_exceeded.
Webhook URLs
Webhook URLs must use https and resolve to a public address. Private, loopback, link-local and cloud-metadata hosts are rejected when you save the webhook and checked again at delivery time. Redirects are not followed and your endpoint’s response body is not echoed back in delivery logs. A company can have at most 10 webhooks.
Common error codes
| Status | Meaning |
|---|---|
| 403 | insufficient_scope — the key lacks a scope; the response lists required_scopes |
| 409 | The record’s state refuses the action — e.g. a locked budget, a delivery already checked in, an invalid status transition |
| 422 | Validation failed, or a referenced id belongs to another company; errors names each field |
| 429 | A rate limit or action throttle; honour Retry-After |
Changes in This Release
The October 2026 release adds document downloads and sending, critical path, seasons and drops, exchange rates, sample requests, labdip swatches, quote award, inbound shipments, purchase-order workflows, partial invoicing, showroom and merchandising endpoints, about 120 new response fields and many new ?include= relations. Most of it is additive. These behaviour changes may need a change on your side:
| Endpoint | What changed |
|---|---|
POST /linesheets/{id}/generate | Now renders the real linesheet and returns the PDF itself (Content-Type: application/pdf) instead of a JSON “queued” message. |
POST /linesheets/{id}/share | Now creates a real share link (token + public URL, optional password, expiry and ordering rights) and needs linesheets:write instead of linesheets:read. It never sends email. |
POST /range-plans/{id}/styles/{styleId}/convert | Now converts the card into a full style (it used to return 501). It creates styles, so the key needs both range_plans:write and styles:write. |
POST /deliveries/{id}/receive | Now performs a real check-in: it moves stock into the location, creates the check-in, relieves on-order quantities, records sample receipts and discrepancies. Receiving a delivery that is already checked in returns 409. |
PUT /budgets/{id} and allocation writes | A locked budget now refuses changes with 409. Use the new lock/unlock endpoints. |
| Quotation status changes | Go through the same decision rules as the app; use PATCH /quotations/{id}/status to record a decision with a brand note. |
| Packing-list and labdip status | Only valid transitions are accepted; others return 409 or 422. |
| Rate limits | Company-wide limits (300/min, 20,000/day) apply across all keys, on top of each key’s own limit. |
| Webhooks, uploads, scheduled reports | New guards — see Limits & Errors. |
| Fixed fields | Supplier metrics and score, delivery contact name/email, tax rate, brand location name, QC version name and lab-test / certification file names used to come back null; they now carry values. Includes no longer return duplicate keys. |
sample_requests:*, milestones:*, exchange_rates:*, showroom:*, merch:* and seasons:write are new, and 44 scopes that routes already checked (invoices, quotations, labdips, tech packs, QC and more) can now be granted to a key. Existing keys keep the scopes they had; edit a key to add new ones.Styles
Styles represent your products/designs in Kōbō 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
/styles/{id}/duplicateDuplicate a style
/styles/{id}/restoreRestore an archived style
/styles/exportExport styles as CSV
/styles/trashedList soft-deleted styles
/styles/{id}/forcePermanently delete a style
/styles/{id}/deletion-impactPreview the impact of deleting a style (safety pre-check before delete)
/styles/importImport styles from CSV or JSON
/styles/bulk-actionsBulk update or delete up to 100 styles
/styles/{id}/collectionsSet the collections a style belongs to
/styles/{id}/production-statusUpdate a style's production status
/styles/{id}/production-readinessCheck whether a style is ready for production
/styles/{id}/production-historyProduction status transition history
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 |
brand_id | integer | Filter by brand (company-wide keys; each style returns its brand as { id, name }) |
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.googleapis.com/kobo-system-files/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
/components/{id}/duplicateDuplicate a component
/components/exportExport components as CSV
/components/trashedList soft-deleted components
/components/{id}/restoreRestore a soft-deleted component
/components/{id}/forcePermanently delete a trashed component
/components/importImport components from CSV
/components/{id}/transactionsInventory transactions for 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 |
Shared Components
A component either belongs to one brand or is shared across every brand in the company. Send "shared": true (and no brand_id) onPOST /components or per row on POST /components/import to create a shared component; only a company-wide API key can. With a company-wide key and more than one brand, a brand-owned component needs brand_id. Every component returnsshared (boolean) and brand ({ id, name }, or null when shared). A brand-scoped key lists its brand's components plus the shared ones, and can read shared components but not change them (403).
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
/suppliers/exportExport suppliers as CSV
/suppliers/{id}/componentsList a supplier's components
/suppliers/{id}/stylesList styles sourced from a supplier
/suppliers/{id}/purchase-ordersList a supplier's purchase orders
/suppliers/{id}/contactsList supplier contacts
/suppliers/{id}/contactsAdd a supplier contact
/suppliers/{id}/contacts/{contactId}Update a supplier contact
/suppliers/{id}/contacts/{contactId}Delete a supplier contact
/suppliers/{supplier}/lifecycle-statusMove a supplier through its per-brand lifecycle (prospect, pending_approval, approved, active, blocked)
Update Lifecycle Status
| Parameter | Type | Description |
|---|---|---|
statusRequired | string | prospect, pending_approval, approved, active or blocked |
note | string | Why (kept on the activity entry) |
brand_id | integer | Brand whose relationship changes; required for a company-wide key |
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"
}
]
}Supplier Certifications
Track a supplier’s compliance certifications — BSCI, OEKO-TEX, GOTS, ISO and more — with issue and expiry dates. Each certification carries a derived expiry state (current, expiring, expired, no_expiry) computed from its dates, and the list can be filtered by type, status or expiry state.
/suppliers/{supplierId}/certificationsList a supplier’s certifications
/suppliers/{supplierId}/certificationsRecord a certification
/supplier-certifications/{id}Get a certification
/supplier-certifications/{id}Update a certification
/supplier-certifications/{id}Partially update a certification
/supplier-certifications/{id}Delete a certification
Supplier File Sections
The collapsible sections that group uploads on a supplier. Files themselves are managed through the Files endpoints using ?supplier_id=; these are the structures they hang in. Deleting a section never deletes its files — they are simply unfiled.
/suppliers/{supplierId}/file-sectionsList a supplier’s file sections
/suppliers/{supplierId}/file-sectionsCreate a file section
/suppliers/{supplierId}/file-sections/orderReorder file sections
/supplier-file-sections/{id}Get a file section
/supplier-file-sections/{id}Update a file section
/supplier-file-sections/{id}Partially update a file section
/supplier-file-sections/{id}Delete a file section
Purchase Orders
/purchase-ordersList all purchase orders
/purchase-orders/{id}Get a specific purchase order
/purchase-ordersCreate a new purchase order (currency defaults to the supplier's; every line is in the PO's currency)
/purchase-orders/{id}Update an existing purchase order
/purchase-orders/{id}Delete a draft purchase order
/purchase-orders/exportExport purchase orders as CSV
/purchase-orders/statusesList available purchase order statuses
/purchase-orders/{id}/itemsList purchase order line items
/purchase-orders/{id}/itemsAdd a line item to a purchase order (unit_price defaults to the supplier price; a price in another currency is converted, 422 if no exchange rate)
/purchase-orders/{id}/items/{itemId}Update a purchase order line item
/purchase-orders/{id}/items/{itemId}Remove a purchase order line item
/purchase-orders/{id}/confirmConfirm a purchase order
/purchase-orders/{id}/unconfirmRevert a confirmed purchase order to draft
/purchase-orders/{id}/cancelCancel a purchase order
/purchase-orders/{id}/check-in-quantitiesCheck-in quantities received per item
/purchase-orders/{id}/pdfDownload the purchase order as a PDF (?sections= narrows it)
/purchase-orders/{id}/sendEmail the purchase order PDF (guarded send; see Documents)
Purchase orders now also expose supplier acknowledgement (supplier_acknowledged_at, supplier_ack_status, supplier_ack_note), client approval and payment-request fields, payment_waived, bill_to_location_id, pack_per_destination and original ship/delivery dates. bill_to_location_id and payment_waived are writable.
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
/component-inventory/bulk-updateBulk update inventory
/inventory/exportExport inventory as CSV
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
/customers/exportExport customers as CSV
/customers/{id}/outstanding-invoicesGet outstanding invoices for a customer
/customers/{id}/overviewGet customer overview/summary
/customers/{id}/sales-ordersList a customer's sales orders
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) |
Customer Addresses
Manage shipping, billing, and other addresses for customers.
/customers/{customerId}/addressesList all addresses for a customer
/customers/{customerId}/addresses/{id}Get a specific customer address
/customers/{customerId}/addressesCreate a new customer address
/customers/{customerId}/addresses/{id}Update an existing customer address
/customers/{customerId}/addresses/{id}Delete a customer address
/customers/{customerId}/addresses/{id}/set-defaultSet an address as the customer's default
Create Address
| Parameter | Type | Description |
|---|---|---|
address_typeRequired | string | Type of address (e.g. shipping, billing) |
address_name | string | Name/label for the address |
is_default | boolean | Whether this is the default address |
street_address | string | Street address |
city | string | City |
state | string | State or province |
country | string | Country |
postal_code | string | Postal/ZIP code |
contact_name | string | Contact person name |
contact_email | string | Contact email |
contact_phone | string | Contact phone number |
notes | string | Additional notes |
Example Response
{
"data": {
"id": 1,
"address_type": "shipping",
"address_name": "Main Warehouse",
"is_default": true,
"street_address": "456 Commerce Blvd",
"city": "New York",
"state": "NY",
"country": "US",
"postal_code": "10001",
"contact_name": "Jane Doe",
"contact_email": "jane@example.com",
"contact_phone": "+1-555-0200",
"notes": null,
"created_at": "2024-01-10T09:00:00Z",
"updated_at": "2024-01-10T09:00:00Z"
}
}Customer Contacts
Manage contact people associated with customers.
/customers/{customerId}/contactsList all contacts for a customer
/customers/{customerId}/contacts/{id}Get a specific customer contact
/customers/{customerId}/contactsCreate a new customer contact
/customers/{customerId}/contacts/{id}Update an existing customer contact
/customers/{customerId}/contacts/{id}Delete a customer contact
/customers/{customerId}/contacts/{id}/set-primarySet a contact as the customer's primary contact
Create Contact
| Parameter | Type | Description |
|---|---|---|
nameRequired | string | Contact person name |
email | string | Contact email address |
phone | string | Contact phone number |
role | string | Contact role (e.g. buyer, manager) |
is_primary | boolean | Whether this is the primary contact |
notes | string | Additional notes |
Example Response
{
"data": {
"id": 1,
"name": "Sarah Johnson",
"email": "sarah@example.com",
"phone": "+1-555-0300",
"role": "Buyer",
"is_primary": true,
"notes": null,
"created_at": "2024-01-10T09:00:00Z",
"updated_at": "2024-01-10T09:00:00Z"
}
}Customer Portal & Access
Customer actions, customer portal invitations and per-style access control for portal users.
Customer Actions
/customers/{customer}/copyDuplicate a customer (with addresses, contacts, and brand links)
/customers/{customer}/invoicesList the full invoice history for a customer
/customers/{customer}/stylesList styles associated with a customer through their sales orders
Portal Access
/customers/{customer}/portal-accessList customer portal users and pending invitations
/customers/{customer}/portal-invitationsInvite a user to the customer portal
/customers/{customer}/portal-invitations/{invitation}Cancel a pending portal invitation
/customers/{customer}/portal-access/{user}Remove a user's customer portal access
Style Access
/customers/{customer}/style-accessList style access grants for a customer
/customers/{customer}/style-accessGrant (or update) access to one or more styles
/customers/{customer}/style-access/{access}Update a single style access grant (access type + scheduling window)
/customers/{customer}/style-access/{access}Revoke a single style access grant
/customers/{customer}/style-access/bulk-revokeBulk revoke style access grants by ID
Customer File Sections
The collapsible sections that group uploads on a customer. Files are managed through the Files endpoints using ?customer_id=. Deleting a section never deletes its files — they are simply unfiled.
/customers/{customerId}/file-sectionsList a customer’s file sections
/customers/{customerId}/file-sectionsCreate a file section
/customers/{customerId}/file-sections/orderReorder file sections
/customer-file-sections/{id}Get a file section
/customer-file-sections/{id}Update a file section
/customer-file-sections/{id}Partially update a file section
/customer-file-sections/{id}Delete a file section
Colors
Manage the color library used across styles and products.
/colorsList all colors
/colors/{id}Get a specific color
/colors/{id}/usageUsage summary for a color (safe-delete pre-check)
/colorsCreate a new color
/colors/{id}Update an existing color
/colors/{id}Delete a color
List Colors
| Parameter | Type | Description |
|---|---|---|
search | string | Search by color name |
group_id | integer | Filter by color group |
per_page | integer | Items per page (max 100) |
sort_by | string | Sort field |
sort_dir | string | Sort direction (asc, desc) |
Create Color
| Parameter | Type | Description |
|---|---|---|
colour_nameRequired | string | Color name |
hex | string | Hex color code (e.g. #FF5733) |
pantone_ref | string | Pantone reference code |
starred | boolean | Whether the color is starred/favorited |
group_id | integer | Color group ID |
Example Response
{
"data": [
{
"id": 1,
"colour_name": "Midnight Blue",
"hex": "#191970",
"pantone_ref": "19-3933 TCX",
"starred": false,
"group": {
"id": 2,
"name": "Blues"
},
"created_at": "2024-01-10T09:00:00Z",
"updated_at": "2024-01-10T09:00:00Z"
}
],
"meta": {
"current_page": 1,
"total": 48
}
}Seasons
Seasons organise styles and collections. Writes use the same rules as the app (for example a season still in use cannot be deleted) and need seasons:write.
/seasonsList all seasons
/seasons/{id}Get a specific season (include=drops for its season deliveries)
/seasonsCreate a season
/seasons/{id}Update a season (PATCH also accepted)
/seasons/{id}Delete a season (refused while it is in use)
/seasons/{id}/reorderMove a season to a new position (body: position, 1-based)
List Seasons
| Parameter | Type | Description |
|---|---|---|
search | string | Search by season name |
per_page | integer | Items per page (max 100) |
sort_by | string | Sort field |
sort_dir | string | Sort direction (asc, desc) |
Example Response
{
"data": [
{
"id": 1,
"season_name": "Spring/Summer 2025",
"created_at": "2024-01-05T08:00:00Z",
"updated_at": "2024-01-05T08:00:00Z"
}
],
"meta": {
"current_page": 1,
"total": 12
}
}Drops (Season Deliveries)
A drop is a dated delivery window within a season. Styles point at one with season_delivery_id and critical-path dates can follow each drop’s launch. Read with seasons:read, write with seasons:write.
/season-deliveriesList drops (filter by season_id)
/season-deliveriesCreate a drop
/season-deliveries/{id}Get a drop
/season-deliveries/{id}Update a drop (PATCH also accepted)
/season-deliveries/{id}Delete a drop
List Drops
| Parameter | Type | Description |
|---|---|---|
season_id | integer | Only this season's drops |
include | string | season |
updated_since | datetime | Only drops updated at or after this time |
per_page | integer | Items per page (10-100, default 25) |
Exchange Rates
Dated sales exchange rates used to convert prices and orders between currencies. Needs exchange_rates:read / exchange_rates:write.
/exchange-ratesList exchange rates
/exchange-ratesCreate an exchange rate
/exchange-rates/{id}Get an exchange rate
/exchange-rates/{id}Update an exchange rate (PATCH also accepted)
/exchange-rates/{id}Delete an exchange rate
Create Exchange Rate
| Parameter | Type | Description |
|---|---|---|
from_currency_idRequired | integer | Source currency |
to_currency_idRequired | integer | Target currency (must differ from the source) |
rateRequired | number | Units of the target currency per one unit of the source |
effective_dateRequired | date | Date the rate applies from |
brand_id | integer | Optional brand the rate belongs to |
List filters
| Parameter | Type | Description |
|---|---|---|
from_currency_id | integer | Filter by source currency |
to_currency_id | integer | Filter by target currency |
effective_on | date | Rates in effect on this date |
Files
Upload and manage files attached to records across the system — styles, components, purchase orders, sales orders, customers, suppliers, notes, sample review issues and QC inspections. Requires the files:read / files:write scopes.
/filesList files, filterable by any subject (style_id, component_id, ...)
/files/{id}Get a specific file record
/filesUpload a file (multipart) against exactly one subject record
/files/{id}Update file metadata (never the binary)
/files/{id}Partially update file metadata
/files/{id}Soft-delete a file
/files/{id}/download-urlResolve a download URL for the file
List Files
| Parameter | Type | Description |
|---|---|---|
style_id | integer | Filter by style |
component_id | integer | Filter by component |
purchase_order_id | integer | Filter by purchase order |
sales_order_id | integer | Filter by sales order |
customer_id | integer | Filter by customer |
supplier_id | integer | Filter by supplier |
note_id | integer | Filter by note |
sample_review_issue_id | integer | Filter by sample review issue |
variant_id | integer | Filter by style variant |
search | string | Search by original file name |
extension | string | Filter by file extension |
is_primary | boolean | Filter by primary flag |
visibility | string | Filter by visibility (company, everyone, private) |
per_page | integer | Items per page (max 100) |
Upload a File
Send a multipart/form-data request with the binary in thefile field plus exactly one subject foreign key (style_id, component_id,purchase_order_id, sales_order_id,customer_id, supplier_id,note_id or sample_review_issue_id).variant_id may only accompany style_id(variant imagery), and section_id may only accompanystyle_id.
| Parameter | Type | Description |
|---|---|---|
fileRequired | file | The file to upload (max 50 MB) |
style_id | integer | Subject: style |
component_id | integer | Subject: component |
purchase_order_id | integer | Subject: purchase order |
sales_order_id | integer | Subject: sales order |
customer_id | integer | Subject: customer |
supplier_id | integer | Subject: supplier |
note_id | integer | Subject: note |
sample_review_issue_id | integer | Subject: sample review issue |
variant_id | integer | Style variant (only with style_id) |
section_id | integer | Style file section (only with style_id) |
visibility | string | company, everyone or private (default: company) |
supplier_visible | boolean | Whether suppliers can see the file |
client_visible | boolean | Agency workspaces: share the file with the client in the client portal (style Files tab). Default false; also settable via PUT/PATCH /files/{id} and returned on every file |
member_access_level | string | self_only, company_team or admins_only |
include_in_techpack | boolean | Include the file in tech pack exports |
is_primary | boolean | Mark as the subject's primary file/image |
tags | array | Tags for the file |
Example Request
curl -X POST "https://api.kobolabs.io/api/v1/files" \
-H "X-API-Key: your_api_key" \
-F "file=@techpack-sketch.png" \
-F "style_id=123" \
-F "is_primary=true"Download URL Response
{
"success": true,
"data": {
"url": "https://storage.googleapis.com/.../techpack-sketch.png",
"file_name": "techpack-sketch.png",
"mime_type": "image/png",
"size": 245120
}
}DELETE /files/{id} soft-deletes the record only — the underlying stored object is never removed, because file version-copies share storage blobs.Bill of Materials (BOM)
The BOM represents the list of components and materials used to manufacture a style.
/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
/styles/{styleId}/bom/bulkBulk-add multiple components to a style's BOM in one request
/bom/bulk-replaceReplace a component across multiple BOM rows in one request
/styles/{styleId}/bomClear ALL BOM entries for a style — requires confirm: true in the payload
/bom/{id}/colorsAssign a library colour to a BOM entry
/bom/{id}/colors/{colorId}Remove a library colour from a BOM entry
/bom/{id}/replaceReplace the component on a single BOM row
DELETE /styles/{styleId}/bom wipes every BOM row on the style and only proceeds when the request body includes {"confirm": true}.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.
/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
/styles/{styleId}/pom/positionsReorder a style's POM rows
/styles/{styleId}/pom/save-templateSave a style's POMs to the library as a new POM template
/styles/{styleId}/pom/diagram/{diagramId}Get a POM diagram linked to a style
/styles/{styleId}/pom/diagramLink a library POM diagram to a style
/styles/{styleId}/pom/diagramUnlink the POM diagram from a style
/styles/{styleId}/pomBulk update/replace all POMs for a 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
}
}Colorway Propagation
Copy data between a style's colorway peers. The same three-endpoint pattern is available for BOM, POM, quality control and sample review issues:colorway-import lists the items available to import from peers,import-from-colorway imports selected items from a peer colorway, and apply-to-colorways pushes items out to all colorway peers.
BOM
/styles/{styleId}/bom/colorway-importList BOM items available for cross-colorway import
/styles/{styleId}/bom/import-from-colorwayImport selected BOM items from a peer colorway
/styles/{styleId}/bom/apply-to-colorwaysApply BOM items to all colorway peers
POM
/styles/{styleId}/pom/colorway-importList POMs available for cross-colorway import
/styles/{styleId}/pom/import-from-colorwayImport selected POMs from a peer colorway
/styles/{styleId}/pom/apply-to-colorwaysApply POMs to all colorway peers
Quality Control
/styles/{styleId}/quality-control/colorway-importList QC data available for cross-colorway import
/styles/{styleId}/quality-control/import-from-colorwayImport QC data from a peer colorway
/styles/{styleId}/quality-control/apply-to-colorwaysApply QC data to all colorway peers
Sample Review Issues
/styles/{styleId}/sample-review-issues/colorway-importList sample review issues available for cross-colorway import
/styles/{styleId}/sample-review-issues/import-from-colorwayImport sample review issues from a peer colorway
/styles/{styleId}/sample-review-issues/apply-to-colorwaysApply sample review issues to all colorway peers
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/batchBulk-create variants in a single transaction (duplicate names skipped and reported)
/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
}Barcodes
Manage the barcode inventory pool and assign barcodes to SKUs. Supported barcode types:upc, ean,code39, code128.
/styles/{style}/skus/assign-barcodesBulk-assign available pool barcodes to specific SKUs of a style
/styles/barcodes/availableList available (unassigned) barcodes from the inventory pool
/styles/barcodes/usedList barcodes already assigned to SKUs
/styles/barcodes/validateValidate a barcode's format and check whether it is already in use
/styles/barcodes/{barcode}Look up a barcode and the SKU it is assigned to
Assign Barcodes to SKUs
| Parameter | Type | Description |
|---|---|---|
typeRequired | string | Barcode type: upc, ean, code39, code128 |
sku_idsRequired | array | SKU IDs on the style to assign barcodes to |
Validate Barcode
| Parameter | Type | Description |
|---|---|---|
barcodeRequired | string | The barcode value to validate |
typeRequired | string | Barcode type: upc, ean, code39, code128 |
Library Constructions
Manage reusable construction specifications and techniques stored in the product library.
/library-constructionsList constructions (paginated)
/library-constructions/{id}Get a construction
/library-constructionsCreate a construction
/library-constructions/{id}Update a construction
/library-constructions/{id}Delete a construction
List Constructions
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
created_since | datetime | Filter by creation time |
Create Construction Example
{
"name": "Flat Felled Seam",
"description": "A strong, flat seam commonly used in denim and workwear",
"category": "seams",
"notes": "Requires double-needle sewing machine"
}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
/sales-orders/{id}/statusUpdate sales order status
/sales-orders/{id}/invoiceCreate invoice from sales order
/sales-orders/{id}/unconfirmUnconfirm a sales order
/sales-orders/{id}/itemsList sales order line items
/sales-orders/{id}/itemsAdd a line item to a sales order
/sales-orders/{id}/items/{itemId}Update a sales order line item
/sales-orders/{id}/items/{itemId}Remove a sales order line item
/sales-orders/{id}/stylesStyles on a sales order
/sales-orders/{id}/fulfilment-quantitiesFulfilment quantities per line
/sales-orders/{id}/download-pdfDownload the sales order as a PDF
/sales-orders/{id}/confirmConfirm a sales order
/sales-orders/{id}/cancelCancel a sales order
/sales-orders/{id}/completeMark a sales order as completed
Status Values
draft, pending,confirmed, processing,shipped, delivered,cancelled
Update Status Example
{
"status": "confirmed",
"notes": "Order confirmed by warehouse"
}Invoices
Create and manage invoices linked to sales orders.
/invoicesList all invoices
/invoices/{id}Get a specific invoice
/invoicesCreate a new invoice
/invoices/{id}Update an invoice
/invoices/{id}/confirmConfirm a draft invoice
/invoices/{id}/cancelCancel an invoice
/invoices/{id}Delete an invoice
/invoices/{id}/itemsAdd a line item to an invoice
/invoices/{id}/items/{itemId}Update an invoice line item
/invoices/{id}/items/{itemId}Remove an invoice line item
/invoices/{id}/recalculate-totalsRecalculate invoice totals from its lines
/invoices/{id}/unconfirmRevert a confirmed invoice to draft
/invoices/{id}/restoreRestore a deleted invoice
/invoices/{id}/download-pdfDownload the invoice as a PDF
/invoices/{id}/sendEmail the invoice PDF (guarded send; see Documents)
/sales-orders/{id}/invoiceable-linesWhat is still invoiceable per sales-order line and size (invoices:read)
Partial (line-by-line) invoicing
Pass lines to POST /invoices to bill exactly the quantities you name. When lines is present invoice_type is ignored and a draft invoice is created for just those lines. Read invoiceable-lines first to see what each line may still take.
| Parameter | Type | Description |
|---|---|---|
sales_order_idRequired | integer | The sales order to invoice |
lines | object[] | [{sales_order_style_id, sizes: {S: 2, M: 3}}] or [{sales_order_style_id, quantity: 5}] |
{
"sales_order_id": 981,
"lines": [
{ "sales_order_style_id": 5521, "sizes": { "S": 2, "M": 3 } },
{ "sales_order_style_id": 5522, "quantity": 10 }
]
}List Invoices
| 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 (draft, confirmed, cancelled) |
sales_order_id | integer | Filter by sales order |
customer_id | integer | Filter by customer |
Create Invoice Example
{
"sales_order_id": 123,
"invoice_number": "INV-2024-0001",
"due_date": "2024-02-15",
"notes": "Net 30 payment terms",
"line_items": [
{
"description": "Classic Cotton Tee - White - M",
"quantity": 50,
"unit_price": 45.00
}
]
}Credit Notes
Manage credit notes for returns, adjustments, and refunds.
/credit-notesList all credit notes
/credit-notes/{id}Get a specific credit note
/credit-notesCreate a credit note
/credit-notes/{id}Update a credit note
/credit-notes/{id}Delete a credit note
/credit-notes/{id}/issueIssue a credit note
/credit-notes/{id}/unissueRevert an issued credit note to draft
/credit-notes/{id}/applyApply a credit note against an invoice
/credit-notes/{id}/voidVoid a credit note
/credit-notes/{id}/unvoidRestore a voided credit note
List Credit Notes
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
Create Credit Note Example
{
"sales_order_id": 123,
"reason": "Damaged goods returned",
"amount": 225.00,
"notes": "5 units returned in defective condition"
}Sales Order Payments
Track payments received against sales orders.
/sales-order-paymentsList all sales order payments
/sales-order-payments/{id}Get a specific payment
/sales-order-paymentsRecord a payment
/sales-order-payments/{id}Update a payment
/sales-order-payments/{id}Delete a payment
/sales-order-payments/summaryPayment totals summary across sales orders
List Payments
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
sales_order_id | integer | Filter by sales order |
Record Payment Example
{
"sales_order_id": 123,
"amount": 2250.00,
"payment_method": "bank_transfer",
"payment_date": "2024-01-20",
"reference": "TT-SO-2024-001"
}Pick Tickets
Manage warehouse pick tickets for fulfilling sales orders.
/pick-ticketsList all pick tickets
/pick-tickets/{id}Get a specific pick ticket
/pick-ticketsCreate a pick ticket
/pick-tickets/{id}Update a pick ticket
/pick-tickets/{id}Delete a pick ticket
/pick-tickets/{id}/mark-pickedMark a pick ticket as picked
/pick-tickets/{id}/unmark-pickedRevert a pick ticket to unpicked
/pick-tickets/{id}/perform-pickRecord the actual pick per size; short picks release the shortfall and re-reserve, as in the app
/pick-tickets/{id}/download-pdfDownload the pick ticket PDF
/pick-tickets/{id}/sendEmail the pick ticket PDF (guarded send)
Perform Pick
| Parameter | Type | Description |
|---|---|---|
stylesRequired | object[] | One row per style: style_id, quantity {size: units picked} |
List Pick Tickets
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
Delivery Notes
Manage delivery notes linked to sales orders. Supports soft delete.
/delivery-notesList all delivery notes
/delivery-notes/{id}Get a specific delivery note (includes salesOrder, items)
/delivery-notesCreate a new delivery note
/delivery-notes/{id}Update an existing delivery note
/delivery-notes/{id}Delete a delivery note (soft delete)
List Delivery Notes
| Parameter | Type | Description |
|---|---|---|
search | string | Search delivery notes |
status | string | Filter by status |
sales_order_id | integer | Filter by sales order |
per_page | integer | Items per page (max 100) |
sort_by | string | Sort field |
sort_dir | string | Sort direction (asc, desc) |
Create Delivery Note
| Parameter | Type | Description |
|---|---|---|
sales_order_idRequired | integer | Associated sales order |
delivery_dateRequired | date | Delivery date |
status | string | Delivery note status |
notes | string | Additional notes |
tracking_number | string | Shipment tracking number |
carrier | string | Shipping carrier name |
Example Response
{
"data": {
"id": 1,
"sales_order": {
"id": 10,
"order_number": "SO-2024-010"
},
"items": [
{
"id": 1,
"sku": "SS24-001-WHT-M",
"quantity": 50
}
],
"delivery_date": "2024-03-15",
"status": "pending",
"notes": null,
"tracking_number": "1Z999AA10123456784",
"carrier": "UPS",
"created_at": "2024-03-10T09:00:00Z",
"updated_at": "2024-03-10T09:00:00Z"
}
}Packing Lists
Manage packing lists for transferring goods between locations.
/packing-listsList all packing lists
/packing-lists/{id}Get a specific packing list (includes fromLocation, toLocation, items)
/packing-listsCreate a new packing list
/packing-lists/{id}Update an existing packing list
/packing-lists/{id}Delete a packing list
List Packing Lists
| Parameter | Type | Description |
|---|---|---|
search | string | Search packing lists |
status | string | Filter by status |
per_page | integer | Items per page (max 100) |
sort_by | string | Sort field |
sort_dir | string | Sort direction (asc, desc) |
Create Packing List
| Parameter | Type | Description |
|---|---|---|
from_location_idRequired | integer | Source location ID |
to_location_idRequired | integer | Destination location ID |
status | string | Packing list status |
notes | string | Additional notes |
packed_date | date | Date packed |
Example Response
{
"data": {
"id": 1,
"from_location": {
"id": 1,
"name": "Main Warehouse"
},
"to_location": {
"id": 2,
"name": "Retail Store NYC"
},
"items": [
{
"id": 1,
"sku": "SS24-001-WHT-M",
"quantity": 25
}
],
"status": "packed",
"notes": null,
"packed_date": "2024-03-12",
"created_at": "2024-03-10T09:00:00Z",
"updated_at": "2024-03-12T14:00:00Z"
}
}Sales Shipments
Track outbound shipments for sales orders.
/sales-shipmentsList all shipments
/sales-shipments/{id}Get a specific shipment
/sales-shipmentsCreate a shipment
/sales-shipments/{id}Update a shipment
/sales-shipments/{id}Delete a shipment
/sales-shipments/{id}/update-statusUpdate shipment status
/sales-shipments/{id}/mark-shippedMark a shipment as shipped
/sales-shipments/{id}/unmark-shippedRevert a shipment to unshipped
/sales-shipments/{id}/mark-deliveredMark a shipment as delivered
/sales-shipments/{id}/commercial-invoice-pdfDownload the commercial invoice. Refused with 422 while a line has no HS code or country of origin.
/sales-shipments/{id}/packing-list-pdfDownload the packing list
/sales-shipments/{id}/carton-labels-pdfDownload the carton labels
/sales-shipments/{id}/unmark-deliveredRevert a shipment to undelivered
List Shipments
| 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 |
Update Status Example
{
"status": "in_transit",
"tracking_number": "1Z999AA10123456784",
"carrier": "UPS"
}Order Confirmations
Manage order confirmation documents for sales orders.
/order-confirmationsList all order confirmations
/order-confirmations/{id}Get a specific confirmation
/order-confirmationsCreate an order confirmation
/order-confirmations/{id}Update an order confirmation
/order-confirmations/{id}Delete an order confirmation
/order-confirmations/{id}/download-pdfDownload the order confirmation as a PDF
List Order Confirmations
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
Deliveries
Inbound deliveries against purchase orders. Receiving a delivery is a real check-in: stock moves into the location exactly as it does in the app.
/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)
/deliveriesCreate a delivery against a purchase order
/deliveries/{id}Update a delivery
/deliveries/{id}Delete a delivery
/deliveries/{id}/receiveCheck a delivery in: moves stock, creates the check-in, relieves on-order, records sample receipts and discrepancies; 409 if already checked in
/deliveries/quantities/{poId}Delivered quantities per item for a purchase order
/deliveries/{id}/cartonsSupplier-shipment cartons for a delivery
/deliveries/{id}/download-pdfDownload the delivery PDF
/deliveries/{id}/sendEmail the delivery PDF (guarded send)
/deliveries/{id}/packing-list-pdfSupplier shipment (ASN) packing list PDF
/deliveries/{id}/carton-labels-pdfSupplier shipment carton labels PDF
Receive a Delivery
Omit items to receive everything still outstanding on the delivery. Deliveries now include parcel_shipment_id (the ASN link), cartons, internal notes and per-item purchase_order_item_id.
| Parameter | Type | Description |
|---|---|---|
location_id | integer | Location to receive into (defaults to the delivery's brand location) |
items | object[] | Units received: style_id, size, quantity, purchase_order_item_id (needed when a style has two PO lines) |
received_notes | string | Stored on the check-in and appended to the delivery's internal notes |
discrepancy | object | Why a supplier-shipped delivery arrived differently: reason, note, missing_cartons |
{
"location_id": 3,
"items": [
{ "style_id": 120, "size": "M", "quantity": 48, "purchase_order_item_id": 301 },
{ "style_id": 120, "size": "L", "quantity": 36, "purchase_order_item_id": 301 }
],
"received_notes": "Two cartons damaged on arrival"
}PO Workflows
The purchase-order workflows the app runs beyond plain CRUD, each through the same service. Reads need purchase-orders:read, writes purchase-orders:write.
/purchase-orders/{id}/short-splitShort-delivery split proposal
/purchase-orders/{id}/short-splitCommit a split (pick tickets per order)
/purchase-orders/{id}/short-split/{runId}/undoUndo a split
/purchase-orders/{id}/destinationsThe PO broken down by destination
/purchase-orders/{id}/deliveries/split-previewPreview one delivery per destination
/purchase-orders/{id}/deliveries/splitCreate one delivery per destination
/purchase-orders/{id}/pack-per-destinationFactory packs per destination (true, false, or null to follow the setting)
/purchase-orders/{id}/supplier-confirmationRecord the supplier's confirmation or a flagged issue
/check-ins/{checkInId}/undoVoid a check-in, reversing its stock
/check-ins/{checkInId}Delete a check-in (undone first)
/purchase-orders/{id}/check-ins/{checkInId}/download-pdfDownload a check-in PDF
{checkInId} is the check-in reference string (for example CI-000123), not a numeric id.
Short-split
| Parameter | Type | Description |
|---|---|---|
splitsRequired | object[] | One row per order and style: sales_order_id, style_id, size_quantities {size: units} |
Destination split / preview
| Parameter | Type | Description |
|---|---|---|
lines | object[] | What is arriving per line: purchase_order_item_id, size_quantities. Omit for everything still to deliver |
overrides | object[] | Fix a destination's sizes for a line: purchase_order_item_id, location_id, size_quantities |
delivery_date | date | Delivery date for every created delivery (split only) |
Supplier confirmation
| Parameter | Type | Description |
|---|---|---|
ack_statusRequired | string | acknowledged or flagged |
note | string | What the supplier said (required when flagged) |
ship_date | date | Ship date the supplier committed to (Y-m-d) |
Documents (PDF & Send)
Download the same PDFs the app produces, and email them through a guarded send. Downloads return application/pdf and need the document’s :read scope; sends need its :write scope.
| Document | Download | Send | Scopes |
|---|---|---|---|
| Credit note | GET /credit-notes/{id}/download-pdf | POST /credit-notes/{id}/send | credit_notes:read / credit_notes:write |
| Pick ticket | GET /pick-tickets/{id}/download-pdf | POST /pick-tickets/{id}/send | pick_tickets:read / pick_tickets:write |
| Sales shipment | GET /sales-shipments/{id}/download-pdf | POST /sales-shipments/{id}/send | shipments:read / shipments:write |
| Commercial invoice | GET /sales-shipments/{id}/commercial-invoice-pdf | — | shipments:read |
| Sales packing list | GET /sales-shipments/{id}/packing-list-pdf | — | shipments:read |
| Sales carton labels | GET /sales-shipments/{id}/carton-labels-pdf | — | shipments:read |
| Sales return | GET /sales-returns/{id}/download-pdf | POST /sales-returns/{id}/send | sales-returns:read / sales-returns:write |
| Sales cancellation | GET /sales-cancellations/{id}/download-pdf | POST /sales-cancellations/{id}/send | sales-cancellations:read / sales-cancellations:write |
| Sales order | GET /sales-orders/{id}/download-pdf | — | sales-orders:read |
| Delivery note | GET /delivery-notes/{id}/download-pdf | — | delivery_notes:read |
| Order confirmation | GET /order-confirmations/{id}/download-pdf | POST /order-confirmations/{id}/send | order_confirmations:read / order_confirmations:write |
| Invoice | GET /invoices/{id}/download-pdf | POST /invoices/{id}/send | invoices:read / invoices:write |
| Customer statement | GET /customers/{id}/statement/download-pdf | — | customers:read |
| Purchase order | GET /purchase-orders/{id}/pdf | POST /purchase-orders/{id}/send | purchase-orders:read / purchase-orders:write |
| PO check-in | GET /purchase-orders/{id}/check-ins/{checkInId}/download-pdf | — | purchase-orders:read |
| PO delivery | GET /deliveries/{id}/download-pdf | POST /deliveries/{id}/send | deliveries:read / deliveries:write |
| ASN packing list | GET /deliveries/{id}/packing-list-pdf | — | deliveries:read |
| ASN carton labels | GET /deliveries/{id}/carton-labels-pdf | — | deliveries:read |
| PO cancellation | GET /cancellations/{id}/download-pdf | POST /cancellations/{id}/send | cancellations:read / cancellations:write |
| Packing list (transfer) | GET /packing-lists/{id}/download-pdf | POST /packing-lists/{id}/send | packing_lists:read / packing_lists:write |
| Bill of materials | GET /styles/{styleId}/bom/download-pdf | POST /styles/{styleId}/bom/send | bom:read / bom:write |
| Points of measure | GET /styles/{styleId}/pom/download-pdf | POST /styles/{styleId}/pom/send | pom:read / pom:write |
| Sample review | GET /styles/{styleId}/variants/{variantId}/sample-review/download-pdf | POST /styles/{styleId}/variants/{variantId}/sample-review/send | sample_reviews:read / sample_reviews:write |
| Cost sheet | GET /styles/{styleId}/pricing/download-pdf | — | pricing:read |
| QC report | GET /quality-control/{id}/download-pdf | — | quality_control:read |
| Tech pack | GET /tech-packs/styles/{styleId}/download-pdf | POST /tech-packs/styles/{styleId}/send | tech_packs:read / tech_packs:write |
/credit-notes/{id}/download-pdfExample download: the credit note PDF
/credit-notes/{id}/sendExample send: email the credit note PDF to up to 5 allowed recipients
Send body
| Parameter | Type | Description |
|---|---|---|
recipientsRequired | string[] | 1-5 emails; each a user of your company or a contact of the document's customer/supplier |
subject | string | Optional (max 191 characters) |
message | string | Optional (max 2,000 characters) |
429 with Retry-After. A recipient outside the allow-list returns 422 — nothing is sent.curl "https://api.kobolabs.io/api/v1/styles/123/bom/download-pdf" \
-H "X-API-Key: your_api_key" \
-o bom.pdf
curl -X POST "https://api.kobolabs.io/api/v1/purchase-orders/88/send" \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{"recipients": ["orders@yoursupplier.com"], "message": "PO attached, please confirm the ship date."}' Inbound Shipments (ASN)
Inbound shipments (advance shipping notices) carry purchase orders from a supplier, with deliveries, cartons and tracking. Read with shipments:read, write with shipments:write.
/parcel-shipmentsList inbound shipments
/parcel-shipments/{id}Get a shipment with POs, deliveries, cartons and tracking
/parcel-shipments/{id}/purchase-ordersAttach purchase orders (whole, or per line / pack)
/parcel-shipments/{id}/purchase-orders/{poId}Detach a purchase order
/parcel-shipments/{id}/purchase-orders/{poId}/moveMove a purchase order to another shipment (target_shipment_id)
List Shipments
| Parameter | Type | Description |
|---|---|---|
status | string | pending, in-transit, delivered, exception, cancelled |
shipment_type | string | sample, materials, production, other |
supplier_id | integer | Shipments carrying this supplier's POs |
purchase_order_id | integer | Shipments carrying this PO |
is_supplier_created | boolean | Only supplier-created (true) or brand-created (false) |
include | string | supplier, deliveries |
Attach Purchase Orders
| Parameter | Type | Description |
|---|---|---|
purchase_order_ids | integer[] | Confirmed POs to attach whole (required without allocations) |
allocations | object[] | Per line: purchase_order_id, purchase_order_item_id, quantity or packs [{code, variant_id, cartons}] |
Carrier Accounts
Read-only list of the company’s carrier accounts. Credentials are never returned. Needs shipments:read.
/carrier-accountsList carrier accounts
/carrier-accounts/{id}Get a carrier account
Shipping Rules
Rules that pick carriers and services for shipments. Read with shipments:read, write with shipments:write.
/shipping-rulesList shipping rules
/shipping-rulesCreate a shipping rule
/shipping-rules/{id}Get a shipping rule
/shipping-rules/{id}Update a shipping rule (PATCH also accepted)
/shipping-rules/{id}Delete a shipping rule
Goods Receipts
Record goods received against purchase orders and deliveries.
/goods-receiptsList all goods receipts
/goods-receipts/{id}Get a specific goods receipt
/goods-receiptsCreate a goods receipt
/goods-receipts/{id}Update a goods receipt
/goods-receipts/{id}Delete a goods receipt
List Goods Receipts
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
supplier_id | integer | Filter by supplier |
Create Goods Receipt Example
{
"order": "PO-2024-0001",
"delivery_name": "DEL-001",
"warehouse": "Main Warehouse",
"supplier_id": 1,
"date_received": "2024-02-15",
"pcs_received": 500,
"quantities": {"S": 100, "M": 150, "L": 150, "XL": 100}
}Cutting Tickets
An instruction to cut part or all of a confirmed production purchase order. Tickets never change PO quantities, stock or money. Issued tickets show in the supplier portal, where the factory records the actual cut.
/cutting-ticketsList cutting tickets
/cutting-tickets/{id}Get a specific cutting ticket
/cutting-ticketsCreate a draft cutting ticket
/cutting-tickets/{id}Update a draft cutting ticket
/cutting-tickets/{id}/issueIssue the ticket to the factory
/cutting-tickets/{id}/cancelCancel a ticket. A factory that had it is told by email.
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}/confirmConfirm a cancellation
/cancellations/{id}/undoUndo a confirmed 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"
}Budgets
Create and manage budgets for purchasing, production, and development spend tracking.
/budgetsList budgets (paginated)
/budgets/{id}Get a budget
/budgetsCreate a budget
/budgets/{id}Update a budget
/budgets/{id}Delete a budget
/budgets/{id}/analyticsBudget analytics: overview, per-category breakdown, timeline, top suppliers, alerts
/budgets/{id}/comparisonBudget vs actual comparison, overall and per category
/budgets/{id}/tracking-entriesPaginated tracking entries for a budget
/budgets/{id}/allocationsBatch upsert per-category allocations
/budgets/{id}/duplicateDuplicate a budget with its category allocations (spending reset)
/budgets/{id}/categories/{categoryId}/allocationUpdate a budget category allocation
/budgets/{id}/lockLock the budget as the agreed version (bumps version)
/budgets/{id}/unlockUnlock the budget for editing
409. Budgets now return version, locked_at and locked_by.List Budgets
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
created_since | datetime | Filter by creation time |
Create Budget Example
{
"name": "SS25 Sourcing Budget",
"amount": 50000.00,
"currency": "USD",
"period_start": "2025-01-01",
"period_end": "2025-06-30",
"notes": "Spring/Summer 2025 component and fabric sourcing"
}Component Inventory
Track inventory levels for components and materials.
/component-inventoryList component inventory
/component-inventory/{id}Get a specific inventory item
/component-inventoryCreate a component inventory record
/component-inventory/bulk-updateBulk update component inventory
/component-inventory/{id}/check-inCheck in component inventory
List Component Inventory
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
component_id | integer | Filter by component |
Check In Example
{
"quantity": 500,
"reference": "PO-2024-0015",
"notes": "Received from supplier shipment"
}Style Inventory
Track finished goods inventory by style, size, and color.
/style-inventoryList style inventory
/style-inventory/{id}Get a specific inventory item
/style-inventory/{id}Update inventory levels
/style-inventory/{id}/check-inCheck in style inventory
/style-inventory/{id}/transferTransfer inventory between locations
List Style 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 |
Transfer Example
{
"to_location_id": 2,
"quantity": 50,
"notes": "Transfer to retail warehouse"
}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}/approveApprove a completed stock take and apply adjustments
/stock-takes/{id}/itemsGet stock take items
/stock-takes/{id}/cancelCancel a stock take
/stock-takes/{id}/variance-summaryVariance summary for a stock take
/stock-takes/{id}/items/batch-countRecord counts for multiple items at once
/stock-takes/{sessionId}/items/{itemId}/countRecord a count for a single item
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"
}Locations
Manage warehouse and storage locations used for inventory tracking and stock takes.
/locationsList locations (paginated)
/locations/{id}Get a location
/locationsCreate a location
/locations/{id}Update a location
/locations/{id}Delete a location
List Locations
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
created_since | datetime | Filter by creation time |
Create Location Example
{
"name": "Warehouse A - Shelf 3B",
"code": "WH-A-3B",
"description": "Main warehouse, aisle 3, shelf B",
"is_active": true
}Component Reservations
Manage reservations of component inventory for production orders and style development.
/component-reservationsList reservations (paginated)
/component-reservations/{id}Get a reservation
/component-reservationsCreate a reservation
/component-reservations/{id}Update a reservation
/component-reservations/{id}Delete a reservation
List Reservations
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
component_id | integer | Filter by component |
status | string | Filter by status (active, released, expired) |
Create Reservation Example
{
"component_id": 45,
"quantity": 500,
"reserved_for": "production_order",
"reference_id": 123,
"expires_at": "2025-03-31T00:00:00Z",
"notes": "Reserved for SS25 production run"
}Range Plans
Plan and manage seasonal ranges before converting to full styles.
/range-plansList all range plans
/range-plans/{id}Get a specific range plan
/range-plansCreate a range plan
/range-plans/{id}Update a range plan
/range-plans/{id}Delete a range plan
/range-plans/{id}/duplicateDuplicate a range plan
/range-plans/{id}/styles/{styleId}Update one card on the plan (prices, drop, newness, ranging...)
/range-plans/{id}/styles/{styleId}/convertConvert a range plan card into a full style (needs range_plans:write and styles:write)
Range plans now return their financial settings (margin_basis, vat_rate, market_id, currency, channel_mix_wholesale_pct, margin_floor_pct, target_margin_pct, model_budget), and each card its cost_price, wholesale_price, rrp, season_delivery_id, newness and ranging fields.
List Range Plans
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
season_id | integer | Filter by season |
Create Range Plan Example
{
"name": "SS25 Core Range",
"season_id": 5,
"category_id": 1,
"target_price": 45.00,
"target_margin": 60,
"notes": "Core basics collection for Spring/Summer 2025"
}Quotations
Create and manage supplier quotations for production costing.
/quotationsList all quotations
/quotations/{id}Get a specific quotation
/quotationsCreate a quotation
/quotations/{id}Update a quotation
/quotations/{id}Delete a quotation
/quotations/{id}/reviseCreate a revision of a quotation
/quotations/style/{styleId}Quotations for a style
/quotations/supplier/{supplierId}Quotations from a supplier
/quotations/price-history/style/{styleId}Quoted price history for a style
/quotations/{id}/statusRecord a decision (pending, counter-offer, approved, rejected) with an optional brand note, through the app's decision rules
Status Decision
| Parameter | Type | Description |
|---|---|---|
statusRequired | string | pending, counter-offer, approved or rejected |
note | string | Brand note saved with the decision (max 2,000 characters) |
List Quotations
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
supplier_id | integer | Filter by supplier |
style_id | integer | Filter by style |
Create Quotation Example
{
"supplier_id": 1,
"style_id": 123,
"unit_price": 22.50,
"currency": "USD",
"moq": 500,
"lead_time_days": 30,
"valid_until": "2024-03-01",
"notes": "Price includes packaging"
}Quote Comparison & Award
Compare every supplier quote on a style with weighted price, quality and delivery scores, then place (award) the style. Read with quotations:read, write with quotations:write.
/styles/{styleId}/quote-comparisonCompare every quote on a style
/styles/{styleId}/quote-comparison/weightsSet the style's score weights (price, quality, delivery)
/styles/{styleId}/quote-comparison/ratings/{quotationId}Rate a quote's quality and delivery
/styles/{styleId}/quote-comparison/awardAward the style to one or more quotes (allocations)
/styles/{styleId}/quote-comparison/award/supersedeClear the current placement
/quote-weightsBrand default weights (brand_id required for a company-wide key)
/quote-weightsSet brand default weights
Award Example
{
"allocations": [
{ "quotation_id": 77 }
]
}Linesheets
Create and manage linesheets for wholesale buyers and showrooms.
/linesheetsList all linesheets
/linesheets/{id}Get a specific linesheet
/linesheetsCreate a linesheet
/linesheets/{id}Update a linesheet
/linesheets/{id}Delete a linesheet
/linesheets/{id}/duplicateDuplicate a linesheet
/linesheets/{id}/archiveArchive a linesheet
/linesheets/{id}/restoreRestore an archived linesheet
/linesheets/{id}/shareCreate a share link (token + public URL); needs linesheets:write; never sends email
/linesheets/{id}/generateRender the linesheet and return the PDF (application/pdf)
/linesheets/{id}/reorderReorder linesheet entries
List Linesheets
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
per_page | integer | Items per page |
updated_since | datetime | Filter by update time |
season_id | integer | Filter by season |
Share a Linesheet
| Parameter | Type | Description |
|---|---|---|
customer_id | integer | Customer the link is for |
recipient | string | Email the link is recorded against (no email is sent) |
expires_in_days | integer | 1-365 |
password | string | Optional password (4-120 characters) |
allow_order | boolean | Let the viewer place an order from the link |
Download the PDF
curl -X POST "https://api.kobolabs.io/api/v1/linesheets/18/generate" \
-H "X-API-Key: your_api_key" \
-o linesheet.pdfLinesheets now also return their ordering rules: minimum order, ship window, price visibility and stock settings.
Sample Requests
Request samples from a supplier for a style, then record what arrives, the verdict and what happens to the sample. Needs sample_requests:read / sample_requests:write. Writes respect the style lock.
/sample-requestsList sample requests
/sample-requestsRaise a sample request with at least one item
/sample-requests/{id}Get a sample request with items and receipts
/sample-requests/{id}Update a sample request (PATCH also accepted)
/sample-requests/{id}/cancelCancel a sample request
/sample-requests/{id}/receiptsRecord a receipt (lines that arrive on a PO delivery are received through check-in instead)
/sample-requests/{id}/approvalRecord the verdict: approval_status, decided_at, note
/sample-requests/{id}/dispositionRecord what happened to the sample
/styles/{styleId}/sample-requestsSample requests for one style
List Sample Requests
| Parameter | Type | Description |
|---|---|---|
style_id | integer | Filter by style |
status | string | draft, requested, confirmed, shipped, partially_received, received, cancelled |
approval_status | string | pending, approved, approved_with_comments, rejected, not_applicable |
supplier_id | integer | Filter by supplier |
sample_stage_id | integer | Filter by sample stage |
include | string | style, reviews |
updated_since | datetime | Only records updated at or after this time |
sort_by | string | id, requested_at, due_at, status, created_at, updated_at |
Create Sample Request Example
{
"style_id": 123,
"supplier_id": 8,
"sample_stage_id": 2,
"due_at": "2026-11-20",
"items": [
{ "variant_id": 451, "size": "M", "quantity_ordered": 2 }
]
}Sample Reviews
Track and manage sample review workflows during product development.
/sample-reviewsList all sample reviews
/sample-reviews/{id}Get a specific sample review
/sample-reviewsCreate a sample review
/sample-reviews/{id}Update a sample review
/sample-reviews/{id}Delete a sample review
/sample-reviews/{id}/change-statusChange review status (approved, rejected, revision needed)
/sample-reviews/{reviewId}/issuesList the issues on the review's style (?version_id= for one sample stage)
/sample-reviews/{reviewId}/issuesAdd an issue to a sample review (optional version_id = sample stage; defaults to the style's current stage)
/sample-reviews/{reviewId}/issues/{issueId}Update a sample review issue
/sample-reviews/{reviewId}/issues/{issueId}Delete a sample review issue
List Sample Reviews
| 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 |
status | string | Filter by status |
In agency workspaces each review also returns client_approval: the client's latest decision from the client portal ({ id, status, comment, created_at }, statusapproved or changes_requested), or null if the client hasn't responded.
Change Status Example
{
"status": "approved",
"comments": "Sample meets all specifications. Ready for production."
}Quality Control
Access QC inspection reports for styles and production runs.
/quality-control/{id}Get a QC inspection
/quality-control/{id}/reportGenerate a QC inspection report
/quality-controlList QC inspections
/quality-controlCreate a QC inspection
/quality-control/{id}Update a QC inspection
/quality-control/{id}Delete a QC inspection
/quality-control/{id}/approveApprove a QC inspection
/quality-control/{id}/rejectReject a QC inspection
Inspection Categories
Each QC inspection covers these categories:fabric_inspection, dimensional_stability,garment_measurements, garment_construction,labeling_packaging, overall_appearance,compliance_safety, random_sampling
Example Response
{
"data": {
"id": 1,
"style": {"id": 123, "name": "Classic Cotton Tee"},
"inspector_name": "Jane Smith",
"inspection_date": "2024-02-10",
"fabric_inspection": {"status": "pass", "notes": "Fabric weight within tolerance"},
"garment_measurements": {"status": "fail", "notes": "Chest width 1cm over tolerance"},
"overall_result": "conditional_pass"
}
}Lab Tests
Lab testing against a style, a material, or both — colourfastness, shrinkage, chemical, flammability and more — with the lab, the standard, the report reference, dates and a status. Filter by style, component, supplier, type, status, or the outstanding and failing shortcuts. Note that expiry_date means “retest due by” rather than “this result stops being true”, and is null for most tests.
/lab-testsList lab tests
/lab-testsRecord a lab test
/lab-tests/{id}Get a lab test
/lab-tests/{id}Update a lab test
/lab-tests/{id}Partially update a lab test
/lab-tests/{id}Delete a lab test
Tech Packs
Generate comprehensive tech pack documents for styles, including BOM, POM, construction details, and specifications.
/tech-packs/styles/{styleId}Generate a tech pack for a style
Tech Pack Contents
The generated tech pack includes style details, bill of materials, points of measure, colorways, construction notes, and supplier information — all consolidated into a single response.
Labdips
Manage lab dip requests and submissions for color matching with suppliers.
/labdipsList all labdips
/labdips/{id}Get a specific labdip
/labdipsCreate a new labdip
/labdips/{id}Update an existing labdip
/labdips/{id}Delete a labdip
List Labdips
| Parameter | Type | Description |
|---|---|---|
search | string | Search by labdip name |
supplier_id | integer | Filter by supplier |
status | string | Filter by status |
per_page | integer | Items per page (max 100) |
sort_by | string | Sort field |
sort_dir | string | Sort direction (asc, desc) |
Create Labdip
| Parameter | Type | Description |
|---|---|---|
nameRequired | string | Labdip name |
supplier_idRequired | integer | Supplier ID |
status | string | Labdip status |
target_colour | string | Target colour reference |
notes | string | Additional notes |
Example Response
{
"data": {
"id": 1,
"name": "Navy Cotton Labdip",
"supplier": {
"id": 5,
"name": "Premium Textiles Ltd"
},
"status": "pending",
"target_colour": "Pantone 19-3933 TCX",
"notes": "Match to Spring collection navy",
"created_at": "2024-02-01T10:00:00Z",
"updated_at": "2024-02-01T10:00:00Z"
}
}Labdip Swatches & Images
A labdip request carries swatches (options) from the dye house. Decide each swatch, pin an approved one to colourways as the standard, or reject the round and re-request. Status changes go through the same service as the app. Read with labdips:read, write with labdips:write.
/labdips/{id}/optionsList swatches
/labdips/{id}/optionsAdd placeholder swatches (count 1-12)
/labdips/{id}/options/{optionId}Edit a swatch: lab_ref, hex, decision_note (PATCH also accepted)
/labdips/{id}/options/{optionId}Remove a swatch
/labdips/{id}/options/{optionId}/decideDecide a swatch (POST also accepted)
/labdips/{id}/options/{optionId}/applyPin an approved swatch to colourways (colourways: [{style_id, variant_id}])
/labdips/{id}/options/{optionId}/usages/{usageId}Remove a standard
/labdips/{id}/reject-allReject every outstanding swatch
/labdips/{id}/re-requestOpen the next round (supplier_id, date, notes, option_count)
/labdips/{id}/imagesUpload an image (multipart; upload limits apply)
/labdips/{id}/images/{imageId}Delete an image
/labdips/{id}/images/{imageId}/annotationsSave image annotations (POST also accepted)
Decide a Swatch
| Parameter | Type | Description |
|---|---|---|
statusRequired | string | The swatch decision |
decision_note | string | Why (max 2,000 characters) |
Moodboards
Create and manage visual moodboards for design inspiration and collection planning.
/moodboardsList all moodboards
/moodboards/{id}Get a specific moodboard
/moodboardsCreate a new moodboard
/moodboards/{id}Update an existing moodboard
/moodboards/{id}Delete a moodboard
List Moodboards
| Parameter | Type | Description |
|---|---|---|
search | string | Search by moodboard name |
per_page | integer | Items per page (max 100) |
sort_by | string | Sort field |
sort_dir | string | Sort direction (asc, desc) |
Create Moodboard
| Parameter | Type | Description |
|---|---|---|
nameRequired | string | Moodboard name |
description | string | Moodboard description |
canvas_data | object | Canvas layout data (JSON) |
thumbnail | string | Thumbnail image URL |
Example Response
{
"data": {
"id": 1,
"name": "SS25 Color Palette",
"description": "Spring/Summer 2025 color inspiration",
"canvas_data": {},
"thumbnail": "https://storage.googleapis.com/kobo-system-files/moodboards/1/thumb.jpg",
"created_at": "2024-02-05T11:00:00Z",
"updated_at": "2024-02-05T11:00:00Z"
}
}Component Sourcing
Manage sourcing requests for components, including supplier submissions and pricing.
/component-sourcingList all sourcing requests
/component-sourcing/{id}Get a specific sourcing request (includes component, submissions)
/component-sourcingCreate a new sourcing request
/component-sourcing/{id}Update an existing sourcing request
/component-sourcing/{id}Delete a sourcing request
Submissions & Response Cycle
/component-sourcing/{id}/submissionsList submissions for a sourcing request
/component-sourcing/{id}/submissionsSubmit a sourcing option against a request (supplier quote or internal option)
/component-sourcing/{id}/submissions/compareCompare all submissions for a sourcing request
/component-sourcing/{id}/chaseRe-notify suppliers who haven't responded yet
/component-sourcing/submissions/{submissionId}/statusUpdate submission status (brand review: approve / reject / withdraw)
/component-sourcing/submissions/{submissionId}/purchase-orderCreate a draft purchase order from a supplier submission
List Sourcing Requests
| Parameter | Type | Description |
|---|---|---|
search | string | Search sourcing requests |
status | string | Filter by status |
component_id | integer | Filter by component |
per_page | integer | Items per page (max 100) |
sort_by | string | Sort field |
sort_dir | string | Sort direction (asc, desc) |
Create Sourcing Request
| Parameter | Type | Description |
|---|---|---|
component_idRequired | integer | Component ID to source |
requirements | string | Sourcing requirements description |
target_quantity | integer | Target quantity needed |
target_price | number | Target unit price |
currency | string | Currency code (e.g. USD) |
deadline_date | date | Sourcing deadline date |
status | string | Request status |
Example Response
{
"data": {
"id": 1,
"component": {
"id": 42,
"name": "Organic Cotton Jersey 180gsm"
},
"submissions": [
{
"id": 1,
"supplier_id": 5,
"unit_price": "3.50",
"currency": "USD",
"lead_time_days": 21
}
],
"requirements": "GOTS certified, minimum 180gsm",
"target_quantity": 5000,
"target_price": "3.00",
"currency": "USD",
"deadline_date": "2024-04-01",
"status": "open",
"created_at": "2024-02-15T09:00:00Z",
"updated_at": "2024-02-15T09:00:00Z"
}
}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
/tasks/bulkCreate multiple tasks in a single transaction
/tasks/bulkBulk update multiple tasks
/tasks/bulkBulk delete multiple tasks
/tasks/{id}/incompleteMark a task as not completed
/tasks/{id}/duplicateDuplicate a task
/tasks/{id}/attachmentsUpload attachments to a task
/tasks/{taskId}/attachments/{attachmentId}Delete a task attachment
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
/notes/{id}/duplicateDuplicate a note
/notes/{id}/favoriteToggle a note as favourite
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
/projects/{id}/tasksList tasks in 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/{id}/unreadMark a notification as unread
/notificationsDelete all notifications (pass read_only=true to delete only read ones)
/notifications/unread-countGet unread notification count
/notificationsCreate a notification
/notifications/bulkCreate notifications for multiple users
/notifications/mark-readMark a set of notifications as read
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
/workflow-templatesGet available workflow templates
/workflows/trigger-typesList available workflow trigger types
/workflows/{id}/activateActivate a workflow
/workflows/{id}/deactivateDeactivate a workflow
/workflow-templates/{id}/createCreate a workflow from a template
/workflow-executionsList workflow execution runs
/workflow-executions/{id}Get a workflow execution run
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}/score/historyHistorical score snapshots for a supplier
/suppliers/{id}/score/breakdownFull score breakdown (grade, trend, per-metric breakdown, statistics)
/suppliers/{id}/metricsGet detailed supplier metrics
/supplier-metrics/{metricId}/verifyVerify a performance metric
/supplier-metrics/{metricId}Delete a performance metric
/supplier-scores/rankingsGet supplier rankings
/supplier-scoresList supplier scores
/supplier-scores/weightsGet the scoring weight configuration
/supplier-scores/calculate-allRecalculate scores for all suppliers
/suppliers/{id}/score/calculateRecalculate one supplier's score
/suppliers/{id}/metricsRecord a supplier metric
/supplier-metrics/typesList available supplier metric types
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.
/size-rangesGet available size ranges
/currenciesGet supported currencies
/component-categoriesGet component categories
Reference Data (lookups:read scope)
/style-categoriesGet style categories
/style-tagsGet style tags
/marketsGet markets
/sales-channelsGet sales channels
/payment-termsGet payment terms
/incotermsGet incoterms
/task-statusesGet task statuses
Account
/accountIdentify the authenticated account (company, brand and API key context)
/account/brandsList the company's brands, flagging the API key's own brand
/currencies/{id}Get a currency
/currencies/salesCurrencies enabled for sales documents
/size-ranges/{id}Get a size range
/component-categories/{id}Get a component category
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$" }
]
}Tax Rates
The tax rates referenced by suppliers, customers, purchase orders and sales orders. Read-only, and filterable by type (Sales or Purchases), active status, name and updated_since.
/tax-ratesList tax rates
/tax-rates/{id}Get a tax rate
Sample Stages
The sample stages configured for your company (proto, fit, SMS and so on). You need these to obtain a valid version_id, which is required when creating QC inspections and sample-review issues.
/sample-stagesList sample stages
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
}
}Materials
Manage the material library (fibres & fabrics catalog). Global seeded materials are read-only; company materials are fully editable.
/materialsList all materials
/materialsCreate a new material
/materials/{id}Get a specific material
/materials/{id}Update a material
/materials/{id}Partially update a material
/materials/{id}Delete a material
Sketches
Manage technical sketches attached to a style.
/styles/{styleId}/sketchesList sketches for a style
/styles/{styleId}/sketchesAdd a sketch to a style
/sketches/{id}Get a specific sketch
/sketches/{id}Update a sketch
/sketches/{id}Partially update a sketch
/sketches/{id}Delete a sketch
Pages
Control the tech pack page status and visibility for a style.
/styles/{styleId}/pagesList a style's pages and their status
/styles/{styleId}/pages/{pageName}/statusUpdate a page's status
/styles/{styleId}/pages/{pageName}/visibilityToggle a page's visibility
File Sections
Organise a style's uploaded files into ordered sections.
/styles/{styleId}/file-sectionsList file sections for a style
/styles/{styleId}/file-sectionsCreate a file section
/styles/{styleId}/file-sections/orderReorder file sections
/file-sections/{id}Update a file section
/file-sections/{id}Delete a file section
Vendor Bench
Multiple vendors per style. Each row carries a role (primary or backup), a rank and a status. Promoting a row to primary re-points the style’s own supplier and demotes the incumbent, so the bench and the style never disagree. The style’s current primary cannot be removed — promote another vendor first.
/styles/{styleId}/suppliersList a style’s vendor bench
/styles/{styleId}/suppliersAdd a supplier to the bench
/style-suppliers/{id}Get a bench row
/style-suppliers/{id}Update a bench row
/style-suppliers/{id}Partially update a bench row
/style-suppliers/{id}Remove a supplier from the bench
Compliance
Read and update the compliance record for a style.
/style-complianceList compliance across styles — also the delta surface for digital product passports
/styles/{styleId}/complianceGet a style's compliance data
/styles/{styleId}/complianceUpdate compliance data
/styles/{styleId}/compliancePartially update compliance data
Digital Product Passport
Generate, validate, and publish EU Digital Product Passports for your styles, manage brand-level passport theming, and read consumer scan analytics. Uses the compliance:read andcompliance:write scopes. The public passport page and QR scan events are unauthenticated by design.
/styles/{styleId}/dppGet the generated Digital Product Passport payload
/styles/{styleId}/dpp/generateGenerate or regenerate the passport (optionally stamping GTIN / serial number)
/styles/{styleId}/dppUpdate passport fields on the compliance record and regenerate
/styles/{styleId}/dpp/validateValidate the passport against EU DPP requirements
/styles/{styleId}/dpp/qr-codePassport QR code (base64 PNG) plus its public URL
/styles/{styleId}/dpp/export/{format}Export the passport as json, qr, or pdf
/styles/{styleId}/dpp/analyticsAggregated scan analytics for the passport
/brands/{brandId}/dpp-settingsBrand-level passport theming and visibility settings
/brands/{brandId}/dpp-settingsUpdate brand-level passport settings
Workflow Groups
Manage workflow task groups attached to a style.
/styles/{styleId}/workflow-groupsList workflow groups for a style
/styles/{styleId}/workflow-groupsCreate a workflow group
/workflow-groups/{id}Update a workflow group
/workflow-groups/{id}Delete a workflow group
Comments
Threaded comments on a style.
/styles/{styleId}/commentsList comments for a style
/styles/{styleId}/commentsAdd a comment
/comments/{id}Update a comment
/comments/{id}Partially update a comment
/comments/{id}Delete a comment
/comments/{id}/readMark a comment as read
/comments/mark-readMark multiple comments as read
/comments/{id}/reactionsAdd a reaction to a comment
/comments/{id}/reactions/{reaction}Remove a reaction from a comment
Style Pricing
Read, update and recalculate the cost sheet for a style.
/styles/{styleId}/pricingGet a style's pricing
/styles/{styleId}/pricingUpdate a style's pricing
/styles/{styleId}/pricingPartially update a style's pricing
/styles/{styleId}/pricing/calculateRecalculate pricing from the cost breakdown
/styles/{styleId}/pricing/sync-component-costsPull current BOM component costs into the costing sheet and recalculate
/style-pricingList cost sheets across styles — the delta surface for a nightly sync
/style-pricing/bulkBulk pricing read across styles (style_ids[] query parameter)
Value-Added Services (VAS)
/styles/{styleId}/pricing/vasList VAS costing lines on the style's pricing
/styles/{styleId}/pricing/vasAdd a VAS costing line (library service or free-text custom line)
/styles/{styleId}/pricing/vas/{vasId}Update a VAS costing line's cost
/styles/{styleId}/pricing/vas/{vasId}Remove a VAS costing line
Component Pricing
Read and update pricing for a component.
/components/{componentId}/pricingGet a component's pricing
/components/{componentId}/pricingUpdate a component's pricing
/components/{componentId}/pricingPartially update a component's pricing
Channel Pricing
Manage per-sales-channel pricing for a style.
/styles/{styleId}/channel-pricingList channel pricing for a style
/channel-pricing/{id}Get a single channel pricing row
/styles/{styleId}/channel-pricingAdd channel pricing
/channel-pricing/{id}Update channel pricing
/channel-pricing/{id}Partially update channel pricing
/channel-pricing/{id}Delete channel pricing
Market Pricing
Per-market pricing on a style’s cost sheet: the target retail and optional wholesale price in the market’s own currency, plus the per-market sales forecast. Landed cost, net revenue and margin are always computed server-side from the cost sheet and the market’s FX, tax and duty configuration — they are never accepted from the caller. A null forecast means “not planned for this market yet”, which is deliberately distinct from a planned zero.
/styles/{styleId}/market-pricingList per-market pricing for a style
/styles/{styleId}/market-pricing/{marketId}Create or update one market’s pricing
/styles/{styleId}/market-pricing/{marketId}Partially update one market’s pricing
/styles/{styleId}/market-pricing/{marketId}Remove one market’s pricing
Pricing Scenarios
Named what-if costing scenarios cloned from a style’s live cost sheet. Swap the supplier quote, shipping method, freight and duty percentages, quantities or margins, compare the resulting margin waterfall against live, then promote the winner back onto the cost sheet. The list response returns the live cost sheet alongside the scenarios, shaped the same way so the two compare field for field.
/styles/{styleId}/pricing-scenariosList scenarios with the live cost sheet
/styles/{styleId}/pricing-scenariosCreate a scenario
/styles/{styleId}/pricing-scenarios/{scenarioId}Get a scenario
/styles/{styleId}/pricing-scenarios/{scenarioId}Update a scenario
/styles/{styleId}/pricing-scenarios/{scenarioId}Partially update a scenario
/styles/{styleId}/pricing-scenarios/{scenarioId}Delete a scenario
/styles/{styleId}/pricing-scenarios/{scenarioId}/promotePromote a scenario onto the live cost sheet
Library Groups
Organise library items into groups.
/library-groupsList library groups
/library-groupsCreate a library group
/library-groups/{id}Get a library group
/library-groups/{id}Update a library group
/library-groups/{id}Partially update a library group
/library-groups/{id}Delete a library group
POM Diagrams
Manage reusable points-of-measure diagrams in the library.
/library-pom-diagramsList POM diagrams
/library-pom-diagramsCreate a POM diagram
/library-pom-diagrams/{id}Get a POM diagram
/library-pom-diagrams/{id}Update a POM diagram
/library-pom-diagrams/{id}Partially update a POM diagram
/library-pom-diagrams/{id}Delete a POM diagram
POM Templates
Manage reusable points-of-measure templates in the library.
/library-pom-templatesList POM templates
/library-pom-templatesCreate a POM template
/library-pom-templates/{id}Get a POM template
/library-pom-templates/{id}Update a POM template
/library-pom-templates/{id}Partially update a POM template
/library-pom-templates/{id}Delete a POM template
Issue Templates
Manage reusable sample-review issue templates in the library.
/library-issue-templatesList issue templates
/library-issue-templatesCreate an issue template
/library-issue-templates/{id}Get an issue template
/library-issue-templates/{id}Update an issue template
/library-issue-templates/{id}Partially update an issue template
/library-issue-templates/{id}Delete an issue template
Assignment & Usage
Assign library POM templates and diagrams to styles, track where they are used, and organise a style's workflows into groups.
POM Templates
/library-pom-templates/{id}/duplicateDuplicate a template, copying its current-version POM rows
/library-pom-templates/{id}/assignable-stylesList styles the template can be assigned to
/library-pom-templates/{id}/assign-stylesAssign the template to one or more styles (per-style outcomes reported)
/library-pom-templates/{id}/using-stylesList styles currently using the template
/library-pom-templates/{id}/poms/{pomId}Update a single POM row belonging to the template
/library-pom-templates/{id}/poms/{pomId}Delete a single POM row belonging to the template
POM Diagrams
/library-pom-diagrams/{id}/assigned-stylesList styles linked to the diagram (pass assigned_only=true to restrict)
/library-pom-diagrams/{id}/assign-stylesSync the diagram's style assignments to the given selection
/library-pom-diagrams/from-styleCreate a diagram from an existing style (clones the style's linked diagram if present)
Workflow Groups
/workflow-groups/{id}/add-workflowsAdd workflows to a group and recalculate its completion percentage
/workflow-groups/{id}/remove-workflowsRemove workflows from a group (they become ungrouped)
/styles/{styleId}/workflow-groups/move-workflowsMove workflows between groups on a style (null target = ungrouped)
Sales Cancellations
Cancellations against sales orders, with confirm / undo state transitions.
/sales-cancellationsList sales cancellations
/sales-cancellations/{id}Get a sales cancellation
/sales-cancellationsCreate a sales cancellation
/sales-cancellations/{id}Update a sales cancellation
/sales-cancellations/{id}Partially update a sales cancellation
/sales-cancellations/{id}Delete a sales cancellation
/sales-cancellations/{id}/confirmConfirm a sales cancellation
/sales-cancellations/{id}/undoUndo a confirmed sales cancellation
Sales Returns
Returns against sales orders, with confirm / undo state transitions.
/sales-returnsList sales returns
/sales-returns/{id}Get a sales return
/sales-returnsCreate a sales return
/sales-returns/{id}Update a sales return
/sales-returns/{id}Partially update a sales return
/sales-returns/{id}Delete a sales return
/sales-returns/{id}/confirmConfirm a sales return
/sales-returns/{id}/undoUndo a confirmed sales return
Production Batches
The sales-order → purchase-order MRP bridge. Preview, commit or cancel a batch.
/production-batchesList production batches
/production-batchesCreate a production batch
/production-batches/{id}Get a production batch
/production-batches/{id}Update a production batch
/production-batches/{id}Partially update a production batch
/production-batches/{id}Delete a production batch
/production-batches/{id}/previewPreview the POs a batch would generate
/production-batches/{id}/commitCommit the batch and generate POs
/production-batches/{id}/cancelCancel a production batch
Activity Log
Read-only audit trail of changes across your account.
/activitiesList activity log entries
/activities/{id}Get a specific activity entry
Scheduled Reports
Configure recurring reports, trigger ad-hoc runs and inspect execution history.
/scheduled-reportsList scheduled reports
/scheduled-reportsCreate a scheduled report
/scheduled-reports/{id}Get a scheduled report
/scheduled-reports/{id}Update a scheduled report
/scheduled-reports/{id}Partially update a scheduled report
/scheduled-reports/{id}Delete a scheduled report
/scheduled-reports/{id}/run-nowTrigger a report run immediately
/scheduled-reports/{id}/send-testSend a test delivery
/scheduled-reports/{id}/executionsList execution history for a report
Note Categories
Manage and reorder the categories used to organise notes.
/note-categoriesList note categories
/note-categoriesCreate a note category
/note-categories/reorderReorder note categories
/note-categories/{id}Get a note category
/note-categories/{id}Update a note category
/note-categories/{id}Partially update a note category
/note-categories/{id}Delete a note category
Budget Tracking
Record and query actual spend tracked against season budgets.
/budget-trackingList budget tracking entries
/budget-trackingCreate a budget tracking entry
/budget-tracking/{id}Get a budget tracking entry
Milestones
Critical-path (T&A) milestones per season: dates, sign-off, dependencies and cascading date changes, with the same refusals as the app. Read with milestones:read, write with milestones:write.
/milestonesList milestones
/milestonesCreate a milestone
/milestones/{id}Get a milestone
/milestones/{id}Update a milestone (PATCH also accepted)
/milestones/{id}Delete a milestone
/milestones/{id}/completionSign a milestone off or reopen it
/milestones/{id}/cascadePush a date change through dependent milestones
/milestone-dependenciesCreate a dependency between milestones
/milestone-dependencies/{id}Remove a dependency
List Milestones
| Parameter | Type | Description |
|---|---|---|
season_id | integer | Only this season's critical path |
workflow_id | integer | Only phases of this milestone definition |
is_completed | boolean | Filter by sign-off |
include | string | season |
updated_since | datetime | Only records updated at or after this time |
Critical-Path Templates
Reusable critical paths. Preview what a template would create for a season, then apply it. Needs milestones:read / milestones:write.
/milestone-templatesList templates
/milestone-templatesCreate a template
/milestone-templates/{id}Get a template
/milestone-templates/{id}Update a template
/milestone-templates/{id}Delete a template
/milestone-templates/{id}/previewPreview the milestones a template would create (read scope)
/milestone-templates/{id}/applyApply a template
T&A Board
The time-and-action board as the app renders it: one row per style and colourway, one column per milestone. Needs milestones:read.
/tna-boardThe T&A board for a season
| Parameter | Type | Description |
|---|---|---|
season_id | integer | The season; falls back to the first season with a critical path |
delivery_id | integer | One drop: columns carry that drop's dates and rows narrow to its styles |
supplier_id | string | Comma-separated supplier ids |
sample_stage_id | string | Comma-separated sample stage ids |
is_production | boolean | 1 production styles only, 0 sampling only |
search | string | Match style code, name, supplier or variant |
Showroom Events
Agency showroom events. What a key sees depends on who owns it: an agency key sees its own events, a brand key only its own brands’ participation. Needs showroom:read.
/showroom/eventsList events
/showroom/events/{id}Get an event with its brands
Appointments & Attendees
The visit diary for an event. An agency key books visits; a brand key requests them. Moving an appointment through its statuses needs showroom:write. Confirmation mail to buyers is throttled to 50 per key per day.
/showroom/events/{eventId}/appointmentsList an event's appointments
/showroom/events/{eventId}/appointmentsBook (agency) or request (brand) a visit
/showroom/appointments/{id}Get an appointment
/showroom/appointments/{id}Update an appointment (agency; PATCH also accepted)
/showroom/appointments/{id}/confirmConfirm (mails the buyer; throttled)
/showroom/appointments/{id}/check-inCheck the visitor in
/showroom/appointments/{id}/completeComplete the visit
/showroom/appointments/{id}/no-showMark as no-show
/showroom/appointments/{id}/rescheduleMove to another time (starts_at, ends_at, force)
/showroom/appointments/{id}/cancelCancel
/showroom/appointments/{id}/attendeesList attendees
/showroom/appointments/{id}/attendeesAdd an attendee (agency)
/showroom/appointments/{id}/attendees/{attendeeId}Update an attendee (agency; PATCH also accepted)
/showroom/appointments/{id}/attendees/{attendeeId}Remove an attendee (agency)
List Appointments
| Parameter | Type | Description |
|---|---|---|
date | date | One local day (event timezone) |
from | date | From this local day |
to | date | Up to and including this local day |
status | string | Comma-separated statuses, e.g. requested,confirmed |
brand_id | integer | Filter by brand |
buyer_id | integer | Filter by buyer |
customer_id | integer | Filter by customer |
Buyer & Customer Selections
Read-only selections: what buyers picked at showroom visits, and what customers saved in the customer portal. Needs showroom:read.
/showroom/selectionsList buyer selections
/showroom/selections/{id}Get a selection with its items
/showroom/selections/{id}/itemsA selection's items
/customer-selectionsList customer-portal selections
/customer-selections/{id}Get a customer-portal selection with its items
Merch Metrics
Read-only merchandising metrics computed the same way as the app’s merch screens. Needs reports:read.
/merch/metrics/{metric}One metric: rate_of_sale, could_have_sold, sell_through, cover, size_availability, stock_age, mix_vs_stock or order_book
| Parameter | Type | Description |
|---|---|---|
from | date | Start of the period |
to | date | End of the period |
season_id | integer | Filter by season |
style_ids | string | Comma-separated style ids |
variant_ids | string | Comma-separated variant ids |
location_ids | string | Comma-separated location ids |
channels | string | Comma-separated sales channels |
grain | string | Time grain of the series |
dimension | string | Group results by this dimension |
Markdown Batches
Draft a markdown across styles, preview the new prices, apply them and revert if needed. Read with merch:read, write with merch:write. Preview stores the recomputed figures on the draft, so it needs write.
/merch/markdown-batchesList markdown batches (status: draft, pushed, reverted; season_id)
/merch/markdown-batchesCreate a draft batch
/merch/markdown-batches/{id}Get a batch
/merch/markdown-batches/{id}Update a draft: name, notes, channel_scope, lines, remove_style_ids (PATCH also accepted)
/merch/markdown-batches/{id}/linesA batch's lines
/merch/markdown-batches/{id}/previewRecompute and preview the new prices (merch:write)
/merch/markdown-batches/{id}/applyApply the markdown
/merch/markdown-batches/{id}/revertRevert an applied markdown
Create Markdown Batch
| Parameter | Type | Description |
|---|---|---|
style_idsRequired | integer[] | 1-500 styles |
name | string | Batch name |
season_id | integer | Season |
depth_pct | number | Markdown depth applied to every line |
channel_scope | object | market_ids[] and include_base |
notes | string | Notes (max 2,000 characters) |
Allocation Runs
Allocate stock across stores or customers: create a run, preview the split, then commit or cancel it. Needs merch:read / merch:write.
/merch/allocation-runsList allocation runs (status: draft, committed, cancelled; season_id)
/merch/allocation-runsCreate a run (name, season_id, notes)
/merch/allocation-runs/{id}Get a run
/merch/allocation-runs/{id}/previewPreview the allocation
/merch/allocation-runs/{id}/commitCommit the run
/merch/allocation-runs/{id}/cancelCancel the run
Preview
| Parameter | Type | Description |
|---|---|---|
style_idsRequired | integer[] | 1-500 styles |
total_units_per_style | integer | Units to allocate per style |
grade_weights | object | Weight per store grade |
size_curve_id | integer | Size curve to split by |
Stock Holds
Hold stock back from sale (faulty, sample, charity or other) and release it later. Needs merch:read / merch:write.
/merch/stock-holdsList stock holds (status: active, released, all)
/merch/stock-holdsHold stock
/merch/stock-holds/{id}Get a hold
/merch/stock-holds/{id}Update a hold (PATCH also accepted)
/merch/stock-holds/{id}/releaseRelease a hold
Create Stock Hold
| Parameter | Type | Description |
|---|---|---|
inventory_idRequired | integer | Inventory row to hold from |
reasonRequired | string | faulty, sample, charity or other |
size | string | Size to hold |
units | integer | Units to hold |
note | string | Note (max 2,000 characters) |
Webhooks
Webhooks allow you to receive real-time notifications when events occur in Kōbō PLM. When you configure a webhook, Kōbō 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 |
style.techpack_generated | A tech pack was generated for a style |
style.sample_review_generated | A sample review document was generated for a style |
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.deleted | A PO was deleted |
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 |
inventory.out_of_stock | Inventory reached zero |
inventory.transferred | Inventory was transferred between locations |
inventory.reserved | Inventory was reserved |
inventory.unreserved | An inventory reservation was released |
inventory.checked_in | Inventory was checked in |
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.deleted | A sales order was deleted |
sales_order.status_changed | A sales order's status changed |
Delivery Events
| Event | Description |
|---|---|
delivery.created | A new delivery was created |
delivery.updated | A delivery was updated |
delivery.deleted | A delivery was deleted |
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.deleted | A task was deleted |
task.completed | A task was marked complete |
task.status_changed | A task's status changed |
Project Events
| Event | Description |
|---|---|
project.created | A new project was created |
project.updated | A project was updated |
project.deleted | A project was deleted |
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 |
payment.deleted | A payment was deleted |
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 |
POM Events
| Event | Description |
|---|---|
pom.created | A point of measure was added |
pom.updated | A point of measure was updated |
pom.deleted | A point of measure was removed |
Note Events
| Event | Description |
|---|---|
note.created | A new note was created |
note.updated | A note was updated |
note.deleted | A note was deleted |
Notification Events
| Event | Description |
|---|---|
notification.created | A new notification was created |
notification.read | A notification was marked as read |
notification.deleted | A notification was deleted |
Invoice Events
| Event | Description |
|---|---|
invoice.created | A new invoice was created |
invoice.updated | An invoice was updated |
invoice.deleted | An invoice was deleted |
invoice.status_changed | An invoice's status changed |
Credit Note Events
| Event | Description |
|---|---|
credit_note.created | A new credit note was created |
credit_note.updated | A credit note was updated |
credit_note.deleted | A credit note was deleted |
credit_note.status_changed | A credit note's status changed |
Order Confirmation Events
| Event | Description |
|---|---|
order_confirmation.created | A new order confirmation was created |
order_confirmation.updated | An order confirmation was updated |
order_confirmation.deleted | An order confirmation was deleted |
order_confirmation.status_changed | An order confirmation's status changed |
Goods Receipt Events
| Event | Description |
|---|---|
goods_receipt.created | A new goods receipt was created |
goods_receipt.updated | A goods receipt was updated |
goods_receipt.deleted | A goods receipt was deleted |
Sales Shipment Events
| Event | Description |
|---|---|
sales_shipment.created | A new shipment was created |
sales_shipment.updated | A shipment was updated |
sales_shipment.deleted | A shipment was deleted |
sales_shipment.status_changed | A shipment's status changed |
Packing List Events
| Event | Description |
|---|---|
packing_list.created | A new packing list was created |
packing_list.updated | A packing list was updated |
packing_list.deleted | A packing list was deleted |
packing_list.status_changed | A packing list's status changed |
Delivery Note Events
| Event | Description |
|---|---|
delivery_note.created | A new delivery note was created |
delivery_note.updated | A delivery note was updated |
delivery_note.deleted | A delivery note was deleted |
Pick Ticket Events
| Event | Description |
|---|---|
pick_ticket.created | A new pick ticket was created |
pick_ticket.updated | A pick ticket was updated |
pick_ticket.deleted | A pick ticket was deleted |
pick_ticket.status_changed | A pick ticket's status changed |
Sales Order Payment Events
| Event | Description |
|---|---|
sales_order_payment.created | A new sales order payment was recorded |
sales_order_payment.updated | A sales order payment was updated |
sales_order_payment.deleted | A sales order payment was deleted |
sales_order_payment.status_changed | A sales order payment's status changed |
Cancellation Events
| Event | Description |
|---|---|
cancellation.created | A cancellation was requested (purchase or sales order) |
cancellation.approved | A cancellation was approved |
cancellation.rejected | A cancellation was rejected |
Return Events
| Event | Description |
|---|---|
return.created | A return was created (purchase or sales order) |
return.updated | A return was updated |
return.deleted | A return was deleted |
return.confirmed | A return was confirmed |
Quotation Events
| Event | Description |
|---|---|
quotation.created | A new quotation request was created |
quotation.updated | A quotation was updated |
quotation.deleted | A quotation was deleted |
quotation.status_changed | A quotation's status changed |
Variant Events
| Event | Description |
|---|---|
variant.created | A new variant (colourway) was created |
variant.updated | A variant was updated |
variant.deleted | A variant was deleted |
Colour Events
| Event | Description |
|---|---|
colour.created | A new colour library entry was created |
colour.updated | A colour was updated |
colour.deleted | A colour was deleted |
Material Events
| Event | Description |
|---|---|
material.created | A new material library entry was created |
material.updated | A material was updated |
material.deleted | A material was deleted |
Lab Dip Events
| Event | Description |
|---|---|
labdip.created | A new lab dip was created |
labdip.updated | A lab dip was updated |
labdip.deleted | A lab dip was deleted |
QC Inspection Events
| Event | Description |
|---|---|
qc_inspection.created | A new QC inspection was created |
qc_inspection.updated | A QC inspection was updated |
qc_inspection.deleted | A QC inspection was deleted |
Sample Review Events
| Event | Description |
|---|---|
sample_review.created | A new sample review was created |
sample_review.updated | A sample review was updated |
sample_review.deleted | A sample review was deleted |
Customer Contact Events
| Event | Description |
|---|---|
customer_contact.created | A new customer contact was created |
customer_contact.updated | A customer contact was updated |
customer_contact.deleted | A customer contact was deleted |
Brand Events
| Event | Description |
|---|---|
brand.created | A new brand was created |
brand.updated | A brand was updated |
brand.deleted | A brand was deleted |
Company Events
| Event | Description |
|---|---|
company.created | A new company was created |
company.updated | A company was updated |
company.deleted | A company was deleted |
User Events
| Event | Description |
|---|---|
user.created | A new user was created |
user.updated | A user was updated |
user.deleted | A user was deleted |
Workflow Events
| Event | Description |
|---|---|
workflow.created | A new workflow was created |
workflow.updated | A workflow was updated |
workflow.deleted | A workflow was deleted |
workflow.executed | A workflow was executed |
Style SKU Events
| Event | Description |
|---|---|
style_sku.created | A SKU was created |
style_sku.updated | A SKU was updated |
style_sku.deleted | A SKU was deleted |
Style Workflow Task Events
| Event | Description |
|---|---|
style_workflow_task.created | A workflow task was created on a style |
style_workflow_task.updated | A workflow task was updated |
style_workflow_task.status_changed | A workflow task changed status |
style_workflow_task.deleted | A workflow task was deleted |
Sample Review Issue Events
| Event | Description |
|---|---|
sample_review_issue.created | An issue was raised on a sample review |
sample_review_issue.updated | A sample review issue was updated |
sample_review_issue.status_changed | A sample review issue changed status |
sample_review_issue.deleted | A sample review issue was deleted |
File Events
| Event | Description |
|---|---|
file.uploaded | A file was uploaded |
file.updated | File metadata was updated |
file.deleted | A file was deleted |
Supplier Contact Events
| Event | Description |
|---|---|
supplier_contact.created | A supplier contact was added |
supplier_contact.updated | A supplier contact was updated |
supplier_contact.deleted | A supplier contact was deleted |
Component Sourcing Events
| Event | Description |
|---|---|
component_sourcing_request.created | A sourcing request was created |
component_sourcing_request.updated | A sourcing request was updated |
component_sourcing_request.status_changed | A sourcing request changed status |
component_sourcing_request.deleted | A sourcing request was deleted |
component_sourcing_submission.received | A supplier submission was received |
component_sourcing_submission.approved | A supplier submission was approved |
component_sourcing_submission.rejected | A supplier submission was rejected |
Purchase Order Payment Events
| Event | Description |
|---|---|
purchase_order_payment.created | A payment was recorded against a purchase order |
purchase_order_payment.updated | A purchase order payment was updated |
purchase_order_payment.deleted | A purchase order payment was deleted |
Purchase Credit Note Events
| Event | Description |
|---|---|
purchase_credit_note.created | A purchase credit note was created |
purchase_credit_note.updated | A purchase credit note was updated |
purchase_credit_note.status_changed | A purchase credit note changed status |
purchase_credit_note.deleted | A purchase credit note was deleted |
Parcel Shipment Events
| Event | Description |
|---|---|
parcel_shipment.created | A parcel shipment was created |
parcel_shipment.updated | A parcel shipment was updated |
parcel_shipment.status_changed | A parcel shipment changed status |
parcel_shipment.deleted | A parcel shipment was deleted |
Production Batch Events
| Event | Description |
|---|---|
production_batch.created | A production batch was created |
production_batch.updated | A production batch was updated |
production_batch.status_changed | A production batch changed status |
production_batch.deleted | A production batch was deleted |
Range Plan Events
| Event | Description |
|---|---|
range_plan.created | A range plan was created |
range_plan.updated | A range plan was updated |
range_plan.deleted | A range plan was deleted |
Milestone Events
| Event | Description |
|---|---|
milestone.created | A milestone was created |
milestone.updated | A milestone was updated |
milestone.completed | A milestone was completed |
milestone.deleted | A milestone was deleted |
Location Events
| Event | Description |
|---|---|
location.created | An inventory location was created |
location.updated | An inventory location was updated |
location.deleted | An inventory location was deleted |
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 | The event that fired this delivery (e.g., sample_review.updated); matches the payload's event field |
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
}https and resolve to a public address; private, loopback, link-local and metadata hosts are rejected (and re-checked on every delivery). Redirects are not followed. A company can have at most 10 webhooks.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 (openapi-generator, Swagger Codegen, or your client of choice):
Postman Collection
Import our Postman collection to start making requests straight away:
Support
- Email: hello@kobolabs.io
Last updated: November 2026