Kobo PLM API Documentation

The Kobo PLM API provides programmatic access to your product lifecycle management data. Use it to integrate with ERPs, build custom workflows, or sync data with external systems.

Base URL

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.

bash
curl -X GET "https://api.kobolabs.io/api/v1/styles" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json"

Getting an API Key

  1. Log in to Kobo 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

ScopeDescription
*Full access to all resources
styles:readRead styles/products
styles:writeCreate, update, delete styles
components:readRead components/materials
components:writeCreate, update, delete components
suppliers:readRead suppliers
suppliers:writeCreate, update, delete suppliers
purchase_orders:readRead purchase orders
purchase_orders:writeCreate, update, delete purchase orders
inventory:readRead inventory levels
inventory:writeUpdate inventory
customers:readRead customers
customers:writeCreate, update, delete customers
sales_orders:readRead sales orders
sales_orders:writeCreate, update, delete sales orders
deliveries:readRead deliveries
bom:readRead bill of materials
bom:writeManage bill of materials
pom:readRead points of measure
pom:writeManage points of measure
tasks:readRead tasks
tasks:writeCreate, update, delete tasks
notes:readRead notes
notes:writeCreate, update, delete notes
projects:readRead projects
projects:writeCreate, update, delete projects
cancellations:readRead cancellations
cancellations:writeManage cancellations
returns:readRead returns
returns:writeManage returns
payments:readRead payments
payments:writeCreate, update payments
stock_takes:readRead stock takes
stock_takes:writeManage stock takes
workflows:readRead workflows
workflows:writeManage workflows
notifications:readRead notifications
notifications:writeManage notifications
webhooks:readRead webhook configurations
webhooks:writeManage webhooks
api_keys:readRead API keys
api_keys:writeManage API keys

Rate Limiting

API requests are rate limited based on your subscription tier:

TierRequests per Minute
Basic100
Professional500
Enterprise2,000

Rate limit headers are included in every response:

http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699574400
Rate Limit Exceeded
When rate limited, you'll receive a 429 Too Many Requests response. Implement exponential backoff to handle this gracefully.

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"

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."]
  }
}

Styles

Styles represent your products/designs in Kobo 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

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

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.koboplm.com/styles/1/main.jpg",
          "type": "main"
        }
      ],
      "skus": [
        {
          "id": 1,
          "sku": "SS24-001-WHT-S",
          "size": "S",
          "color": "White",
          "barcode": "1234567890123"
        }
      ],
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T14:45:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 150
  }
}

Create Style

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

List Components

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

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

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"
    }
  ]
}

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

PUT/purchase-orders/{id}

Update an existing purchase order

DELETE/purchase-orders/{id}

Delete a draft purchase order

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/inventory/bulk-update

Bulk update inventory

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

List Customers

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

Bill of Materials (BOM)

The BOM represents the list of components and materials used to manufacture a style.

GET/bom

List all BOM items

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

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

List all POM items

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

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
  }
}

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

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
}

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

Status Values

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

Deliveries

Deliveries are read-only via the API.

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)

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}/approve

Approve a cancellation

POST/cancellations/{id}/reject

Reject a 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"
}

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}/finalize

Finalize and apply stock take adjustments

GET/stock-takes/{id}/items

Get stock take items

POST/stock-takes/{id}/items

Add item to stock take

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"
}

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

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

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

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

GET/notifications/unread-count

Get unread notification count

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/workflows/templates

Get available workflow templates

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}/metrics

Get detailed supplier metrics

GET/suppliers/rankings

Get supplier rankings

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/lookups/size-ranges

Get available size ranges

GET/lookups/currencies

Get supported currencies

GET/lookups/component-categories

Get component categories

GET/lookups/units

Get units of measure

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$" }
  ]
}

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 Kobo 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
  }
}

Webhooks

Webhooks allow you to receive real-time notifications when events occur in Kobo PLM. When you configure a webhook, Kobo PLM will send an HTTP POST request to your specified URL whenever the subscribed events occur.

Available Events

Style Events

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

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

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.status_changedA sales order's status changed

Delivery Events

EventDescription
delivery.createdA new delivery was created
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.completedA task was marked complete
task.assignedA task was assigned

Project Events

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

Payment Events

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

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

Workflow Events

EventDescription
workflow.executedA workflow was executed
workflow.failedA workflow execution failed

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-EventEvent type (e.g., style.updated)
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
}

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:

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

Postman Collection

Import our Postman collection to quickly test the API:

https://api.kobolabs.io/api/v1/postman-collection.json

Support

  • Email: api-support@koboplm.com
  • Documentation: https://docs.koboplm.com
  • Status Page: https://status.koboplm.com

Last updated: December 2025