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

https://api.kobolabs.io/api/v1

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.

bash
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

  1. Log in to Kōbō PLM
  2. Go to Account Settings → API Keys
  3. Click Create API Key
  4. Select the scopes (permissions) you need
  5. 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.

ScopeDescription
*Complete access to all API resources
styles:readView styles and their details
styles:writeCreate, update, and delete styles
components:readView components and materials
components:writeCreate, update, and delete components
suppliers:readView supplier information
suppliers:writeCreate, update, and delete suppliers
customers:readView customer information
customers:writeCreate, update, and delete customers
purchase-orders:readView purchase orders
purchase-orders:writeCreate, update, and manage purchase orders
sales-orders:readView sales orders
sales-orders:writeCreate, update, and manage sales orders
inventory:readView inventory levels and locations
inventory:writeAdjust inventory levels
deliveries:readView delivery information
deliveries:writeCreate and manage deliveries
api-keys:readView API key information
api-keys:writeManage API keys
webhooks:readView webhook configurations
webhooks:writeManage webhook configurations
bom:readView bill of materials for styles
bom:writeCreate, update, and delete BOM entries
pom:readView points of measure for styles
pom:writeCreate, update, and delete POM entries
sample_requests:readView sample requests, their items and receipts
sample_requests:writeRaise, update and cancel sample requests; record receipts, approvals and dispositions
tasks:readView tasks and assignments
tasks:writeCreate, update, and manage tasks
notes:readView notes and linked entities
notes:writeCreate, update, and delete notes
projects:readView projects and their tasks
projects:writeCreate, update, and delete projects
cutting-tickets:readView cutting tickets
cutting-tickets:writeCreate, issue and cancel cutting tickets
cancellations:readView PO cancellations
cancellations:writeCreate and manage PO cancellations
returns:readView PO returns
returns:writeCreate and manage PO returns
payments:readView PO payments
payments:writeRecord and manage PO payments
stock-takes:readView stock take sessions and counts
stock-takes:writeCreate, manage stock take sessions and record counts
workflows:readView workflow definitions and executions
workflows:writeCreate, manage, and execute workflows
supplier-scores:readView supplier scores, rankings, and metrics
supplier-scores:writeCalculate scores and record performance metrics
size-ranges:readView size range configurations
currencies:readView currency configurations
lookups:readView reference data: style categories, style tags, markets, sales channels, payment terms, incoterms, tax rates
files:readList and download files/attachments on styles, orders, components and more
files:writeUpload, update and delete files/attachments
notifications:readView notifications
notifications:writeSend and manage notifications
materials:readView the materials/fabrics catalog
materials:writeCreate, update, and delete tenant-custom materials
production-batches:readView production batches and their purchase orders
production-batches:writeCreate, commit, and cancel production batches
pricing:readView style and component pricing
pricing:writeSet style/component pricing and market pricing
library:readView library groups, POM diagrams/templates, and issue templates
library:writeCreate, update, and delete library items
comments:readView style comments
comments:writeCreate, update, and delete style comments
compliance:readView style and component compliance / DPP data
compliance:writeUpdate style and component compliance / DPP data
budgets:readView season budgets and tracking entries
budgets:writeManage budgets and record tracking entries
reports:readView scheduled reports and executions
reports:writeCreate, manage, and run scheduled reports
activities:readView the activity / audit log
seasons:readView seasons and their drops (season deliveries)
seasons:writeCreate, update, reorder and delete seasons and their drops
milestones:readView milestones, critical-path templates and the T&A board
milestones:writeCreate, update, sign off and delete milestones and dependencies; manage and apply critical-path templates
exchange_rates:readView dated sales exchange rates
exchange_rates:writeCreate, update and delete sales exchange rates
showroom:readView showroom events, appointments, attendees and buyer/customer selections
showroom:writeBook, update and move appointments through their statuses; manage attendees
merch:readView markdown batches, allocation runs and stock holds
merch:writeDraft and apply markdown batches, run allocations, hold and release stock
shipments:readView inbound shipments / ASN (POs, deliveries, cartons, tracking), sales shipments, carrier accounts and shipping rules
shipments:writeAttach, detach and move purchase orders on inbound shipments, manage sales shipments and shipping rules
colors:readView colours
colors:writeCreate, update and delete colours
component-reservations:readView component reservations
component-reservations:writeCreate, update and delete component reservations
component_sourcing:readView component sourcing
component_sourcing:writeCreate, update and delete component sourcing
credit_notes:readView credit notes
credit_notes:writeCreate, update and delete credit notes
delivery_notes:readView delivery notes
delivery_notes:writeCreate, update and delete delivery notes
goods_receipts:readView goods receipts
goods_receipts:writeCreate, update and delete goods receipts
invoices:readView invoices
invoices:writeCreate, update and delete invoices
labdips:readView lab dips
labdips:writeCreate, update and delete lab dips
library-constructions:readView library constructions
library-constructions:writeCreate, update and delete library constructions
linesheets:readView line sheets
linesheets:writeCreate, update and delete line sheets
locations:readView locations
locations:writeCreate, update and delete locations
moodboards:readView moodboards
moodboards:writeCreate, update and delete moodboards
order_confirmations:readView order confirmations
order_confirmations:writeCreate, update and delete order confirmations
packing_lists:readView packing lists
packing_lists:writeCreate, update and delete packing lists
pick_tickets:readView pick tickets
pick_tickets:writeCreate, update and delete pick tickets
quality_control:readView quality control
quality_control:writeCreate, update and delete quality control
quotations:readView quotations
quotations:writeCreate, update and delete quotations
range_plans:readView range plans
range_plans:writeCreate, update and delete range plans
sales-cancellations:readView sales cancellations
sales-cancellations:writeCreate, update and delete sales cancellations
sales-returns:readView sales returns
sales-returns:writeCreate, update and delete sales returns
sample_reviews:readView sample reviews
sample_reviews:writeCreate, update and delete sample reviews
tech_packs:readView tech packs
tech_packs:writeCreate, update and delete tech packs

Rate Limiting

Requests are limited at two levels, and the first limit reached wins:

LimitAllowance
Per API keyThe key’s own rate_limit per minute (100 by default)
Per company, per minute300 requests, summed across all of the company’s keys
Per company, per day20,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):

http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699574400
Rate Limit Exceeded
Over any limit you receive 429 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:

ParameterTypeDescription
pageintegerPage number (default: 1)
per_pageintegerItems per page (default: 25, max: 100)

Response includes pagination metadata:

json
{
  "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:

ParameterTypeDescription
updated_sincedatetimeISO 8601 datetime (e.g., 2024-01-01T00:00:00Z)
created_sincedatetimeISO 8601 datetime (e.g., 2024-01-01T00:00:00Z)
bash
# 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.

bash
# 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.

ParameterTypeDescription
includestringComma-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.

EndpointRelations you can include
/budgetstrackingEntries
/colorslabdips files components styles
/component-inventorystyle location component reservations variant
/component-reservationsinventory
/component-sourcingfiles
/componentscomponentPricing inventories purchaseOrders primaryImageFile boms componentUnits files variants sourcingRequests
/credit-notesstyles
/customerssalesOrders addresses contacts defaultBillingAddress defaultShippingAddress primaryContact invoices masterCustomer linkedCustomers accessibleStyles brands
/deliveriespurchaseOrder brandLocation contact items parcelShipment discrepancies
/filesstyle component supplier customer note issueTemplate section styleSection purchaseOrder salesOrder qcInspection
/goods-receiptssupplier
/inventorystyle location component reservations variant
/invoicessalesOrder customer items payments pickTicket shipment depositInvoice balanceInvoices
/labdipsstyles
/library-issue-templatesfiles
/library-pom-diagramsstyles
/milestonesseason
/note-categoriesnotes
/notesseasons salesOrders attachments
/packing-listsfromLocation toLocation items
/parcel-shipmentssupplier deliveries
/pick-ticketsstyles
/production-batchessourceSalesOrder
/projectsseason sharedWithSuppliers
/purchase-orderscancellations productionBatch returns creditNotes files statusHistory bankAccount billToLocation incoterm checkIns styleCheckIns tags
/quality-controlattachments
/quotationssupplier styles priceHistory valueAddedServices
/range-plansseason rangePlanStyles market
/sales-orderssalesStyles brandLocation productionBatch files payments salesOrderPayments pickTickets deliveryNotes creditNotes returns cancellations orderConfirmation shippingMethod market statusHistory
/sales-shipmentssalesOrder pickTicket items invoice
/sample-requestsstyle reviews
/sample-reviewsstyle sampleRequest
/season-deliveriesseason
/seasonssuppliers budgets activeBudget drops
/style-compliancestyle
/style-inventorystyle location component reservations variant
/style-pricingstyle budgetTracking
/stylesseason 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-sectionsfiles
/styles/{styleId}/pomdiagram
/styles/{styleId}/pricing-scenariosquotationRequest
/suppliersstyles locations purchaseOrders brands components performanceMetrics score users
/tasksstatus taskLabel project assignedTo assignedBy milestones customer

Error Handling

The API uses standard HTTP status codes:

CodeDescription
200Success
201Created
204No Content (successful delete)
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Insufficient permissions
404Not Found
422Validation Error
429Rate Limited
500Server Error

Error responses include details:

json
{
  "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.

AreaLimitWhen exceeded
RequestsKey’s rate_limit/min; 300/min and 20,000/day per company429 rate_limit_exceeded
Document send1–5 recipients; subject ≤ 191 chars; message ≤ 2,000 chars422 validation_error
Document send recipientsEach must be a user of your company or a contact of the document’s customer or supplier422 per-recipient error under errors.recipients.N
Document send throttle3 sends per document per 15 minutes; 50 sends per key per day429 rate_limit_exceeded
File uploadsAllowed extensions only; 25 MB per file; 500 uploads per company per day422 (type/size) or 429 upload_limit_exceeded
WebhooksHTTPS public URL only; at most 10 webhooks per company422
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 users422 / 429
Customer portal invitations20 per key per day429
Showroom booking mailConfirmation emails from appointment actions: 50 per key per day429

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.

ParameterTypeDescription
recipientsRequiredstring[]1–5 email addresses, no duplicates
subjectstringOptional subject (max 191 characters)
messagestringOptional message body (max 2,000 characters)
bash
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

StatusMeaning
403insufficient_scope — the key lacks a scope; the response lists required_scopes
409The record’s state refuses the action — e.g. a locked budget, a delivery already checked in, an invalid status transition
422Validation failed, or a referenced id belongs to another company; errors names each field
429A 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:

EndpointWhat changed
POST /linesheets/{id}/generateNow renders the real linesheet and returns the PDF itself (Content-Type: application/pdf) instead of a JSON “queued” message.
POST /linesheets/{id}/shareNow 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}/convertNow 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}/receiveNow 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 writesA locked budget now refuses changes with 409. Use the new lock/unlock endpoints.
Quotation status changesGo 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 statusOnly valid transitions are accepted; others return 409 or 422.
Rate limitsCompany-wide limits (300/min, 20,000/day) apply across all keys, on top of each key’s own limit.
Webhooks, uploads, scheduled reportsNew guards — see Limits & Errors.
Fixed fieldsSupplier 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.
New scopes
Scopes such as 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.

GET/styles

List all styles with optional filtering and pagination

GET/styles/{id}

Get a specific style by ID

POST/styles

Create a new style

PUT/styles/{id}

Update an existing style

DELETE/styles/{id}

Delete a style

POST/styles/{id}/duplicate

Duplicate a style

POST/styles/{id}/restore

Restore an archived style

GET/styles/export

Export styles as CSV

GET/styles/trashed

List soft-deleted styles

DELETE/styles/{id}/force

Permanently delete a style

GET/styles/{id}/deletion-impact

Preview the impact of deleting a style (safety pre-check before delete)

POST/styles/import

Import styles from CSV or JSON

POST/styles/bulk-actions

Bulk update or delete up to 100 styles

PUT/styles/{id}/collections

Set the collections a style belongs to

PUT/styles/{id}/production-status

Update a style's production status

GET/styles/{id}/production-readiness

Check whether a style is ready for production

GET/styles/{id}/production-history

Production status transition history

List Styles

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page (max 100)
updated_sincedatetimeFilter by update time
created_sincedatetimeFilter by creation time
statusstringFilter by status
season_idintegerFilter by season
brand_idintegerFilter by brand (company-wide keys; each style returns its brand as { id, name })

Example Request

bash
curl "https://api.kobolabs.io/api/v1/styles?per_page=50&status=active" \
  -H "X-API-Key: your_api_key"

Example Response

json
{
  "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

bash
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.

GET/components

List all components

GET/components/{id}

Get a specific component

POST/components

Create a new component

PUT/components/{id}

Update an existing component

DELETE/components/{id}

Delete a component

POST/components/{id}/duplicate

Duplicate a component

GET/components/export

Export components as CSV

GET/components/trashed

List soft-deleted components

POST/components/{id}/restore

Restore a soft-deleted component

DELETE/components/{id}/force

Permanently delete a trashed component

POST/components/import

Import components from CSV

GET/components/{id}/transactions

Inventory transactions for a component

List Components

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
typestringFilter by component type
supplier_idintegerFilter 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

json
{
  "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

GET/suppliers

List all suppliers

GET/suppliers/{id}

Get a specific supplier

POST/suppliers

Create a new supplier

PUT/suppliers/{id}

Update an existing supplier

DELETE/suppliers/{id}

Delete a supplier

GET/suppliers/export

Export suppliers as CSV

GET/suppliers/{id}/components

List a supplier's components

GET/suppliers/{id}/styles

List styles sourced from a supplier

GET/suppliers/{id}/purchase-orders

List a supplier's purchase orders

GET/suppliers/{id}/contacts

List supplier contacts

POST/suppliers/{id}/contacts

Add a supplier contact

PUT/suppliers/{id}/contacts/{contactId}

Update a supplier contact

DELETE/suppliers/{id}/contacts/{contactId}

Delete a supplier contact

PUT/suppliers/{supplier}/lifecycle-status

Move a supplier through its per-brand lifecycle (prospect, pending_approval, approved, active, blocked)

Update Lifecycle Status

ParameterTypeDescription
statusRequiredstringprospect, pending_approval, approved, active or blocked
notestringWhy (kept on the activity entry)
brand_idintegerBrand whose relationship changes; required for a company-wide key

List Suppliers

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
countrystringFilter by country code
typestringFilter by supplier type

Example Response

json
{
  "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.

GET/suppliers/{supplierId}/certifications

List a supplier’s certifications

POST/suppliers/{supplierId}/certifications

Record a certification

GET/supplier-certifications/{id}

Get a certification

PUT/supplier-certifications/{id}

Update a certification

PATCH/supplier-certifications/{id}

Partially update a certification

DELETE/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.

GET/suppliers/{supplierId}/file-sections

List a supplier’s file sections

POST/suppliers/{supplierId}/file-sections

Create a file section

PUT/suppliers/{supplierId}/file-sections/order

Reorder file sections

GET/supplier-file-sections/{id}

Get a file section

PUT/supplier-file-sections/{id}

Update a file section

PATCH/supplier-file-sections/{id}

Partially update a file section

DELETE/supplier-file-sections/{id}

Delete a file section

Purchase Orders

GET/purchase-orders

List all purchase orders

GET/purchase-orders/{id}

Get a specific purchase order

POST/purchase-orders

Create a new purchase order (currency defaults to the supplier's; every line is in the PO's currency)

PUT/purchase-orders/{id}

Update an existing purchase order

DELETE/purchase-orders/{id}

Delete a draft purchase order

GET/purchase-orders/export

Export purchase orders as CSV

GET/purchase-orders/statuses

List available purchase order statuses

GET/purchase-orders/{id}/items

List purchase order line items

POST/purchase-orders/{id}/items

Add 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)

PUT/purchase-orders/{id}/items/{itemId}

Update a purchase order line item

DELETE/purchase-orders/{id}/items/{itemId}

Remove a purchase order line item

POST/purchase-orders/{id}/confirm

Confirm a purchase order

POST/purchase-orders/{id}/unconfirm

Revert a confirmed purchase order to draft

POST/purchase-orders/{id}/cancel

Cancel a purchase order

GET/purchase-orders/{id}/check-in-quantities

Check-in quantities received per item

GET/purchase-orders/{id}/pdf

Download the purchase order as a PDF (?sections= narrows it)

POST/purchase-orders/{id}/send

Email 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

json
{
  "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

GET/inventory

List inventory items

GET/inventory/{id}

Get a specific inventory item

PUT/inventory/{id}

Update inventory levels

POST/component-inventory/bulk-update

Bulk update inventory

GET/inventory/export

Export inventory as CSV

List Inventory

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
style_idintegerFilter by style
location_idintegerFilter by location
low_stockbooleanFilter low stock items

Bulk Update Example

json
{
  "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

GET/customers

List all customers

GET/customers/{id}

Get a specific customer

POST/customers

Create a new customer

PUT/customers/{id}

Update an existing customer

DELETE/customers/{id}

Delete a customer

GET/customers/export

Export customers as CSV

GET/customers/{id}/outstanding-invoices

Get outstanding invoices for a customer

GET/customers/{id}/overview

Get customer overview/summary

GET/customers/{id}/sales-orders

List a customer's sales orders

List Customers

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
typestringFilter by type (wholesale, retail)

Customer Addresses

Manage shipping, billing, and other addresses for customers.

GET/customers/{customerId}/addresses

List all addresses for a customer

GET/customers/{customerId}/addresses/{id}

Get a specific customer address

POST/customers/{customerId}/addresses

Create a new customer address

PUT/customers/{customerId}/addresses/{id}

Update an existing customer address

DELETE/customers/{customerId}/addresses/{id}

Delete a customer address

POST/customers/{customerId}/addresses/{id}/set-default

Set an address as the customer's default

Create Address

ParameterTypeDescription
address_typeRequiredstringType of address (e.g. shipping, billing)
address_namestringName/label for the address
is_defaultbooleanWhether this is the default address
street_addressstringStreet address
citystringCity
statestringState or province
countrystringCountry
postal_codestringPostal/ZIP code
contact_namestringContact person name
contact_emailstringContact email
contact_phonestringContact phone number
notesstringAdditional notes

Example Response

json
{
  "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.

GET/customers/{customerId}/contacts

List all contacts for a customer

GET/customers/{customerId}/contacts/{id}

Get a specific customer contact

POST/customers/{customerId}/contacts

Create a new customer contact

PUT/customers/{customerId}/contacts/{id}

Update an existing customer contact

DELETE/customers/{customerId}/contacts/{id}

Delete a customer contact

POST/customers/{customerId}/contacts/{id}/set-primary

Set a contact as the customer's primary contact

Create Contact

ParameterTypeDescription
nameRequiredstringContact person name
emailstringContact email address
phonestringContact phone number
rolestringContact role (e.g. buyer, manager)
is_primarybooleanWhether this is the primary contact
notesstringAdditional notes

Example Response

json
{
  "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

POST/customers/{customer}/copy

Duplicate a customer (with addresses, contacts, and brand links)

GET/customers/{customer}/invoices

List the full invoice history for a customer

GET/customers/{customer}/styles

List styles associated with a customer through their sales orders

Portal Access

GET/customers/{customer}/portal-access

List customer portal users and pending invitations

POST/customers/{customer}/portal-invitations

Invite a user to the customer portal

DELETE/customers/{customer}/portal-invitations/{invitation}

Cancel a pending portal invitation

DELETE/customers/{customer}/portal-access/{user}

Remove a user's customer portal access

Style Access

GET/customers/{customer}/style-access

List style access grants for a customer

POST/customers/{customer}/style-access

Grant (or update) access to one or more styles

PUT/customers/{customer}/style-access/{access}

Update a single style access grant (access type + scheduling window)

DELETE/customers/{customer}/style-access/{access}

Revoke a single style access grant

POST/customers/{customer}/style-access/bulk-revoke

Bulk 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.

GET/customers/{customerId}/file-sections

List a customer’s file sections

POST/customers/{customerId}/file-sections

Create a file section

PUT/customers/{customerId}/file-sections/order

Reorder file sections

GET/customer-file-sections/{id}

Get a file section

PUT/customer-file-sections/{id}

Update a file section

PATCH/customer-file-sections/{id}

Partially update a file section

DELETE/customer-file-sections/{id}

Delete a file section

Colors

Manage the color library used across styles and products.

GET/colors

List all colors

GET/colors/{id}

Get a specific color

GET/colors/{id}/usage

Usage summary for a color (safe-delete pre-check)

POST/colors

Create a new color

PUT/colors/{id}

Update an existing color

DELETE/colors/{id}

Delete a color

List Colors

ParameterTypeDescription
searchstringSearch by color name
group_idintegerFilter by color group
per_pageintegerItems per page (max 100)
sort_bystringSort field
sort_dirstringSort direction (asc, desc)

Create Color

ParameterTypeDescription
colour_nameRequiredstringColor name
hexstringHex color code (e.g. #FF5733)
pantone_refstringPantone reference code
starredbooleanWhether the color is starred/favorited
group_idintegerColor group ID

Example Response

json
{
  "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.

GET/seasons

List all seasons

GET/seasons/{id}

Get a specific season (include=drops for its season deliveries)

POST/seasons

Create a season

PUT/seasons/{id}

Update a season (PATCH also accepted)

DELETE/seasons/{id}

Delete a season (refused while it is in use)

POST/seasons/{id}/reorder

Move a season to a new position (body: position, 1-based)

List Seasons

ParameterTypeDescription
searchstringSearch by season name
per_pageintegerItems per page (max 100)
sort_bystringSort field
sort_dirstringSort direction (asc, desc)

Example Response

json
{
  "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.

GET/season-deliveries

List drops (filter by season_id)

POST/season-deliveries

Create a drop

GET/season-deliveries/{id}

Get a drop

PUT/season-deliveries/{id}

Update a drop (PATCH also accepted)

DELETE/season-deliveries/{id}

Delete a drop

List Drops

ParameterTypeDescription
season_idintegerOnly this season's drops
includestringseason
updated_sincedatetimeOnly drops updated at or after this time
per_pageintegerItems 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.

GET/exchange-rates

List exchange rates

POST/exchange-rates

Create an exchange rate

GET/exchange-rates/{id}

Get an exchange rate

PUT/exchange-rates/{id}

Update an exchange rate (PATCH also accepted)

DELETE/exchange-rates/{id}

Delete an exchange rate

Create Exchange Rate

ParameterTypeDescription
from_currency_idRequiredintegerSource currency
to_currency_idRequiredintegerTarget currency (must differ from the source)
rateRequirednumberUnits of the target currency per one unit of the source
effective_dateRequireddateDate the rate applies from
brand_idintegerOptional brand the rate belongs to

List filters

ParameterTypeDescription
from_currency_idintegerFilter by source currency
to_currency_idintegerFilter by target currency
effective_ondateRates 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.

GET/files

List files, filterable by any subject (style_id, component_id, ...)

GET/files/{id}

Get a specific file record

POST/files

Upload a file (multipart) against exactly one subject record

PUT/files/{id}

Update file metadata (never the binary)

PATCH/files/{id}

Partially update file metadata

DELETE/files/{id}

Soft-delete a file

GET/files/{id}/download-url

Resolve a download URL for the file

List Files

ParameterTypeDescription
style_idintegerFilter by style
component_idintegerFilter by component
purchase_order_idintegerFilter by purchase order
sales_order_idintegerFilter by sales order
customer_idintegerFilter by customer
supplier_idintegerFilter by supplier
note_idintegerFilter by note
sample_review_issue_idintegerFilter by sample review issue
variant_idintegerFilter by style variant
searchstringSearch by original file name
extensionstringFilter by file extension
is_primarybooleanFilter by primary flag
visibilitystringFilter by visibility (company, everyone, private)
per_pageintegerItems 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.

ParameterTypeDescription
fileRequiredfileThe file to upload (max 50 MB)
style_idintegerSubject: style
component_idintegerSubject: component
purchase_order_idintegerSubject: purchase order
sales_order_idintegerSubject: sales order
customer_idintegerSubject: customer
supplier_idintegerSubject: supplier
note_idintegerSubject: note
sample_review_issue_idintegerSubject: sample review issue
variant_idintegerStyle variant (only with style_id)
section_idintegerStyle file section (only with style_id)
visibilitystringcompany, everyone or private (default: company)
supplier_visiblebooleanWhether suppliers can see the file
client_visiblebooleanAgency 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_levelstringself_only, company_team or admins_only
include_in_techpackbooleanInclude the file in tech pack exports
is_primarybooleanMark as the subject's primary file/image
tagsarrayTags for the file

Example Request

bash
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

json
{
  "success": true,
  "data": {
    "url": "https://storage.googleapis.com/.../techpack-sketch.png",
    "file_name": "techpack-sketch.png",
    "mime_type": "image/png",
    "size": 245120
  }
}
Deletion is Always Soft
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.

GET/bom/{id}

Get a specific BOM item

PUT/bom/{id}

Update a BOM item

DELETE/bom/{id}

Delete a BOM item

GET/styles/{styleId}/bom

Get BOM for a specific style

POST/styles/{styleId}/bom

Add component to style BOM

POST/styles/{styleId}/bom/bulk

Bulk-add multiple components to a style's BOM in one request

POST/bom/bulk-replace

Replace a component across multiple BOM rows in one request

DELETE/styles/{styleId}/bom

Clear ALL BOM entries for a style — requires confirm: true in the payload

POST/bom/{id}/colors

Assign a library colour to a BOM entry

DELETE/bom/{id}/colors/{colorId}

Remove a library colour from a BOM entry

POST/bom/{id}/replace

Replace the component on a single BOM row

Bulk BOM Clear
DELETE /styles/{styleId}/bom wipes every BOM row on the style and only proceeds when the request body includes {"confirm": true}.

List BOM Items

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
style_idintegerFilter by style ID
component_idintegerFilter by component ID

Add BOM Item Example

json
{
  "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.

GET/pom/{id}

Get a specific POM item

PUT/pom/{id}

Update a POM item

DELETE/pom/{id}

Delete a POM item

GET/styles/{styleId}/pom

Get POM for a specific style

POST/styles/{styleId}/pom

Add POM item to style

PUT/styles/{styleId}/pom/positions

Reorder a style's POM rows

POST/styles/{styleId}/pom/save-template

Save a style's POMs to the library as a new POM template

GET/styles/{styleId}/pom/diagram/{diagramId}

Get a POM diagram linked to a style

PUT/styles/{styleId}/pom/diagram

Link a library POM diagram to a style

DELETE/styles/{styleId}/pom/diagram

Unlink the POM diagram from a style

PUT/styles/{styleId}/pom

Bulk update/replace all POMs for a style

List POM Items

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
style_idintegerFilter by style ID

Add POM Item Example

json
{
  "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

GET/styles/{styleId}/bom/colorway-import

List BOM items available for cross-colorway import

POST/styles/{styleId}/bom/import-from-colorway

Import selected BOM items from a peer colorway

POST/styles/{styleId}/bom/apply-to-colorways

Apply BOM items to all colorway peers

POM

GET/styles/{styleId}/pom/colorway-import

List POMs available for cross-colorway import

POST/styles/{styleId}/pom/import-from-colorway

Import selected POMs from a peer colorway

POST/styles/{styleId}/pom/apply-to-colorways

Apply POMs to all colorway peers

Quality Control

GET/styles/{styleId}/quality-control/colorway-import

List QC data available for cross-colorway import

POST/styles/{styleId}/quality-control/import-from-colorway

Import QC data from a peer colorway

POST/styles/{styleId}/quality-control/apply-to-colorways

Apply QC data to all colorway peers

Sample Review Issues

GET/styles/{styleId}/sample-review-issues/colorway-import

List sample review issues available for cross-colorway import

POST/styles/{styleId}/sample-review-issues/import-from-colorway

Import sample review issues from a peer colorway

POST/styles/{styleId}/sample-review-issues/apply-to-colorways

Apply sample review issues to all colorway peers

Variants & SKUs

Manage style variants (color/size combinations), SKUs, and colorways.

Variants

GET/styles/{id}/variants

Get style variants

POST/styles/{id}/variants

Create a style variant

POST/styles/{id}/variants/batch

Bulk-create variants in a single transaction (duplicate names skipped and reported)

PUT/styles/{id}/variants/{variantId}

Update a variant

DELETE/styles/{id}/variants/{variantId}

Delete a variant

SKUs

GET/styles/{id}/skus

Get style SKUs

POST/styles/{id}/skus

Create a SKU

PUT/styles/{id}/skus/{skuId}

Update a SKU

DELETE/styles/{id}/skus/{skuId}

Delete a SKU

Colorways

GET/styles/{id}/colorways

Get style colorways

Create Variant Example

json
{
  "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.

POST/styles/{style}/skus/assign-barcodes

Bulk-assign available pool barcodes to specific SKUs of a style

GET/styles/barcodes/available

List available (unassigned) barcodes from the inventory pool

GET/styles/barcodes/used

List barcodes already assigned to SKUs

POST/styles/barcodes/validate

Validate a barcode's format and check whether it is already in use

GET/styles/barcodes/{barcode}

Look up a barcode and the SKU it is assigned to

Assign Barcodes to SKUs

ParameterTypeDescription
typeRequiredstringBarcode type: upc, ean, code39, code128
sku_idsRequiredarraySKU IDs on the style to assign barcodes to

Validate Barcode

ParameterTypeDescription
barcodeRequiredstringThe barcode value to validate
typeRequiredstringBarcode type: upc, ean, code39, code128

Library Constructions

Manage reusable construction specifications and techniques stored in the product library.

GET/library-constructions

List constructions (paginated)

GET/library-constructions/{id}

Get a construction

POST/library-constructions

Create a construction

PUT/library-constructions/{id}

Update a construction

DELETE/library-constructions/{id}

Delete a construction

List Constructions

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
created_sincedatetimeFilter by creation time

Create Construction Example

json
{
  "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

GET/sales-orders

List all sales orders

GET/sales-orders/{id}

Get a specific sales order

POST/sales-orders

Create a new sales order

PUT/sales-orders/{id}

Update an existing sales order

DELETE/sales-orders/{id}

Delete a sales order

POST/sales-orders/{id}/status

Update sales order status

POST/sales-orders/{id}/invoice

Create invoice from sales order

POST/sales-orders/{id}/unconfirm

Unconfirm a sales order

GET/sales-orders/{id}/items

List sales order line items

POST/sales-orders/{id}/items

Add a line item to a sales order

PUT/sales-orders/{id}/items/{itemId}

Update a sales order line item

DELETE/sales-orders/{id}/items/{itemId}

Remove a sales order line item

GET/sales-orders/{id}/styles

Styles on a sales order

GET/sales-orders/{id}/fulfilment-quantities

Fulfilment quantities per line

GET/sales-orders/{id}/download-pdf

Download the sales order as a PDF

POST/sales-orders/{id}/confirm

Confirm a sales order

POST/sales-orders/{id}/cancel

Cancel a sales order

POST/sales-orders/{id}/complete

Mark a sales order as completed

Status Values

draft, pending,confirmed, processing,shipped, delivered,cancelled

Update Status Example

json
{
  "status": "confirmed",
  "notes": "Order confirmed by warehouse"
}

Invoices

Create and manage invoices linked to sales orders.

GET/invoices

List all invoices

GET/invoices/{id}

Get a specific invoice

POST/invoices

Create a new invoice

PUT/invoices/{id}

Update an invoice

POST/invoices/{id}/confirm

Confirm a draft invoice

POST/invoices/{id}/cancel

Cancel an invoice

DELETE/invoices/{id}

Delete an invoice

POST/invoices/{id}/items

Add a line item to an invoice

PUT/invoices/{id}/items/{itemId}

Update an invoice line item

DELETE/invoices/{id}/items/{itemId}

Remove an invoice line item

POST/invoices/{id}/recalculate-totals

Recalculate invoice totals from its lines

POST/invoices/{id}/unconfirm

Revert a confirmed invoice to draft

POST/invoices/{id}/restore

Restore a deleted invoice

GET/invoices/{id}/download-pdf

Download the invoice as a PDF

POST/invoices/{id}/send

Email the invoice PDF (guarded send; see Documents)

GET/sales-orders/{id}/invoiceable-lines

What 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.

ParameterTypeDescription
sales_order_idRequiredintegerThe sales order to invoice
linesobject[][{sales_order_style_id, sizes: {S: 2, M: 3}}] or [{sales_order_style_id, quantity: 5}]
json
{
  "sales_order_id": 981,
  "lines": [
    { "sales_order_style_id": 5521, "sizes": { "S": 2, "M": 3 } },
    { "sales_order_style_id": 5522, "quantity": 10 }
  ]
}

List Invoices

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status (draft, confirmed, cancelled)
sales_order_idintegerFilter by sales order
customer_idintegerFilter by customer

Create Invoice Example

json
{
  "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.

GET/credit-notes

List all credit notes

GET/credit-notes/{id}

Get a specific credit note

POST/credit-notes

Create a credit note

PUT/credit-notes/{id}

Update a credit note

DELETE/credit-notes/{id}

Delete a credit note

POST/credit-notes/{id}/issue

Issue a credit note

POST/credit-notes/{id}/unissue

Revert an issued credit note to draft

POST/credit-notes/{id}/apply

Apply a credit note against an invoice

POST/credit-notes/{id}/void

Void a credit note

POST/credit-notes/{id}/unvoid

Restore a voided credit note

List Credit Notes

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time

Create Credit Note Example

json
{
  "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.

GET/sales-order-payments

List all sales order payments

GET/sales-order-payments/{id}

Get a specific payment

POST/sales-order-payments

Record a payment

PUT/sales-order-payments/{id}

Update a payment

DELETE/sales-order-payments/{id}

Delete a payment

GET/sales-order-payments/summary

Payment totals summary across sales orders

List Payments

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
sales_order_idintegerFilter by sales order

Record Payment Example

json
{
  "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.

GET/pick-tickets

List all pick tickets

GET/pick-tickets/{id}

Get a specific pick ticket

POST/pick-tickets

Create a pick ticket

PUT/pick-tickets/{id}

Update a pick ticket

DELETE/pick-tickets/{id}

Delete a pick ticket

POST/pick-tickets/{id}/mark-picked

Mark a pick ticket as picked

POST/pick-tickets/{id}/unmark-picked

Revert a pick ticket to unpicked

POST/pick-tickets/{id}/perform-pick

Record the actual pick per size; short picks release the shortfall and re-reserve, as in the app

GET/pick-tickets/{id}/download-pdf

Download the pick ticket PDF

POST/pick-tickets/{id}/send

Email the pick ticket PDF (guarded send)

Perform Pick

ParameterTypeDescription
stylesRequiredobject[]One row per style: style_id, quantity {size: units picked}

List Pick Tickets

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time

Delivery Notes

Manage delivery notes linked to sales orders. Supports soft delete.

GET/delivery-notes

List all delivery notes

GET/delivery-notes/{id}

Get a specific delivery note (includes salesOrder, items)

POST/delivery-notes

Create a new delivery note

PUT/delivery-notes/{id}

Update an existing delivery note

DELETE/delivery-notes/{id}

Delete a delivery note (soft delete)

List Delivery Notes

ParameterTypeDescription
searchstringSearch delivery notes
statusstringFilter by status
sales_order_idintegerFilter by sales order
per_pageintegerItems per page (max 100)
sort_bystringSort field
sort_dirstringSort direction (asc, desc)

Create Delivery Note

ParameterTypeDescription
sales_order_idRequiredintegerAssociated sales order
delivery_dateRequireddateDelivery date
statusstringDelivery note status
notesstringAdditional notes
tracking_numberstringShipment tracking number
carrierstringShipping carrier name

Example Response

json
{
  "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.

GET/packing-lists

List all packing lists

GET/packing-lists/{id}

Get a specific packing list (includes fromLocation, toLocation, items)

POST/packing-lists

Create a new packing list

PUT/packing-lists/{id}

Update an existing packing list

DELETE/packing-lists/{id}

Delete a packing list

List Packing Lists

ParameterTypeDescription
searchstringSearch packing lists
statusstringFilter by status
per_pageintegerItems per page (max 100)
sort_bystringSort field
sort_dirstringSort direction (asc, desc)

Create Packing List

ParameterTypeDescription
from_location_idRequiredintegerSource location ID
to_location_idRequiredintegerDestination location ID
statusstringPacking list status
notesstringAdditional notes
packed_datedateDate packed

Example Response

json
{
  "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.

GET/sales-shipments

List all shipments

GET/sales-shipments/{id}

Get a specific shipment

POST/sales-shipments

Create a shipment

PUT/sales-shipments/{id}

Update a shipment

DELETE/sales-shipments/{id}

Delete a shipment

POST/sales-shipments/{id}/update-status

Update shipment status

POST/sales-shipments/{id}/mark-shipped

Mark a shipment as shipped

POST/sales-shipments/{id}/unmark-shipped

Revert a shipment to unshipped

POST/sales-shipments/{id}/mark-delivered

Mark a shipment as delivered

GET/sales-shipments/{id}/commercial-invoice-pdf

Download the commercial invoice. Refused with 422 while a line has no HS code or country of origin.

GET/sales-shipments/{id}/packing-list-pdf

Download the packing list

GET/sales-shipments/{id}/carton-labels-pdf

Download the carton labels

POST/sales-shipments/{id}/unmark-delivered

Revert a shipment to undelivered

List Shipments

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status

Update Status Example

json
{
  "status": "in_transit",
  "tracking_number": "1Z999AA10123456784",
  "carrier": "UPS"
}

Order Confirmations

Manage order confirmation documents for sales orders.

GET/order-confirmations

List all order confirmations

GET/order-confirmations/{id}

Get a specific confirmation

POST/order-confirmations

Create an order confirmation

PUT/order-confirmations/{id}

Update an order confirmation

DELETE/order-confirmations/{id}

Delete an order confirmation

GET/order-confirmations/{id}/download-pdf

Download the order confirmation as a PDF

List Order Confirmations

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter 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.

GET/deliveries

List all deliveries

GET/deliveries/{id}

Get a specific delivery

List Deliveries

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status
purchase_order_idintegerFilter by PO
GET/deliveries/by-delivery-id/{deliveryId}

Get delivery by delivery ID (not internal ID)

POST/deliveries

Create a delivery against a purchase order

PUT/deliveries/{id}

Update a delivery

DELETE/deliveries/{id}

Delete a delivery

POST/deliveries/{id}/receive

Check a delivery in: moves stock, creates the check-in, relieves on-order, records sample receipts and discrepancies; 409 if already checked in

GET/deliveries/quantities/{poId}

Delivered quantities per item for a purchase order

GET/deliveries/{id}/cartons

Supplier-shipment cartons for a delivery

GET/deliveries/{id}/download-pdf

Download the delivery PDF

POST/deliveries/{id}/send

Email the delivery PDF (guarded send)

GET/deliveries/{id}/packing-list-pdf

Supplier shipment (ASN) packing list PDF

GET/deliveries/{id}/carton-labels-pdf

Supplier 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.

ParameterTypeDescription
location_idintegerLocation to receive into (defaults to the delivery's brand location)
itemsobject[]Units received: style_id, size, quantity, purchase_order_item_id (needed when a style has two PO lines)
received_notesstringStored on the check-in and appended to the delivery's internal notes
discrepancyobjectWhy a supplier-shipped delivery arrived differently: reason, note, missing_cartons
json
{
  "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.

GET/purchase-orders/{id}/short-split

Short-delivery split proposal

POST/purchase-orders/{id}/short-split

Commit a split (pick tickets per order)

POST/purchase-orders/{id}/short-split/{runId}/undo

Undo a split

GET/purchase-orders/{id}/destinations

The PO broken down by destination

POST/purchase-orders/{id}/deliveries/split-preview

Preview one delivery per destination

POST/purchase-orders/{id}/deliveries/split

Create one delivery per destination

PATCH/purchase-orders/{id}/pack-per-destination

Factory packs per destination (true, false, or null to follow the setting)

POST/purchase-orders/{id}/supplier-confirmation

Record the supplier's confirmation or a flagged issue

POST/check-ins/{checkInId}/undo

Void a check-in, reversing its stock

DELETE/check-ins/{checkInId}

Delete a check-in (undone first)

GET/purchase-orders/{id}/check-ins/{checkInId}/download-pdf

Download a check-in PDF

{checkInId} is the check-in reference string (for example CI-000123), not a numeric id.

Short-split

ParameterTypeDescription
splitsRequiredobject[]One row per order and style: sales_order_id, style_id, size_quantities {size: units}

Destination split / preview

ParameterTypeDescription
linesobject[]What is arriving per line: purchase_order_item_id, size_quantities. Omit for everything still to deliver
overridesobject[]Fix a destination's sizes for a line: purchase_order_item_id, location_id, size_quantities
delivery_datedateDelivery date for every created delivery (split only)

Supplier confirmation

ParameterTypeDescription
ack_statusRequiredstringacknowledged or flagged
notestringWhat the supplier said (required when flagged)
ship_datedateShip 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.

DocumentDownloadSendScopes
Credit noteGET /credit-notes/{id}/download-pdfPOST /credit-notes/{id}/sendcredit_notes:read / credit_notes:write
Pick ticketGET /pick-tickets/{id}/download-pdfPOST /pick-tickets/{id}/sendpick_tickets:read / pick_tickets:write
Sales shipmentGET /sales-shipments/{id}/download-pdfPOST /sales-shipments/{id}/sendshipments:read / shipments:write
Commercial invoiceGET /sales-shipments/{id}/commercial-invoice-pdf—shipments:read
Sales packing listGET /sales-shipments/{id}/packing-list-pdf—shipments:read
Sales carton labelsGET /sales-shipments/{id}/carton-labels-pdf—shipments:read
Sales returnGET /sales-returns/{id}/download-pdfPOST /sales-returns/{id}/sendsales-returns:read / sales-returns:write
Sales cancellationGET /sales-cancellations/{id}/download-pdfPOST /sales-cancellations/{id}/sendsales-cancellations:read / sales-cancellations:write
Sales orderGET /sales-orders/{id}/download-pdf—sales-orders:read
Delivery noteGET /delivery-notes/{id}/download-pdf—delivery_notes:read
Order confirmationGET /order-confirmations/{id}/download-pdfPOST /order-confirmations/{id}/sendorder_confirmations:read / order_confirmations:write
InvoiceGET /invoices/{id}/download-pdfPOST /invoices/{id}/sendinvoices:read / invoices:write
Customer statementGET /customers/{id}/statement/download-pdf—customers:read
Purchase orderGET /purchase-orders/{id}/pdfPOST /purchase-orders/{id}/sendpurchase-orders:read / purchase-orders:write
PO check-inGET /purchase-orders/{id}/check-ins/{checkInId}/download-pdf—purchase-orders:read
PO deliveryGET /deliveries/{id}/download-pdfPOST /deliveries/{id}/senddeliveries:read / deliveries:write
ASN packing listGET /deliveries/{id}/packing-list-pdf—deliveries:read
ASN carton labelsGET /deliveries/{id}/carton-labels-pdf—deliveries:read
PO cancellationGET /cancellations/{id}/download-pdfPOST /cancellations/{id}/sendcancellations:read / cancellations:write
Packing list (transfer)GET /packing-lists/{id}/download-pdfPOST /packing-lists/{id}/sendpacking_lists:read / packing_lists:write
Bill of materialsGET /styles/{styleId}/bom/download-pdfPOST /styles/{styleId}/bom/sendbom:read / bom:write
Points of measureGET /styles/{styleId}/pom/download-pdfPOST /styles/{styleId}/pom/sendpom:read / pom:write
Sample reviewGET /styles/{styleId}/variants/{variantId}/sample-review/download-pdfPOST /styles/{styleId}/variants/{variantId}/sample-review/sendsample_reviews:read / sample_reviews:write
Cost sheetGET /styles/{styleId}/pricing/download-pdf—pricing:read
QC reportGET /quality-control/{id}/download-pdf—quality_control:read
Tech packGET /tech-packs/styles/{styleId}/download-pdfPOST /tech-packs/styles/{styleId}/sendtech_packs:read / tech_packs:write
GET/credit-notes/{id}/download-pdf

Example download: the credit note PDF

POST/credit-notes/{id}/send

Example send: email the credit note PDF to up to 5 allowed recipients

Send body

ParameterTypeDescription
recipientsRequiredstring[]1-5 emails; each a user of your company or a contact of the document's customer/supplier
subjectstringOptional (max 191 characters)
messagestringOptional (max 2,000 characters)
Send limits
A document can be sent 3 times per 15 minutes and a key can send 50 documents a day. Over either limit returns 429 with Retry-After. A recipient outside the allow-list returns 422 — nothing is sent.
bash
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.

GET/parcel-shipments

List inbound shipments

GET/parcel-shipments/{id}

Get a shipment with POs, deliveries, cartons and tracking

POST/parcel-shipments/{id}/purchase-orders

Attach purchase orders (whole, or per line / pack)

DELETE/parcel-shipments/{id}/purchase-orders/{poId}

Detach a purchase order

POST/parcel-shipments/{id}/purchase-orders/{poId}/move

Move a purchase order to another shipment (target_shipment_id)

List Shipments

ParameterTypeDescription
statusstringpending, in-transit, delivered, exception, cancelled
shipment_typestringsample, materials, production, other
supplier_idintegerShipments carrying this supplier's POs
purchase_order_idintegerShipments carrying this PO
is_supplier_createdbooleanOnly supplier-created (true) or brand-created (false)
includestringsupplier, deliveries

Attach Purchase Orders

ParameterTypeDescription
purchase_order_idsinteger[]Confirmed POs to attach whole (required without allocations)
allocationsobject[]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.

GET/carrier-accounts

List carrier accounts

GET/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.

GET/shipping-rules

List shipping rules

POST/shipping-rules

Create a shipping rule

GET/shipping-rules/{id}

Get a shipping rule

PUT/shipping-rules/{id}

Update a shipping rule (PATCH also accepted)

DELETE/shipping-rules/{id}

Delete a shipping rule

Goods Receipts

Record goods received against purchase orders and deliveries.

GET/goods-receipts

List all goods receipts

GET/goods-receipts/{id}

Get a specific goods receipt

POST/goods-receipts

Create a goods receipt

PUT/goods-receipts/{id}

Update a goods receipt

DELETE/goods-receipts/{id}

Delete a goods receipt

List Goods Receipts

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
supplier_idintegerFilter by supplier

Create Goods Receipt Example

json
{
  "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.

GET/cutting-tickets

List cutting tickets

GET/cutting-tickets/{id}

Get a specific cutting ticket

POST/cutting-tickets

Create a draft cutting ticket

PUT/cutting-tickets/{id}

Update a draft cutting ticket

POST/cutting-tickets/{id}/issue

Issue the ticket to the factory

POST/cutting-tickets/{id}/cancel

Cancel a ticket. A factory that had it is told by email.

Cancellations

Manage purchase order cancellation requests with approval workflows.

GET/cancellations

List all cancellations

GET/cancellations/{id}

Get a specific cancellation

POST/cancellations

Create a cancellation request

PUT/cancellations/{id}

Update a cancellation

DELETE/cancellations/{id}

Delete a cancellation

POST/cancellations/{id}/confirm

Confirm a cancellation

POST/cancellations/{id}/undo

Undo a confirmed cancellation

Status Values

draft, pending,approved, rejected

List Cancellations

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status
purchase_order_idintegerFilter by purchase order ID

Returns

Manage purchase order returns for defective or incorrect goods.

GET/returns

List all returns

GET/returns/{id}

Get a specific return

POST/returns

Create a return

PUT/returns/{id}

Update a return

DELETE/returns/{id}

Delete a return

POST/returns/{id}/confirm

Confirm a return

Status Values

draft, confirmed,processing, completed

List Returns

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status
purchase_order_idintegerFilter by purchase order ID

Payments

Track payments against purchase orders.

GET/payments

List all payments

GET/payments/{id}

Get a specific payment

POST/payments

Create a payment

PUT/payments/{id}

Update a payment

DELETE/payments/{id}

Delete a payment

GET/payments/summary/{poId}

Get payment summary for a PO

List Payments

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status
purchase_order_idintegerFilter by purchase order ID
payment_methodstringFilter by payment method
date_fromdateFilter payments from date
date_todateFilter payments to date

Create Payment Example

json
{
  "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.

GET/budgets

List budgets (paginated)

GET/budgets/{id}

Get a budget

POST/budgets

Create a budget

PUT/budgets/{id}

Update a budget

DELETE/budgets/{id}

Delete a budget

GET/budgets/{id}/analytics

Budget analytics: overview, per-category breakdown, timeline, top suppliers, alerts

GET/budgets/{id}/comparison

Budget vs actual comparison, overall and per category

GET/budgets/{id}/tracking-entries

Paginated tracking entries for a budget

PUT/budgets/{id}/allocations

Batch upsert per-category allocations

POST/budgets/{id}/duplicate

Duplicate a budget with its category allocations (spending reset)

PUT/budgets/{id}/categories/{categoryId}/allocation

Update a budget category allocation

POST/budgets/{id}/lock

Lock the budget as the agreed version (bumps version)

POST/budgets/{id}/unlock

Unlock the budget for editing

Locked budgets
While a budget is locked, updates and allocation writes return 409. Budgets now return version, locked_at and locked_by.

List Budgets

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
created_sincedatetimeFilter by creation time

Create Budget Example

json
{
  "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.

GET/component-inventory

List component inventory

GET/component-inventory/{id}

Get a specific inventory item

POST/component-inventory

Create a component inventory record

POST/component-inventory/bulk-update

Bulk update component inventory

POST/component-inventory/{id}/check-in

Check in component inventory

List Component Inventory

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
component_idintegerFilter by component

Check In Example

json
{
  "quantity": 500,
  "reference": "PO-2024-0015",
  "notes": "Received from supplier shipment"
}

Style Inventory

Track finished goods inventory by style, size, and color.

GET/style-inventory

List style inventory

GET/style-inventory/{id}

Get a specific inventory item

PUT/style-inventory/{id}

Update inventory levels

POST/style-inventory/{id}/check-in

Check in style inventory

POST/style-inventory/{id}/transfer

Transfer inventory between locations

List Style Inventory

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
style_idintegerFilter by style
location_idintegerFilter by location

Transfer Example

json
{
  "to_location_id": 2,
  "quantity": 50,
  "notes": "Transfer to retail warehouse"
}

Inventory Operations

Advanced inventory management operations including transfers, reservations, and check-ins.

GET/inventory/summary

Get inventory summary across all locations

GET/inventory/low-stock

Get items below reorder threshold

GET/inventory/{id}/transactions

Get transaction history for an inventory item

POST/inventory/{id}/transfer

Transfer inventory between locations

POST/inventory/{id}/reserve

Reserve inventory for an order

POST/inventory/{id}/unreserve

Release reserved inventory

POST/inventory/{id}/check-in

Check in inventory from a delivery

Low Stock Query

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
thresholdintegerLow stock threshold (default: 10)

Transfer Inventory Example

json
{
  "to_location_id": 2,
  "quantity": 50,
  "notes": "Transfer to retail warehouse"
}

Reserve Inventory Example

json
{
  "quantity": 100,
  "reference_type": "sales_order",
  "reference_id": 456,
  "notes": "Reserved for SO-2024-0050"
}

Stock Takes

Manage physical inventory counts and reconciliation.

GET/stock-takes

List all stock takes

GET/stock-takes/{id}

Get a specific stock take

POST/stock-takes

Create a stock take

PUT/stock-takes/{id}

Update a stock take

DELETE/stock-takes/{id}

Delete a stock take

GET/stock-takes/statuses

Get available stock take statuses

POST/stock-takes/{id}/start

Start a stock take

POST/stock-takes/{id}/complete

Complete a stock take

POST/stock-takes/{id}/approve

Approve a completed stock take and apply adjustments

GET/stock-takes/{id}/items

Get stock take items

POST/stock-takes/{id}/cancel

Cancel a stock take

GET/stock-takes/{id}/variance-summary

Variance summary for a stock take

POST/stock-takes/{id}/items/batch-count

Record counts for multiple items at once

POST/stock-takes/{sessionId}/items/{itemId}/count

Record a count for a single item

Status Values

draft, in_progress,completed, cancelled

List Stock Takes

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status
location_idintegerFilter by location ID

Add Stock Take Item Example

json
{
  "inventory_id": 123,
  "counted_quantity": 95,
  "notes": "5 units damaged"
}

Locations

Manage warehouse and storage locations used for inventory tracking and stock takes.

GET/locations

List locations (paginated)

GET/locations/{id}

Get a location

POST/locations

Create a location

PUT/locations/{id}

Update a location

DELETE/locations/{id}

Delete a location

List Locations

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
created_sincedatetimeFilter by creation time

Create Location Example

json
{
  "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.

GET/component-reservations

List reservations (paginated)

GET/component-reservations/{id}

Get a reservation

POST/component-reservations

Create a reservation

PUT/component-reservations/{id}

Update a reservation

DELETE/component-reservations/{id}

Delete a reservation

List Reservations

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
component_idintegerFilter by component
statusstringFilter by status (active, released, expired)

Create Reservation Example

json
{
  "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.

GET/range-plans

List all range plans

GET/range-plans/{id}

Get a specific range plan

POST/range-plans

Create a range plan

PUT/range-plans/{id}

Update a range plan

DELETE/range-plans/{id}

Delete a range plan

POST/range-plans/{id}/duplicate

Duplicate a range plan

PUT/range-plans/{id}/styles/{styleId}

Update one card on the plan (prices, drop, newness, ranging...)

POST/range-plans/{id}/styles/{styleId}/convert

Convert 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

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
season_idintegerFilter by season

Create Range Plan Example

json
{
  "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.

GET/quotations

List all quotations

GET/quotations/{id}

Get a specific quotation

POST/quotations

Create a quotation

PUT/quotations/{id}

Update a quotation

DELETE/quotations/{id}

Delete a quotation

POST/quotations/{id}/revise

Create a revision of a quotation

GET/quotations/style/{styleId}

Quotations for a style

GET/quotations/supplier/{supplierId}

Quotations from a supplier

GET/quotations/price-history/style/{styleId}

Quoted price history for a style

PATCH/quotations/{id}/status

Record a decision (pending, counter-offer, approved, rejected) with an optional brand note, through the app's decision rules

Status Decision

ParameterTypeDescription
statusRequiredstringpending, counter-offer, approved or rejected
notestringBrand note saved with the decision (max 2,000 characters)

List Quotations

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
supplier_idintegerFilter by supplier
style_idintegerFilter by style

Create Quotation Example

json
{
  "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.

GET/styles/{styleId}/quote-comparison

Compare every quote on a style

PUT/styles/{styleId}/quote-comparison/weights

Set the style's score weights (price, quality, delivery)

PUT/styles/{styleId}/quote-comparison/ratings/{quotationId}

Rate a quote's quality and delivery

POST/styles/{styleId}/quote-comparison/award

Award the style to one or more quotes (allocations)

POST/styles/{styleId}/quote-comparison/award/supersede

Clear the current placement

GET/quote-weights

Brand default weights (brand_id required for a company-wide key)

PUT/quote-weights

Set brand default weights

Award Example

json
{
  "allocations": [
    { "quotation_id": 77 }
  ]
}

Linesheets

Create and manage linesheets for wholesale buyers and showrooms.

GET/linesheets

List all linesheets

GET/linesheets/{id}

Get a specific linesheet

POST/linesheets

Create a linesheet

PUT/linesheets/{id}

Update a linesheet

DELETE/linesheets/{id}

Delete a linesheet

POST/linesheets/{id}/duplicate

Duplicate a linesheet

POST/linesheets/{id}/archive

Archive a linesheet

POST/linesheets/{id}/restore

Restore an archived linesheet

POST/linesheets/{id}/share

Create a share link (token + public URL); needs linesheets:write; never sends email

POST/linesheets/{id}/generate

Render the linesheet and return the PDF (application/pdf)

PUT/linesheets/{id}/reorder

Reorder linesheet entries

List Linesheets

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
season_idintegerFilter by season

Share a Linesheet

ParameterTypeDescription
customer_idintegerCustomer the link is for
recipientstringEmail the link is recorded against (no email is sent)
expires_in_daysinteger1-365
passwordstringOptional password (4-120 characters)
allow_orderbooleanLet the viewer place an order from the link

Download the PDF

bash
curl -X POST "https://api.kobolabs.io/api/v1/linesheets/18/generate" \
  -H "X-API-Key: your_api_key" \
  -o linesheet.pdf

Linesheets 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.

GET/sample-requests

List sample requests

POST/sample-requests

Raise a sample request with at least one item

GET/sample-requests/{id}

Get a sample request with items and receipts

PUT/sample-requests/{id}

Update a sample request (PATCH also accepted)

POST/sample-requests/{id}/cancel

Cancel a sample request

POST/sample-requests/{id}/receipts

Record a receipt (lines that arrive on a PO delivery are received through check-in instead)

POST/sample-requests/{id}/approval

Record the verdict: approval_status, decided_at, note

POST/sample-requests/{id}/disposition

Record what happened to the sample

GET/styles/{styleId}/sample-requests

Sample requests for one style

List Sample Requests

ParameterTypeDescription
style_idintegerFilter by style
statusstringdraft, requested, confirmed, shipped, partially_received, received, cancelled
approval_statusstringpending, approved, approved_with_comments, rejected, not_applicable
supplier_idintegerFilter by supplier
sample_stage_idintegerFilter by sample stage
includestringstyle, reviews
updated_sincedatetimeOnly records updated at or after this time
sort_bystringid, requested_at, due_at, status, created_at, updated_at

Create Sample Request Example

json
{
  "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.

GET/sample-reviews

List all sample reviews

GET/sample-reviews/{id}

Get a specific sample review

POST/sample-reviews

Create a sample review

PUT/sample-reviews/{id}

Update a sample review

DELETE/sample-reviews/{id}

Delete a sample review

POST/sample-reviews/{id}/change-status

Change review status (approved, rejected, revision needed)

GET/sample-reviews/{reviewId}/issues

List the issues on the review's style (?version_id= for one sample stage)

POST/sample-reviews/{reviewId}/issues

Add an issue to a sample review (optional version_id = sample stage; defaults to the style's current stage)

PUT/sample-reviews/{reviewId}/issues/{issueId}

Update a sample review issue

DELETE/sample-reviews/{reviewId}/issues/{issueId}

Delete a sample review issue

List Sample Reviews

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
style_idintegerFilter by style
statusstringFilter 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

json
{
  "status": "approved",
  "comments": "Sample meets all specifications. Ready for production."
}

Quality Control

Access QC inspection reports for styles and production runs.

GET/quality-control/{id}

Get a QC inspection

GET/quality-control/{id}/report

Generate a QC inspection report

GET/quality-control

List QC inspections

POST/quality-control

Create a QC inspection

PUT/quality-control/{id}

Update a QC inspection

DELETE/quality-control/{id}

Delete a QC inspection

POST/quality-control/{id}/approve

Approve a QC inspection

POST/quality-control/{id}/reject

Reject 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

json
{
  "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.

GET/lab-tests

List lab tests

POST/lab-tests

Record a lab test

GET/lab-tests/{id}

Get a lab test

PUT/lab-tests/{id}

Update a lab test

PATCH/lab-tests/{id}

Partially update a lab test

DELETE/lab-tests/{id}

Delete a lab test

Tech Packs

Generate comprehensive tech pack documents for styles, including BOM, POM, construction details, and specifications.

GET/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.

GET/labdips

List all labdips

GET/labdips/{id}

Get a specific labdip

POST/labdips

Create a new labdip

PUT/labdips/{id}

Update an existing labdip

DELETE/labdips/{id}

Delete a labdip

List Labdips

ParameterTypeDescription
searchstringSearch by labdip name
supplier_idintegerFilter by supplier
statusstringFilter by status
per_pageintegerItems per page (max 100)
sort_bystringSort field
sort_dirstringSort direction (asc, desc)

Create Labdip

ParameterTypeDescription
nameRequiredstringLabdip name
supplier_idRequiredintegerSupplier ID
statusstringLabdip status
target_colourstringTarget colour reference
notesstringAdditional notes

Example Response

json
{
  "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.

GET/labdips/{id}/options

List swatches

POST/labdips/{id}/options

Add placeholder swatches (count 1-12)

PUT/labdips/{id}/options/{optionId}

Edit a swatch: lab_ref, hex, decision_note (PATCH also accepted)

DELETE/labdips/{id}/options/{optionId}

Remove a swatch

PATCH/labdips/{id}/options/{optionId}/decide

Decide a swatch (POST also accepted)

POST/labdips/{id}/options/{optionId}/apply

Pin an approved swatch to colourways (colourways: [{style_id, variant_id}])

DELETE/labdips/{id}/options/{optionId}/usages/{usageId}

Remove a standard

POST/labdips/{id}/reject-all

Reject every outstanding swatch

POST/labdips/{id}/re-request

Open the next round (supplier_id, date, notes, option_count)

POST/labdips/{id}/images

Upload an image (multipart; upload limits apply)

DELETE/labdips/{id}/images/{imageId}

Delete an image

PUT/labdips/{id}/images/{imageId}/annotations

Save image annotations (POST also accepted)

Decide a Swatch

ParameterTypeDescription
statusRequiredstringThe swatch decision
decision_notestringWhy (max 2,000 characters)

Moodboards

Create and manage visual moodboards for design inspiration and collection planning.

GET/moodboards

List all moodboards

GET/moodboards/{id}

Get a specific moodboard

POST/moodboards

Create a new moodboard

PUT/moodboards/{id}

Update an existing moodboard

DELETE/moodboards/{id}

Delete a moodboard

List Moodboards

ParameterTypeDescription
searchstringSearch by moodboard name
per_pageintegerItems per page (max 100)
sort_bystringSort field
sort_dirstringSort direction (asc, desc)

Create Moodboard

ParameterTypeDescription
nameRequiredstringMoodboard name
descriptionstringMoodboard description
canvas_dataobjectCanvas layout data (JSON)
thumbnailstringThumbnail image URL

Example Response

json
{
  "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.

GET/component-sourcing

List all sourcing requests

GET/component-sourcing/{id}

Get a specific sourcing request (includes component, submissions)

POST/component-sourcing

Create a new sourcing request

PUT/component-sourcing/{id}

Update an existing sourcing request

DELETE/component-sourcing/{id}

Delete a sourcing request

Submissions & Response Cycle

GET/component-sourcing/{id}/submissions

List submissions for a sourcing request

POST/component-sourcing/{id}/submissions

Submit a sourcing option against a request (supplier quote or internal option)

GET/component-sourcing/{id}/submissions/compare

Compare all submissions for a sourcing request

POST/component-sourcing/{id}/chase

Re-notify suppliers who haven't responded yet

PUT/component-sourcing/submissions/{submissionId}/status

Update submission status (brand review: approve / reject / withdraw)

POST/component-sourcing/submissions/{submissionId}/purchase-order

Create a draft purchase order from a supplier submission

List Sourcing Requests

ParameterTypeDescription
searchstringSearch sourcing requests
statusstringFilter by status
component_idintegerFilter by component
per_pageintegerItems per page (max 100)
sort_bystringSort field
sort_dirstringSort direction (asc, desc)

Create Sourcing Request

ParameterTypeDescription
component_idRequiredintegerComponent ID to source
requirementsstringSourcing requirements description
target_quantityintegerTarget quantity needed
target_pricenumberTarget unit price
currencystringCurrency code (e.g. USD)
deadline_datedateSourcing deadline date
statusstringRequest status

Example Response

json
{
  "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.

GET/tasks

List all tasks

GET/tasks/{id}

Get a specific task

POST/tasks

Create a task

PUT/tasks/{id}

Update a task

DELETE/tasks/{id}

Delete a task

POST/tasks/{id}/complete

Mark task as completed

POST/tasks/bulk

Create multiple tasks in a single transaction

PATCH/tasks/bulk

Bulk update multiple tasks

DELETE/tasks/bulk

Bulk delete multiple tasks

POST/tasks/{id}/incomplete

Mark a task as not completed

POST/tasks/{id}/duplicate

Duplicate a task

POST/tasks/{id}/attachments

Upload attachments to a task

DELETE/tasks/{taskId}/attachments/{attachmentId}

Delete a task attachment

List Tasks

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status (pending, in_progress, completed, cancelled)
prioritystringFilter by priority (low, medium, high, urgent)
assignee_idintegerFilter by assignee user ID
due_beforedateFilter tasks due before date
due_afterdateFilter tasks due after date

Create Task Example

json
{
  "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.

GET/notes

List all notes

GET/notes/{id}

Get a specific note

POST/notes

Create a note

PUT/notes/{id}

Update a note

DELETE/notes/{id}

Delete a note

POST/notes/{id}/duplicate

Duplicate a note

POST/notes/{id}/favorite

Toggle a note as favourite

List Notes

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
notable_typestringFilter by resource type (style, component, supplier, customer, purchase_order, sales_order)
notable_idintegerFilter by resource ID

Create Note Example

json
{
  "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.

GET/projects

List all projects

GET/projects/{id}

Get a specific project

POST/projects

Create a project

PUT/projects/{id}

Update a project

DELETE/projects/{id}

Delete a project

GET/projects/{id}/tasks

List tasks in a project

List Projects

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
statusstringFilter by status

Create Project Example

json
{
  "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.

GET/notifications

List notifications

GET/notifications/{id}

Get a specific notification

DELETE/notifications/{id}

Delete a notification

POST/notifications/{id}/read

Mark notification as read

POST/notifications/mark-all-read

Mark all notifications as read

POST/notifications/{id}/unread

Mark a notification as unread

DELETE/notifications

Delete all notifications (pass read_only=true to delete only read ones)

GET/notifications/unread-count

Get unread notification count

POST/notifications

Create a notification

POST/notifications/bulk

Create notifications for multiple users

POST/notifications/mark-read

Mark a set of notifications as read

List Notifications

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
is_readbooleanFilter by read status
typestringFilter by notification type

Workflows

Automate processes with workflow rules and triggers.

GET/workflows

List all workflows

GET/workflows/{id}

Get a specific workflow

POST/workflows

Create a workflow

PUT/workflows/{id}

Update a workflow

DELETE/workflows/{id}

Delete a workflow

POST/workflows/{id}/execute

Manually execute a workflow

GET/workflows/{id}/executions

Get workflow execution history

GET/workflow-templates

Get available workflow templates

GET/workflows/trigger-types

List available workflow trigger types

POST/workflows/{id}/activate

Activate a workflow

POST/workflows/{id}/deactivate

Deactivate a workflow

POST/workflow-templates/{id}/create

Create a workflow from a template

GET/workflow-executions

List workflow execution runs

GET/workflow-executions/{id}

Get a workflow execution run

List Workflows

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
updated_sincedatetimeFilter by update time
is_activebooleanFilter by active status
trigger_typestringFilter by trigger type

Execute Workflow Example

json
{
  "context": {
    "style_id": 123,
    "action": "status_change"
  }
}

Supplier Scoring

Access supplier performance scores and metrics.

GET/suppliers/{id}/score

Get supplier overall score

GET/suppliers/{id}/score/history

Historical score snapshots for a supplier

GET/suppliers/{id}/score/breakdown

Full score breakdown (grade, trend, per-metric breakdown, statistics)

GET/suppliers/{id}/metrics

Get detailed supplier metrics

POST/supplier-metrics/{metricId}/verify

Verify a performance metric

DELETE/supplier-metrics/{metricId}

Delete a performance metric

GET/supplier-scores/rankings

Get supplier rankings

GET/supplier-scores

List supplier scores

GET/supplier-scores/weights

Get the scoring weight configuration

POST/supplier-scores/calculate-all

Recalculate scores for all suppliers

POST/suppliers/{id}/score/calculate

Recalculate one supplier's score

POST/suppliers/{id}/metrics

Record a supplier metric

GET/supplier-metrics/types

List available supplier metric types

Supplier Metrics Query

ParameterTypeDescription
periodstringMetrics period: 30d, 90d, 1y, all (default: 90d)

Supplier Rankings Query

ParameterTypeDescription
pageintegerPage number
per_pageintegerItems per page
sort_bystringSort by: overall_score, quality_score, delivery_score, communication_score
sort_dirstringSort direction: asc, desc

Example Response

json
{
  "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.

GET/size-ranges

Get available size ranges

GET/currencies

Get supported currencies

GET/component-categories

Get component categories

Reference Data (lookups:read scope)

GET/style-categories

Get style categories

GET/style-tags

Get style tags

GET/markets

Get markets

GET/sales-channels

Get sales channels

GET/payment-terms

Get payment terms

GET/incoterms

Get incoterms

GET/task-statuses

Get task statuses

Account

GET/account

Identify the authenticated account (company, brand and API key context)

GET/account/brands

List the company's brands, flagging the API key's own brand

GET/currencies/{id}

Get a currency

GET/currencies/sales

Currencies enabled for sales documents

GET/size-ranges/{id}

Get a size range

GET/component-categories/{id}

Get a component category

Example Response - Currencies

json
{
  "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.

GET/tax-rates

List tax rates

GET/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.

GET/sample-stages

List sample stages

API Keys

Manage API keys programmatically (requires api_keys:write scope).

GET/api-keys

List all API keys

GET/api-keys/{id}

Get a specific API key

GET/api-keys/{id}/usage

Get API key usage statistics

POST/api-keys/{id}/revoke

Revoke an API key

Security Note
API keys can only be created through the Kōbō PLM web interface for security reasons. The API allows listing, viewing usage, and revoking keys only.

Usage Statistics Response

json
{
  "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.

GET/materials

List all materials

POST/materials

Create a new material

GET/materials/{id}

Get a specific material

PUT/materials/{id}

Update a material

PATCH/materials/{id}

Partially update a material

DELETE/materials/{id}

Delete a material

Sketches

Manage technical sketches attached to a style.

GET/styles/{styleId}/sketches

List sketches for a style

POST/styles/{styleId}/sketches

Add a sketch to a style

GET/sketches/{id}

Get a specific sketch

PUT/sketches/{id}

Update a sketch

PATCH/sketches/{id}

Partially update a sketch

DELETE/sketches/{id}

Delete a sketch

Pages

Control the tech pack page status and visibility for a style.

GET/styles/{styleId}/pages

List a style's pages and their status

PUT/styles/{styleId}/pages/{pageName}/status

Update a page's status

PUT/styles/{styleId}/pages/{pageName}/visibility

Toggle a page's visibility

File Sections

Organise a style's uploaded files into ordered sections.

GET/styles/{styleId}/file-sections

List file sections for a style

POST/styles/{styleId}/file-sections

Create a file section

PUT/styles/{styleId}/file-sections/order

Reorder file sections

PUT/file-sections/{id}

Update a file section

DELETE/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.

GET/styles/{styleId}/suppliers

List a style’s vendor bench

POST/styles/{styleId}/suppliers

Add a supplier to the bench

GET/style-suppliers/{id}

Get a bench row

PUT/style-suppliers/{id}

Update a bench row

PATCH/style-suppliers/{id}

Partially update a bench row

DELETE/style-suppliers/{id}

Remove a supplier from the bench

Compliance

Read and update the compliance record for a style.

GET/style-compliance

List compliance across styles — also the delta surface for digital product passports

GET/styles/{styleId}/compliance

Get a style's compliance data

PUT/styles/{styleId}/compliance

Update compliance data

PATCH/styles/{styleId}/compliance

Partially 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.

GET/styles/{styleId}/dpp

Get the generated Digital Product Passport payload

POST/styles/{styleId}/dpp/generate

Generate or regenerate the passport (optionally stamping GTIN / serial number)

PUT/styles/{styleId}/dpp

Update passport fields on the compliance record and regenerate

GET/styles/{styleId}/dpp/validate

Validate the passport against EU DPP requirements

GET/styles/{styleId}/dpp/qr-code

Passport QR code (base64 PNG) plus its public URL

GET/styles/{styleId}/dpp/export/{format}

Export the passport as json, qr, or pdf

GET/styles/{styleId}/dpp/analytics

Aggregated scan analytics for the passport

GET/brands/{brandId}/dpp-settings

Brand-level passport theming and visibility settings

PUT/brands/{brandId}/dpp-settings

Update brand-level passport settings

Workflow Groups

Manage workflow task groups attached to a style.

GET/styles/{styleId}/workflow-groups

List workflow groups for a style

POST/styles/{styleId}/workflow-groups

Create a workflow group

PUT/workflow-groups/{id}

Update a workflow group

DELETE/workflow-groups/{id}

Delete a workflow group

Comments

Threaded comments on a style.

GET/styles/{styleId}/comments

List comments for a style

POST/styles/{styleId}/comments

Add a comment

PUT/comments/{id}

Update a comment

PATCH/comments/{id}

Partially update a comment

DELETE/comments/{id}

Delete a comment

POST/comments/{id}/read

Mark a comment as read

POST/comments/mark-read

Mark multiple comments as read

POST/comments/{id}/reactions

Add a reaction to a comment

DELETE/comments/{id}/reactions/{reaction}

Remove a reaction from a comment

Style Pricing

Read, update and recalculate the cost sheet for a style.

GET/styles/{styleId}/pricing

Get a style's pricing

PUT/styles/{styleId}/pricing

Update a style's pricing

PATCH/styles/{styleId}/pricing

Partially update a style's pricing

POST/styles/{styleId}/pricing/calculate

Recalculate pricing from the cost breakdown

POST/styles/{styleId}/pricing/sync-component-costs

Pull current BOM component costs into the costing sheet and recalculate

GET/style-pricing

List cost sheets across styles — the delta surface for a nightly sync

GET/style-pricing/bulk

Bulk pricing read across styles (style_ids[] query parameter)

Value-Added Services (VAS)

GET/styles/{styleId}/pricing/vas

List VAS costing lines on the style's pricing

POST/styles/{styleId}/pricing/vas

Add a VAS costing line (library service or free-text custom line)

PUT/styles/{styleId}/pricing/vas/{vasId}

Update a VAS costing line's cost

DELETE/styles/{styleId}/pricing/vas/{vasId}

Remove a VAS costing line

Component Pricing

Read and update pricing for a component.

GET/components/{componentId}/pricing

Get a component's pricing

PUT/components/{componentId}/pricing

Update a component's pricing

PATCH/components/{componentId}/pricing

Partially update a component's pricing

Channel Pricing

Manage per-sales-channel pricing for a style.

GET/styles/{styleId}/channel-pricing

List channel pricing for a style

GET/channel-pricing/{id}

Get a single channel pricing row

POST/styles/{styleId}/channel-pricing

Add channel pricing

PUT/channel-pricing/{id}

Update channel pricing

PATCH/channel-pricing/{id}

Partially update channel pricing

DELETE/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.

GET/styles/{styleId}/market-pricing

List per-market pricing for a style

PUT/styles/{styleId}/market-pricing/{marketId}

Create or update one market’s pricing

PATCH/styles/{styleId}/market-pricing/{marketId}

Partially update one market’s pricing

DELETE/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.

GET/styles/{styleId}/pricing-scenarios

List scenarios with the live cost sheet

POST/styles/{styleId}/pricing-scenarios

Create a scenario

GET/styles/{styleId}/pricing-scenarios/{scenarioId}

Get a scenario

PUT/styles/{styleId}/pricing-scenarios/{scenarioId}

Update a scenario

PATCH/styles/{styleId}/pricing-scenarios/{scenarioId}

Partially update a scenario

DELETE/styles/{styleId}/pricing-scenarios/{scenarioId}

Delete a scenario

POST/styles/{styleId}/pricing-scenarios/{scenarioId}/promote

Promote a scenario onto the live cost sheet

Library Groups

Organise library items into groups.

GET/library-groups

List library groups

POST/library-groups

Create a library group

GET/library-groups/{id}

Get a library group

PUT/library-groups/{id}

Update a library group

PATCH/library-groups/{id}

Partially update a library group

DELETE/library-groups/{id}

Delete a library group

POM Diagrams

Manage reusable points-of-measure diagrams in the library.

GET/library-pom-diagrams

List POM diagrams

POST/library-pom-diagrams

Create a POM diagram

GET/library-pom-diagrams/{id}

Get a POM diagram

PUT/library-pom-diagrams/{id}

Update a POM diagram

PATCH/library-pom-diagrams/{id}

Partially update a POM diagram

DELETE/library-pom-diagrams/{id}

Delete a POM diagram

POM Templates

Manage reusable points-of-measure templates in the library.

GET/library-pom-templates

List POM templates

POST/library-pom-templates

Create a POM template

GET/library-pom-templates/{id}

Get a POM template

PUT/library-pom-templates/{id}

Update a POM template

PATCH/library-pom-templates/{id}

Partially update a POM template

DELETE/library-pom-templates/{id}

Delete a POM template

Issue Templates

Manage reusable sample-review issue templates in the library.

GET/library-issue-templates

List issue templates

POST/library-issue-templates

Create an issue template

GET/library-issue-templates/{id}

Get an issue template

PUT/library-issue-templates/{id}

Update an issue template

PATCH/library-issue-templates/{id}

Partially update an issue template

DELETE/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

POST/library-pom-templates/{id}/duplicate

Duplicate a template, copying its current-version POM rows

GET/library-pom-templates/{id}/assignable-styles

List styles the template can be assigned to

POST/library-pom-templates/{id}/assign-styles

Assign the template to one or more styles (per-style outcomes reported)

GET/library-pom-templates/{id}/using-styles

List styles currently using the template

PUT/library-pom-templates/{id}/poms/{pomId}

Update a single POM row belonging to the template

DELETE/library-pom-templates/{id}/poms/{pomId}

Delete a single POM row belonging to the template

POM Diagrams

GET/library-pom-diagrams/{id}/assigned-styles

List styles linked to the diagram (pass assigned_only=true to restrict)

POST/library-pom-diagrams/{id}/assign-styles

Sync the diagram's style assignments to the given selection

POST/library-pom-diagrams/from-style

Create a diagram from an existing style (clones the style's linked diagram if present)

Workflow Groups

POST/workflow-groups/{id}/add-workflows

Add workflows to a group and recalculate its completion percentage

POST/workflow-groups/{id}/remove-workflows

Remove workflows from a group (they become ungrouped)

POST/styles/{styleId}/workflow-groups/move-workflows

Move workflows between groups on a style (null target = ungrouped)

Sales Cancellations

Cancellations against sales orders, with confirm / undo state transitions.

GET/sales-cancellations

List sales cancellations

GET/sales-cancellations/{id}

Get a sales cancellation

POST/sales-cancellations

Create a sales cancellation

PUT/sales-cancellations/{id}

Update a sales cancellation

PATCH/sales-cancellations/{id}

Partially update a sales cancellation

DELETE/sales-cancellations/{id}

Delete a sales cancellation

POST/sales-cancellations/{id}/confirm

Confirm a sales cancellation

POST/sales-cancellations/{id}/undo

Undo a confirmed sales cancellation

Sales Returns

Returns against sales orders, with confirm / undo state transitions.

GET/sales-returns

List sales returns

GET/sales-returns/{id}

Get a sales return

POST/sales-returns

Create a sales return

PUT/sales-returns/{id}

Update a sales return

PATCH/sales-returns/{id}

Partially update a sales return

DELETE/sales-returns/{id}

Delete a sales return

POST/sales-returns/{id}/confirm

Confirm a sales return

POST/sales-returns/{id}/undo

Undo a confirmed sales return

Production Batches

The sales-order → purchase-order MRP bridge. Preview, commit or cancel a batch.

GET/production-batches

List production batches

POST/production-batches

Create a production batch

GET/production-batches/{id}

Get a production batch

PUT/production-batches/{id}

Update a production batch

PATCH/production-batches/{id}

Partially update a production batch

DELETE/production-batches/{id}

Delete a production batch

POST/production-batches/{id}/preview

Preview the POs a batch would generate

POST/production-batches/{id}/commit

Commit the batch and generate POs

POST/production-batches/{id}/cancel

Cancel a production batch

Activity Log

Read-only audit trail of changes across your account.

GET/activities

List activity log entries

GET/activities/{id}

Get a specific activity entry

Scheduled Reports

Configure recurring reports, trigger ad-hoc runs and inspect execution history.

GET/scheduled-reports

List scheduled reports

POST/scheduled-reports

Create a scheduled report

GET/scheduled-reports/{id}

Get a scheduled report

PUT/scheduled-reports/{id}

Update a scheduled report

PATCH/scheduled-reports/{id}

Partially update a scheduled report

DELETE/scheduled-reports/{id}

Delete a scheduled report

POST/scheduled-reports/{id}/run-now

Trigger a report run immediately

POST/scheduled-reports/{id}/send-test

Send a test delivery

GET/scheduled-reports/{id}/executions

List execution history for a report

Note Categories

Manage and reorder the categories used to organise notes.

GET/note-categories

List note categories

POST/note-categories

Create a note category

PUT/note-categories/reorder

Reorder note categories

GET/note-categories/{id}

Get a note category

PUT/note-categories/{id}

Update a note category

PATCH/note-categories/{id}

Partially update a note category

DELETE/note-categories/{id}

Delete a note category

Budget Tracking

Record and query actual spend tracked against season budgets.

GET/budget-tracking

List budget tracking entries

POST/budget-tracking

Create a budget tracking entry

GET/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.

GET/milestones

List milestones

POST/milestones

Create a milestone

GET/milestones/{id}

Get a milestone

PUT/milestones/{id}

Update a milestone (PATCH also accepted)

DELETE/milestones/{id}

Delete a milestone

PATCH/milestones/{id}/completion

Sign a milestone off or reopen it

POST/milestones/{id}/cascade

Push a date change through dependent milestones

POST/milestone-dependencies

Create a dependency between milestones

DELETE/milestone-dependencies/{id}

Remove a dependency

List Milestones

ParameterTypeDescription
season_idintegerOnly this season's critical path
workflow_idintegerOnly phases of this milestone definition
is_completedbooleanFilter by sign-off
includestringseason
updated_sincedatetimeOnly 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.

GET/milestone-templates

List templates

POST/milestone-templates

Create a template

GET/milestone-templates/{id}

Get a template

PUT/milestone-templates/{id}

Update a template

DELETE/milestone-templates/{id}

Delete a template

POST/milestone-templates/{id}/preview

Preview the milestones a template would create (read scope)

POST/milestone-templates/{id}/apply

Apply 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.

GET/tna-board

The T&A board for a season

ParameterTypeDescription
season_idintegerThe season; falls back to the first season with a critical path
delivery_idintegerOne drop: columns carry that drop's dates and rows narrow to its styles
supplier_idstringComma-separated supplier ids
sample_stage_idstringComma-separated sample stage ids
is_productionboolean1 production styles only, 0 sampling only
searchstringMatch 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.

GET/showroom/events

List events

GET/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.

GET/showroom/events/{eventId}/appointments

List an event's appointments

POST/showroom/events/{eventId}/appointments

Book (agency) or request (brand) a visit

GET/showroom/appointments/{id}

Get an appointment

PUT/showroom/appointments/{id}

Update an appointment (agency; PATCH also accepted)

POST/showroom/appointments/{id}/confirm

Confirm (mails the buyer; throttled)

POST/showroom/appointments/{id}/check-in

Check the visitor in

POST/showroom/appointments/{id}/complete

Complete the visit

POST/showroom/appointments/{id}/no-show

Mark as no-show

POST/showroom/appointments/{id}/reschedule

Move to another time (starts_at, ends_at, force)

POST/showroom/appointments/{id}/cancel

Cancel

GET/showroom/appointments/{id}/attendees

List attendees

POST/showroom/appointments/{id}/attendees

Add an attendee (agency)

PUT/showroom/appointments/{id}/attendees/{attendeeId}

Update an attendee (agency; PATCH also accepted)

DELETE/showroom/appointments/{id}/attendees/{attendeeId}

Remove an attendee (agency)

List Appointments

ParameterTypeDescription
datedateOne local day (event timezone)
fromdateFrom this local day
todateUp to and including this local day
statusstringComma-separated statuses, e.g. requested,confirmed
brand_idintegerFilter by brand
buyer_idintegerFilter by buyer
customer_idintegerFilter 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.

GET/showroom/selections

List buyer selections

GET/showroom/selections/{id}

Get a selection with its items

GET/showroom/selections/{id}/items

A selection's items

GET/customer-selections

List customer-portal selections

GET/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.

GET/merch/metrics/{metric}

One metric: rate_of_sale, could_have_sold, sell_through, cover, size_availability, stock_age, mix_vs_stock or order_book

ParameterTypeDescription
fromdateStart of the period
todateEnd of the period
season_idintegerFilter by season
style_idsstringComma-separated style ids
variant_idsstringComma-separated variant ids
location_idsstringComma-separated location ids
channelsstringComma-separated sales channels
grainstringTime grain of the series
dimensionstringGroup 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.

GET/merch/markdown-batches

List markdown batches (status: draft, pushed, reverted; season_id)

POST/merch/markdown-batches

Create a draft batch

GET/merch/markdown-batches/{id}

Get a batch

PUT/merch/markdown-batches/{id}

Update a draft: name, notes, channel_scope, lines, remove_style_ids (PATCH also accepted)

GET/merch/markdown-batches/{id}/lines

A batch's lines

GET/merch/markdown-batches/{id}/preview

Recompute and preview the new prices (merch:write)

POST/merch/markdown-batches/{id}/apply

Apply the markdown

POST/merch/markdown-batches/{id}/revert

Revert an applied markdown

Create Markdown Batch

ParameterTypeDescription
style_idsRequiredinteger[]1-500 styles
namestringBatch name
season_idintegerSeason
depth_pctnumberMarkdown depth applied to every line
channel_scopeobjectmarket_ids[] and include_base
notesstringNotes (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.

GET/merch/allocation-runs

List allocation runs (status: draft, committed, cancelled; season_id)

POST/merch/allocation-runs

Create a run (name, season_id, notes)

GET/merch/allocation-runs/{id}

Get a run

POST/merch/allocation-runs/{id}/preview

Preview the allocation

POST/merch/allocation-runs/{id}/commit

Commit the run

POST/merch/allocation-runs/{id}/cancel

Cancel the run

Preview

ParameterTypeDescription
style_idsRequiredinteger[]1-500 styles
total_units_per_styleintegerUnits to allocate per style
grade_weightsobjectWeight per store grade
size_curve_idintegerSize 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.

GET/merch/stock-holds

List stock holds (status: active, released, all)

POST/merch/stock-holds

Hold stock

GET/merch/stock-holds/{id}

Get a hold

PUT/merch/stock-holds/{id}

Update a hold (PATCH also accepted)

POST/merch/stock-holds/{id}/release

Release a hold

Create Stock Hold

ParameterTypeDescription
inventory_idRequiredintegerInventory row to hold from
reasonRequiredstringfaulty, sample, charity or other
sizestringSize to hold
unitsintegerUnits to hold
notestringNote (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

EventDescription
style.createdA new style was created
style.updatedA style was updated
style.deletedA style was deleted
style.status_changedA style's status changed
style.techpack_generatedA tech pack was generated for a style
style.sample_review_generatedA sample review document was generated for a style

Component Events

EventDescription
component.createdA new component was created
component.updatedA component was updated
component.deletedA component was deleted

Supplier Events

EventDescription
supplier.createdA new supplier was created
supplier.updatedA supplier was updated
supplier.deletedA supplier was deleted

Purchase Order Events

EventDescription
purchase_order.createdA new PO was created
purchase_order.updatedA PO was updated
purchase_order.deletedA PO was deleted
purchase_order.status_changedA PO's status changed
purchase_order.confirmedA PO was confirmed
purchase_order.cancelledA PO was cancelled

Inventory Events

EventDescription
inventory.updatedInventory levels changed
inventory.low_stockInventory fell below reorder point
inventory.out_of_stockInventory reached zero
inventory.transferredInventory was transferred between locations
inventory.reservedInventory was reserved
inventory.unreservedAn inventory reservation was released
inventory.checked_inInventory was checked in

Customer Events

EventDescription
customer.createdA new customer was created
customer.updatedA customer was updated
customer.deletedA customer was deleted

Sales Order Events

EventDescription
sales_order.createdA new sales order was created
sales_order.updatedA sales order was updated
sales_order.deletedA sales order was deleted
sales_order.status_changedA sales order's status changed

Delivery Events

EventDescription
delivery.createdA new delivery was created
delivery.updatedA delivery was updated
delivery.deletedA delivery was deleted
delivery.checked_inA delivery was received
delivery.status_changedA delivery's status changed

BOM Events

EventDescription
bom.createdA BOM item was added
bom.updatedA BOM item was updated
bom.deletedA BOM item was removed

Task Events

EventDescription
task.createdA new task was created
task.updatedA task was updated
task.deletedA task was deleted
task.completedA task was marked complete
task.status_changedA task's status changed

Project Events

EventDescription
project.createdA new project was created
project.updatedA project was updated
project.deletedA project was deleted
project.status_changedA project's status changed

Payment Events

EventDescription
payment.createdA new payment was recorded
payment.updatedA payment was updated
payment.deletedA payment was deleted

Stock Take Events

EventDescription
stock_take.createdA stock take was created
stock_take.startedA stock take was started
stock_take.completedA stock take was completed
stock_take.finalizedA stock take was finalized

POM Events

EventDescription
pom.createdA point of measure was added
pom.updatedA point of measure was updated
pom.deletedA point of measure was removed

Note Events

EventDescription
note.createdA new note was created
note.updatedA note was updated
note.deletedA note was deleted

Notification Events

EventDescription
notification.createdA new notification was created
notification.readA notification was marked as read
notification.deletedA notification was deleted

Invoice Events

EventDescription
invoice.createdA new invoice was created
invoice.updatedAn invoice was updated
invoice.deletedAn invoice was deleted
invoice.status_changedAn invoice's status changed

Credit Note Events

EventDescription
credit_note.createdA new credit note was created
credit_note.updatedA credit note was updated
credit_note.deletedA credit note was deleted
credit_note.status_changedA credit note's status changed

Order Confirmation Events

EventDescription
order_confirmation.createdA new order confirmation was created
order_confirmation.updatedAn order confirmation was updated
order_confirmation.deletedAn order confirmation was deleted
order_confirmation.status_changedAn order confirmation's status changed

Goods Receipt Events

EventDescription
goods_receipt.createdA new goods receipt was created
goods_receipt.updatedA goods receipt was updated
goods_receipt.deletedA goods receipt was deleted

Sales Shipment Events

EventDescription
sales_shipment.createdA new shipment was created
sales_shipment.updatedA shipment was updated
sales_shipment.deletedA shipment was deleted
sales_shipment.status_changedA shipment's status changed

Packing List Events

EventDescription
packing_list.createdA new packing list was created
packing_list.updatedA packing list was updated
packing_list.deletedA packing list was deleted
packing_list.status_changedA packing list's status changed

Delivery Note Events

EventDescription
delivery_note.createdA new delivery note was created
delivery_note.updatedA delivery note was updated
delivery_note.deletedA delivery note was deleted

Pick Ticket Events

EventDescription
pick_ticket.createdA new pick ticket was created
pick_ticket.updatedA pick ticket was updated
pick_ticket.deletedA pick ticket was deleted
pick_ticket.status_changedA pick ticket's status changed

Sales Order Payment Events

EventDescription
sales_order_payment.createdA new sales order payment was recorded
sales_order_payment.updatedA sales order payment was updated
sales_order_payment.deletedA sales order payment was deleted
sales_order_payment.status_changedA sales order payment's status changed

Cancellation Events

EventDescription
cancellation.createdA cancellation was requested (purchase or sales order)
cancellation.approvedA cancellation was approved
cancellation.rejectedA cancellation was rejected

Return Events

EventDescription
return.createdA return was created (purchase or sales order)
return.updatedA return was updated
return.deletedA return was deleted
return.confirmedA return was confirmed

Quotation Events

EventDescription
quotation.createdA new quotation request was created
quotation.updatedA quotation was updated
quotation.deletedA quotation was deleted
quotation.status_changedA quotation's status changed

Variant Events

EventDescription
variant.createdA new variant (colourway) was created
variant.updatedA variant was updated
variant.deletedA variant was deleted

Colour Events

EventDescription
colour.createdA new colour library entry was created
colour.updatedA colour was updated
colour.deletedA colour was deleted

Material Events

EventDescription
material.createdA new material library entry was created
material.updatedA material was updated
material.deletedA material was deleted

Lab Dip Events

EventDescription
labdip.createdA new lab dip was created
labdip.updatedA lab dip was updated
labdip.deletedA lab dip was deleted

QC Inspection Events

EventDescription
qc_inspection.createdA new QC inspection was created
qc_inspection.updatedA QC inspection was updated
qc_inspection.deletedA QC inspection was deleted

Sample Review Events

EventDescription
sample_review.createdA new sample review was created
sample_review.updatedA sample review was updated
sample_review.deletedA sample review was deleted

Customer Contact Events

EventDescription
customer_contact.createdA new customer contact was created
customer_contact.updatedA customer contact was updated
customer_contact.deletedA customer contact was deleted

Brand Events

EventDescription
brand.createdA new brand was created
brand.updatedA brand was updated
brand.deletedA brand was deleted

Company Events

EventDescription
company.createdA new company was created
company.updatedA company was updated
company.deletedA company was deleted

User Events

EventDescription
user.createdA new user was created
user.updatedA user was updated
user.deletedA user was deleted

Workflow Events

EventDescription
workflow.createdA new workflow was created
workflow.updatedA workflow was updated
workflow.deletedA workflow was deleted
workflow.executedA workflow was executed

Style SKU Events

EventDescription
style_sku.createdA SKU was created
style_sku.updatedA SKU was updated
style_sku.deletedA SKU was deleted

Style Workflow Task Events

EventDescription
style_workflow_task.createdA workflow task was created on a style
style_workflow_task.updatedA workflow task was updated
style_workflow_task.status_changedA workflow task changed status
style_workflow_task.deletedA workflow task was deleted

Sample Review Issue Events

EventDescription
sample_review_issue.createdAn issue was raised on a sample review
sample_review_issue.updatedA sample review issue was updated
sample_review_issue.status_changedA sample review issue changed status
sample_review_issue.deletedA sample review issue was deleted

File Events

EventDescription
file.uploadedA file was uploaded
file.updatedFile metadata was updated
file.deletedA file was deleted

Supplier Contact Events

EventDescription
supplier_contact.createdA supplier contact was added
supplier_contact.updatedA supplier contact was updated
supplier_contact.deletedA supplier contact was deleted

Component Sourcing Events

EventDescription
component_sourcing_request.createdA sourcing request was created
component_sourcing_request.updatedA sourcing request was updated
component_sourcing_request.status_changedA sourcing request changed status
component_sourcing_request.deletedA sourcing request was deleted
component_sourcing_submission.receivedA supplier submission was received
component_sourcing_submission.approvedA supplier submission was approved
component_sourcing_submission.rejectedA supplier submission was rejected

Purchase Order Payment Events

EventDescription
purchase_order_payment.createdA payment was recorded against a purchase order
purchase_order_payment.updatedA purchase order payment was updated
purchase_order_payment.deletedA purchase order payment was deleted

Purchase Credit Note Events

EventDescription
purchase_credit_note.createdA purchase credit note was created
purchase_credit_note.updatedA purchase credit note was updated
purchase_credit_note.status_changedA purchase credit note changed status
purchase_credit_note.deletedA purchase credit note was deleted

Parcel Shipment Events

EventDescription
parcel_shipment.createdA parcel shipment was created
parcel_shipment.updatedA parcel shipment was updated
parcel_shipment.status_changedA parcel shipment changed status
parcel_shipment.deletedA parcel shipment was deleted

Production Batch Events

EventDescription
production_batch.createdA production batch was created
production_batch.updatedA production batch was updated
production_batch.status_changedA production batch changed status
production_batch.deletedA production batch was deleted

Range Plan Events

EventDescription
range_plan.createdA range plan was created
range_plan.updatedA range plan was updated
range_plan.deletedA range plan was deleted

Milestone Events

EventDescription
milestone.createdA milestone was created
milestone.updatedA milestone was updated
milestone.completedA milestone was completed
milestone.deletedA milestone was deleted

Location Events

EventDescription
location.createdAn inventory location was created
location.updatedAn inventory location was updated
location.deletedAn inventory location was deleted

Webhook Payload

All webhooks send a JSON payload with the following structure:

json
{
  "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

HeaderDescription
Content-Typeapplication/json
User-AgentKOBO-PLM-Webhooks/1.0
X-Webhook-EventThe event that fired this delivery (e.g., sample_review.updated); matches the payload's event field
X-Webhook-Event-IdUnique event ID (UUID)
X-Webhook-TimestampUnix timestamp
X-Webhook-SignatureHMAC-SHA256 signature

Signature Verification

To verify that a webhook came from Kobo PLM, validate the signature:

javascript
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');
});
python
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}"
    )
php
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:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours

Managing Webhooks

GET/webhooks/events

List available webhook events

GET/webhooks

List all webhooks

POST/webhooks

Create a new webhook

GET/webhooks/{id}

Get a specific webhook

PUT/webhooks/{id}

Update a webhook

DELETE/webhooks/{id}

Delete a webhook

POST/webhooks/{id}/rotate-secret

Rotate webhook signing secret

POST/webhooks/{id}/test

Send a test event

POST/webhooks/{id}/reset

Reset webhook failure count

GET/webhooks/{id}/stats

Get webhook delivery statistics

GET/webhooks/{id}/deliveries

Get delivery history

POST/webhooks/{id}/deliveries/{deliveryId}/retry

Retry a failed delivery

Create Webhook

json
{
  "name": "ERP Sync",
  "url": "https://your-system.com/webhooks/kobo",
  "events": ["style.created", "style.updated", "inventory.updated"],
  "is_active": true
}
URL rules
The URL must be 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:

bash
# 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:

javascript
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:

javascript
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:

bash
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

Last updated: November 2026