openapi: 3.0.3
info:
title: 'Lagr API'
description: 'REST JSON API for Lagr inventory and warehouse management.'
version: 1.0.0
servers:
-
url: 'https://api.lagrwms.no'
tags:
-
name: 'Getting started'
description: 'Health check, authentication, and session context.'
-
name: Warehouses
description: 'Physical warehouses that hold stock.'
-
name: Catalog
description: 'Product master data and relationships.'
-
name: Inventory
description: 'On-hand, reserved, and available quantities per SKU and location.'
-
name: 'Warehouse operations'
description: 'Shrinkage, damage, and valuation adjustments.'
-
name: Purchasing
description: 'Suppliers and inbound purchase orders.'
-
name: Sales
description: 'Customers and outbound sales order fulfillment.'
-
name: Integrations
description: 'ERP connections, credentials, and Tripletex sync actions. Requires `integrations.manage`.'
-
name: Webhooks
description: 'Incoming events from Tripletex (Bearer secret, not user token).'
components:
securitySchemes:
default:
type: http
scheme: bearer
description: "Authenticate with `POST /api/v1/auth/login` using `email`, `password`, and `tenant_slug`. The response includes a Bearer token.\n\nSend these headers on all other endpoints:\n\n- `Authorization: Bearer {token}`\n- `X-Tenant-Slug: {tenant_slug}`\n\nIntegration endpoints additionally require the `integrations.manage` permission for the authenticated user."
security:
-
default: []
paths:
/api/v1/health:
get:
summary: 'Health check'
operationId: healthCheck
description: 'Returns API and database status. No authentication required.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
status: ok
database: ok
properties:
status:
type: string
example: ok
database:
type: string
example: ok
tags:
- 'Getting started'
security: []
/api/v1/auth/login:
post:
summary: Login
operationId: login
description: 'Exchange email, password, and tenant slug for a Bearer token.'
parameters: []
responses: { }
tags:
- 'Getting started'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: 'User email.'
example: user@example.com
password:
type: string
description: 'User password.'
example: '|]|{+-'
tenant_slug:
type: string
description: 'Tenant slug.'
example: demo
required:
- email
- password
- tenant_slug
security: []
/api/v1/me:
get:
summary: 'Get current user'
operationId: getCurrentUser
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- 'Getting started'
/api/v1/warehouses:
get:
summary: 'List warehouses'
operationId: listWarehouses
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Warehouses
post:
summary: 'Create warehouses'
operationId: createWarehouses
description: ''
parameters: []
responses: { }
tags:
- Warehouses
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
code:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
status:
type: string
description: ''
example: inactive
enum:
- active
- inactive
timezone:
type: string
description: 'Must not be greater than 64 characters.'
example: Antarctica/Rothera
nullable: true
settings:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- name
- code
'/api/v1/warehouses/{warehouseId}':
get:
summary: 'Get warehouses'
operationId: getWarehouses
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Warehouses
parameters:
-
in: path
name: warehouseId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/warehouses/{warehouseId}/locations':
get:
summary: 'List locations'
operationId: listLocations
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Warehouses
post:
summary: 'Create locations'
operationId: createLocations
description: ''
parameters: []
responses: { }
tags:
- Warehouses
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
code:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
kind:
type: string
description: ''
example: area
enum:
- area
- location
- slot
parent_id:
type: integer
description: ''
example: 16
nullable: true
status:
type: string
description: ''
example: inactive
enum:
- active
- inactive
settings:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- name
- code
parameters:
-
in: path
name: warehouseId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/warehouses/{warehouseId}/locations/{locationId}':
get:
summary: 'Get locations'
operationId: getLocations
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Warehouses
parameters:
-
in: path
name: warehouseId
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: locationId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/products:
get:
summary: 'List products'
operationId: listProducts
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
post:
summary: 'Create products'
operationId: createProducts
description: ''
parameters: []
responses: { }
tags:
- Catalog
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
code:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
category_id:
type: integer
description: ''
example: 16
nullable: true
vat_type_id:
type: integer
description: ''
example: 16
nullable: true
status:
type: string
description: ''
example: inactive
enum:
- active
- inactive
description:
type: string
description: 'Must not be greater than 500 characters.'
example: 'Et animi quos velit et fugiat.'
nullable: true
external_id:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
source_system:
type: string
description: 'Must not be greater than 64 characters.'
example: l
nullable: true
settings:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- name
- code
'/api/v1/products/{productId}':
get:
summary: 'Get products'
operationId: getProducts
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
put:
summary: 'Update products'
operationId: updateProducts
description: ''
parameters: []
responses: { }
tags:
- Catalog
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
category_id:
type: integer
description: ''
example: 16
nullable: true
vat_type_id:
type: integer
description: ''
example: 16
nullable: true
status:
type: string
description: ''
example: inactive
enum:
- active
- inactive
description:
type: string
description: 'Must not be greater than 500 characters.'
example: 'Et animi quos velit et fugiat.'
nullable: true
parameters:
-
in: path
name: productId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/products/{productId}/relationships':
post:
summary: 'Add product relationship'
operationId: addProductRelationship
description: ''
parameters: []
responses: { }
tags:
- Catalog
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
related_product_id:
type: integer
description: ''
example: 16
relationship_type:
type: string
description: ''
example: architecto
required:
- related_product_id
parameters:
-
in: path
name: productId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/products/{productId}/relationships/{relatedProductId}':
delete:
summary: 'Remove product relationship'
operationId: removeProductRelationship
description: ''
parameters: []
responses: { }
tags:
- Catalog
parameters:
-
in: path
name: productId
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: relatedProductId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/products/{productId}/skus':
get:
summary: 'List SKUs'
operationId: listSKUs
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
post:
summary: 'Create SKUs'
operationId: createSKUs
description: ''
parameters: []
responses: { }
tags:
- Catalog
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
code:
type: string
description: 'Must not be greater than 64 characters.'
example: b
manufacturer_code:
type: string
description: 'Must not be greater than 128 characters.'
example: 'n'
nullable: true
barcode:
type: string
description: 'Must not be greater than 128 characters.'
example: g
nullable: true
barcodes:
type: array
description: 'Must not be greater than 128 characters.'
example:
- z
items:
type: string
distributor_codes:
type: array
description: ''
example: null
items:
type: object
properties:
distributor_id:
type: integer
description: 'This field is required when distributor_codes is present.'
example: 16
item_code:
type: string
description: 'This field is required when distributor_codes is present. Must not be greater than 128 characters.'
example: 'n'
status:
type: string
description: ''
example: active
enum:
- active
- inactive
external_id:
type: string
description: 'Must not be greater than 255 characters.'
example: m
nullable: true
source_system:
type: string
description: 'Must not be greater than 64 characters.'
example: i
nullable: true
settings:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- code
parameters:
-
in: path
name: productId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/products/{productId}/skus/{skuId}':
get:
summary: 'Get SKUs'
operationId: getSKUs
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
parameters:
-
in: path
name: productId
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: skuId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/categories:
get:
summary: 'List categories'
operationId: listCategories
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
parent_id:
type: integer
description: ''
example: 16
nullable: true
post:
summary: 'Create categories'
operationId: createCategories
description: ''
parameters: []
responses: { }
tags:
- Catalog
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
code:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
parent_id:
type: integer
description: ''
example: 16
nullable: true
department_id:
type: integer
description: ''
example: 16
nullable: true
status:
type: string
description: ''
example: active
enum:
- active
- inactive
tracking_rules:
type: object
description: ''
example: null
properties:
serial:
type: string
description: ''
example: architecto
imei:
type: string
description: ''
example: architecto
fifo:
type: boolean
description: ''
example: true
nullable: true
settings:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- name
- code
'/api/v1/categories/{categoryId}':
get:
summary: 'Get categories'
operationId: getCategories
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
parameters:
-
in: path
name: categoryId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/vat-types:
get:
summary: 'List VAT types'
operationId: listVATTypes
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
direction:
type: string
description: ''
example: inbound
enum:
- inbound
- outbound
post:
summary: 'Create VAT types'
operationId: createVATTypes
description: ''
parameters: []
responses: { }
tags:
- Catalog
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
code:
type: string
description: 'Must not be greater than 16 characters.'
example: bngzmiyvdljnikhw
name:
type: string
description: 'Must not be greater than 255 characters.'
example: a
direction:
type: string
description: ''
example: outbound
enum:
- inbound
- outbound
basis_percentage:
type: number
description: 'Must be at least 0.'
example: 50
tax_percentage:
type: number
description: 'Must be at least 0.'
example: 62
status:
type: string
description: ''
example: active
enum:
- active
- inactive
tripletex_id:
type: integer
description: ''
example: 16
nullable: true
source_system:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
nullable: true
required:
- code
- name
- direction
/api/v1/vat-types/seed-defaults:
post:
summary: 'Seed default VAT types'
operationId: seedDefaultVATTypes
description: ''
parameters: []
responses: { }
tags:
- Catalog
'/api/v1/vat-types/{vatTypeId}':
get:
summary: 'Get VAT types'
operationId: getVATTypes
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
parameters:
-
in: path
name: vatTypeId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/currencies:
get:
summary: 'List currencies'
operationId: listCurrencies
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
/api/v1/exchange-rates:
get:
summary: 'List exchange rates'
operationId: listExchangeRates
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
currency:
type: string
description: 'Must be 3 characters.'
example: bng
limit:
type: integer
description: 'Must be at least 1. Must not be greater than 100.'
example: 16
/api/v1/exchange-rates/latest:
get:
summary: 'Get latest exchange rate'
operationId: getLatestExchangeRate
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Catalog
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
currency:
type: string
description: 'Must be 3 characters.'
example: bng
date:
type: string
description: 'Must be a valid date.'
example: '2026-07-10T21:07:01'
required:
- currency
/api/v1/exchange-rates/sync:
post:
summary: 'Sync exchange rates'
operationId: syncExchangeRates
description: ''
parameters: []
responses: { }
tags:
- Catalog
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
currencies:
type: array
description: 'Must be 3 characters.'
example:
- bng
items:
type: string
observations:
type: integer
description: 'Must be at least 1. Must not be greater than 120.'
example: 16
/api/v1/inventory:
get:
summary: 'List inventory levels'
operationId: listInventoryLevels
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Inventory
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
location_id:
type: integer
description: ''
example: 16
/api/v1/inventory-lots:
get:
summary: 'List inventory lots'
operationId: listInventoryLots
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Inventory
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
location_id:
type: integer
description: ''
example: 16
/api/v1/tracked-units:
get:
summary: 'List tracked units'
operationId: listTrackedUnits
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Inventory
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
location_id:
type: integer
description: ''
example: 16
/api/v1/stock-movements:
get:
summary: 'List stock movements'
operationId: listStockMovements
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Inventory
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
location_id:
type: integer
description: ''
example: 16
post:
summary: 'Create stock movements'
operationId: createStockMovements
description: ''
parameters: []
responses: { }
tags:
- Inventory
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
location_id:
type: integer
description: ''
example: 16
movement_type:
type: string
description: ''
example: adjust
enum:
- receive
- pick
- ship
- write_off
- adjust
- reserve
- release_reservation
quantity_delta:
type: string
description: ''
example: architecto
unit_cost:
type: number
description: 'Must be at least 0.'
example: 39
nullable: true
units:
type: array
description: ''
example: null
items:
type: object
properties:
serial_number:
type: string
description: 'Must not be greater than 128 characters.'
example: g
nullable: true
imei:
type: string
description: 'Must not be greater than 32 characters.'
example: z
nullable: true
unit_cost:
type: number
description: 'Must be at least 0.'
example: 77
nullable: true
tracked_unit_ids:
type: array
description: ''
example:
- 16
items:
type: integer
note:
type: string
description: ''
example: architecto
nullable: true
source_document_type:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
nullable: true
source_document_id:
type: integer
description: ''
example: 16
nullable: true
source_system:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
nullable: true
metadata:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- sku_id
- location_id
- movement_type
- quantity_delta
/api/v1/stock-transfers:
post:
summary: 'Create stock transfers'
operationId: createStockTransfers
description: ''
parameters: []
responses: { }
tags:
- Inventory
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
from_location_id:
type: integer
description: ''
example: 16
to_location_id:
type: integer
description: 'The value and from_location_id must be different.'
example: 16
quantity:
type: string
description: ''
example: architecto
note:
type: string
description: ''
example: architecto
nullable: true
metadata:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- sku_id
- from_location_id
- to_location_id
- quantity
/api/v1/write-offs:
get:
summary: 'List write-off'
operationId: listWriteOff
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- 'Warehouse operations'
post:
summary: 'Create write-off'
operationId: createWriteOff
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
warehouse_id:
type: integer
description: ''
example: 16
type:
type: string
description: ''
example: architecto
reason_code:
type: string
description: ''
example: architecto
notes:
type: string
description: ''
example: architecto
nullable: true
lines:
type: array
description: 'Must have at least 1 items.'
example:
- []
items:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
location_id:
type: integer
description: ''
example: 16
quantity:
type: string
description: ''
example: architecto
new_unit_cost:
type: number
description: 'Must be at least 0.'
example: 39
nullable: true
tracked_unit_ids:
type: array
description: ''
example:
- 16
items:
type: integer
notes:
type: string
description: ''
example: architecto
nullable: true
required:
- sku_id
- location_id
- quantity
required:
- warehouse_id
- lines
'/api/v1/write-offs/{writeOffId}':
get:
summary: 'Get write-off'
operationId: getWriteOff
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- 'Warehouse operations'
parameters:
-
in: path
name: writeOffId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/write-offs/{writeOffId}/complete':
post:
summary: 'Complete write-off'
operationId: completeWriteOff
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
parameters:
-
in: path
name: writeOffId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/write-offs/{writeOffId}/cancel':
post:
summary: 'Cancel write-off'
operationId: cancelWriteOff
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
parameters:
-
in: path
name: writeOffId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/stock-takes:
get:
summary: 'List stock take'
operationId: listStockTake
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- 'Warehouse operations'
post:
summary: 'Create stock take'
operationId: createStockTake
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
warehouse_id:
type: integer
description: ''
example: 16
type:
type: string
description: ''
example: architecto
scope:
type: string
description: ''
example: architecto
category_ids:
type: array
description: ''
example:
- 16
items:
type: integer
notes:
type: string
description: ''
example: architecto
nullable: true
assigned_user_id:
type: integer
description: ''
example: 16
nullable: true
lines:
type: array
description: 'Must have at least 1 items.'
example: null
items:
type: object
properties:
sku_id:
type: integer
description: 'This field is required when lines is present.'
example: 16
location_id:
type: integer
description: 'This field is required when lines is present.'
example: 16
notes:
type: string
description: ''
example: architecto
nullable: true
required:
- warehouse_id
'/api/v1/stock-takes/{stockTakeId}':
get:
summary: 'Get stock take'
operationId: getStockTake
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- 'Warehouse operations'
parameters:
-
in: path
name: stockTakeId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/stock-takes/{stockTakeId}/start':
post:
summary: 'Start stock take'
operationId: startStockTake
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
parameters:
-
in: path
name: stockTakeId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/stock-takes/{stockTakeId}/scan':
post:
summary: 'Scan during stock take'
operationId: scanDuringStockTake
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
scan:
type: string
description: 'Must not be greater than 128 characters.'
example: b
location_id:
type: integer
description: ''
example: 16
nullable: true
increment:
type: boolean
description: ''
example: true
required:
- scan
parameters:
-
in: path
name: stockTakeId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/stock-takes/{stockTakeId}/lines/{lineId}/count':
post:
summary: 'Record stock take count'
operationId: recordStockTakeCount
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
counted_quantity:
type: string
description: ''
example: architecto
notes:
type: string
description: ''
example: architecto
nullable: true
required:
- counted_quantity
parameters:
-
in: path
name: stockTakeId
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: lineId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/stock-takes/{stockTakeId}/complete':
post:
summary: 'Complete stock take'
operationId: completeStockTake
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
parameters:
-
in: path
name: stockTakeId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/stock-takes/{stockTakeId}/cancel':
post:
summary: 'Cancel stock take'
operationId: cancelStockTake
description: ''
parameters: []
responses: { }
tags:
- 'Warehouse operations'
parameters:
-
in: path
name: stockTakeId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/distributors:
get:
summary: 'List distributors'
operationId: listDistributors
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Purchasing
post:
summary: 'Create distributors'
operationId: createDistributors
description: ''
parameters: []
responses: { }
tags:
- Purchasing
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
distributor_number:
type: string
description: 'Must not be greater than 32 characters.'
example: 'n'
nullable: true
address_line1:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
address_line2:
type: string
description: 'Must not be greater than 255 characters.'
example: z
nullable: true
postal_code:
type: string
description: 'Must not be greater than 32 characters.'
example: m
nullable: true
city:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
country:
type: string
description: 'Must be 2 characters.'
example: yv
nullable: true
phone:
type: string
description: 'Must not be greater than 64 characters.'
example: d
nullable: true
contact_email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: jermaine.tillman@example.org
nullable: true
organization_number:
type: string
description: 'Must not be greater than 32 characters.'
example: h
nullable: true
website:
type: string
description: 'Must not be greater than 255 characters.'
example: w
nullable: true
notes:
type: string
description: ''
example: architecto
nullable: true
status:
type: string
description: ''
example: inactive
enum:
- active
- inactive
default_currency:
type: string
description: 'Must be 3 characters.'
example: ngz
nullable: true
required:
- name
'/api/v1/distributors/{distributorId}':
get:
summary: 'Get distributors'
operationId: getDistributors
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Purchasing
parameters:
-
in: path
name: distributorId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/purchase-orders:
get:
summary: 'List purchase order'
operationId: listPurchaseOrder
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Purchasing
post:
summary: 'Create purchase order'
operationId: createPurchaseOrder
description: ''
parameters: []
responses: { }
tags:
- Purchasing
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
warehouse_id:
type: integer
description: ''
example: 16
distributor_id:
type: integer
description: ''
example: 16
nullable: true
vendor_name:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
reference:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
expected_at:
type: string
description: 'Must be a valid date.'
example: '2026-07-10T21:07:01'
nullable: true
notes:
type: string
description: ''
example: architecto
nullable: true
currency_code:
type: string
description: 'Must be 3 characters.'
example: ngz
nullable: true
lines:
type: array
description: 'Must have at least 1 items.'
example:
- []
items:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
quantity_ordered:
type: string
description: ''
example: architecto
unit_cost:
type: number
description: 'Must be at least 0.'
example: 39
nullable: true
required:
- sku_id
- quantity_ordered
required:
- warehouse_id
- lines
'/api/v1/purchase-orders/{purchaseOrderId}':
get:
summary: 'Get purchase order'
operationId: getPurchaseOrder
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Purchasing
parameters:
-
in: path
name: purchaseOrderId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/purchase-orders/{purchaseOrderId}/submit':
post:
summary: 'Submit purchase order'
operationId: submitPurchaseOrder
description: ''
parameters: []
responses: { }
tags:
- Purchasing
parameters:
-
in: path
name: purchaseOrderId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/purchase-orders/{purchaseOrderId}/cancel':
post:
summary: 'Cancel purchase order'
operationId: cancelPurchaseOrder
description: ''
parameters: []
responses: { }
tags:
- Purchasing
parameters:
-
in: path
name: purchaseOrderId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/purchase-orders/{purchaseOrderId}/lines/{lineId}/receive':
post:
summary: 'Receive purchase order line'
operationId: receivePurchaseOrderLine
description: ''
parameters: []
responses: { }
tags:
- Purchasing
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
location_id:
type: integer
description: ''
example: 16
quantity:
type: string
description: ''
example: architecto
unit_cost:
type: number
description: 'Must be at least 0.'
example: 39
nullable: true
units:
type: array
description: ''
example: null
items:
type: object
properties:
serial_number:
type: string
description: 'Must not be greater than 128 characters.'
example: 'n'
nullable: true
imei:
type: string
description: 'Must not be greater than 32 characters.'
example: g
nullable: true
note:
type: string
description: ''
example: architecto
nullable: true
required:
- location_id
- quantity
parameters:
-
in: path
name: purchaseOrderId
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: lineId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/customers:
get:
summary: 'List customers'
operationId: listCustomers
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Sales
post:
summary: 'Create customers'
operationId: createCustomers
description: ''
parameters: []
responses: { }
tags:
- Sales
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
customer_number:
type: string
description: 'Must not be greater than 32 characters.'
example: 'n'
nullable: true
address_line1:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
address_line2:
type: string
description: 'Must not be greater than 255 characters.'
example: z
nullable: true
postal_code:
type: string
description: 'Must not be greater than 32 characters.'
example: m
nullable: true
city:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
country:
type: string
description: 'Must be 2 characters.'
example: yv
nullable: true
phone:
type: string
description: 'Must not be greater than 64 characters.'
example: d
nullable: true
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: jermaine.tillman@example.org
nullable: true
organization_number:
type: string
description: 'Must not be greater than 32 characters.'
example: h
nullable: true
status:
type: string
description: ''
example: inactive
enum:
- active
- inactive
required:
- name
'/api/v1/customers/{customerId}':
get:
summary: 'Get customers'
operationId: getCustomers
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Sales
put:
summary: 'Update customers'
operationId: updateCustomers
description: ''
parameters: []
responses: { }
tags:
- Sales
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
address_line1:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
address_line2:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
postal_code:
type: string
description: 'Must not be greater than 32 characters.'
example: z
nullable: true
city:
type: string
description: 'Must not be greater than 255 characters.'
example: m
nullable: true
country:
type: string
description: 'Must be 2 characters.'
example: iy
nullable: true
phone:
type: string
description: 'Must not be greater than 64 characters.'
example: v
nullable: true
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: jdach@example.org
nullable: true
organization_number:
type: string
description: 'Must not be greater than 32 characters.'
example: i
nullable: true
status:
type: string
description: ''
example: active
enum:
- active
- inactive
parameters:
-
in: path
name: customerId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/sales-orders:
get:
summary: 'List sales order'
operationId: listSalesOrder
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Sales
post:
summary: 'Create sales order'
operationId: createSalesOrder
description: ''
parameters: []
responses: { }
tags:
- Sales
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
warehouse_id:
type: integer
description: ''
example: 16
customer_name:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
reference:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
notes:
type: string
description: ''
example: architecto
nullable: true
lines:
type: array
description: 'Must have at least 1 items.'
example:
- []
items:
type: object
properties:
sku_id:
type: integer
description: ''
example: 16
quantity_ordered:
type: string
description: ''
example: architecto
required:
- sku_id
- quantity_ordered
required:
- warehouse_id
- customer_name
- lines
'/api/v1/sales-orders/{salesOrderId}':
get:
summary: 'Get sales order'
operationId: getSalesOrder
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Sales
parameters:
-
in: path
name: salesOrderId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/sales-orders/{salesOrderId}/confirm':
post:
summary: 'Confirm and reserve sales order'
operationId: confirmAndReserveSalesOrder
description: ''
parameters: []
responses: { }
tags:
- Sales
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
allocations:
type: array
description: 'Must have at least 1 items.'
example:
- []
items:
type: object
properties:
line_id:
type: integer
description: ''
example: 16
location_id:
type: integer
description: ''
example: 16
quantity:
type: string
description: ''
example: architecto
required:
- line_id
- location_id
- quantity
required:
- allocations
parameters:
-
in: path
name: salesOrderId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/sales-orders/{salesOrderId}/cancel':
post:
summary: 'Cancel sales order'
operationId: cancelSalesOrder
description: ''
parameters: []
responses: { }
tags:
- Sales
parameters:
-
in: path
name: salesOrderId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/sales-orders/{salesOrderId}/allocations/{allocationId}/pick':
post:
summary: 'Pick allocated stock'
operationId: pickAllocatedStock
description: ''
parameters: []
responses: { }
tags:
- Sales
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
quantity:
type: string
description: ''
example: architecto
note:
type: string
description: ''
example: architecto
nullable: true
required:
- quantity
parameters:
-
in: path
name: salesOrderId
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: allocationId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/sales-orders/{salesOrderId}/allocations/{allocationId}/ship':
post:
summary: 'Ship picked stock'
operationId: shipPickedStock
description: ''
parameters: []
responses: { }
tags:
- Sales
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
quantity:
type: string
description: ''
example: architecto
tracked_unit_ids:
type: array
description: ''
example:
- 16
items:
type: integer
note:
type: string
description: ''
example: architecto
nullable: true
required:
- quantity
parameters:
-
in: path
name: salesOrderId
description: ''
example: architecto
required: true
schema:
type: string
-
in: path
name: allocationId
description: ''
example: architecto
required: true
schema:
type: string
/api/v1/integrations/tripletex/webhook-guide:
get:
summary: 'Tripletex webhook guide'
operationId: tripletexWebhookGuide
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Integrations
/api/v1/integrations/tripletex/sync-products:
post:
summary: 'Sync products from Tripletex'
operationId: syncProductsFromTripletex
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
/api/v1/integrations/tripletex/sync-all:
post:
summary: 'Inbound sync (all entities)'
operationId: inboundSyncallEntities
description: ''
parameters: []
responses: { }
tags:
- Integrations
/api/v1/integrations/tripletex/reconcile:
post:
summary: 'Two-way reconciliation'
operationId: twoWayReconciliation
description: ''
parameters: []
responses: { }
tags:
- Integrations
/api/v1/integrations/tripletex/push-products:
post:
summary: 'Push products to Tripletex'
operationId: pushProductsToTripletex
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
product_id:
type: integer
description: ''
example: 16
/api/v1/integrations/tripletex/sync-orders:
post:
summary: 'Sync sales orders from Tripletex'
operationId: syncSalesOrdersFromTripletex
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
/api/v1/integrations/tripletex/sync-suppliers:
post:
summary: 'Sync suppliers from Tripletex'
operationId: syncSuppliersFromTripletex
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
/api/v1/integrations/tripletex/sync-customers:
post:
summary: 'Sync customers from Tripletex'
operationId: syncCustomersFromTripletex
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
/api/v1/integrations/tripletex/sync-employees:
post:
summary: 'Sync Employees'
operationId: syncEmployees
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
/api/v1/integrations/webhook-events:
get:
summary: 'List webhook events'
operationId: listWebhookEvents
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
status:
type: string
description: 'Must not be greater than 32 characters.'
example: 'n'
event:
type: string
description: 'Must not be greater than 128 characters.'
example: g
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 100.'
example: 16
/api/v1/integrations/tripletex/webhook-subscriptions:
get:
summary: 'List webhook subscriptions'
operationId: listWebhookSubscriptions
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Integrations
put:
summary: 'Update webhook subscriptions'
operationId: updateWebhookSubscriptions
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
connection_id:
type: integer
description: ''
example: 16
events:
type: array
description: ''
example:
- architecto
items:
type: string
/api/v1/integrations:
get:
summary: 'List integration connection'
operationId: listIntegrationConnection
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Integrations
post:
summary: 'Create integration connection'
operationId: createIntegrationConnection
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
provider:
type: string
description: 'Must not be greater than 64 characters.'
example: 'n'
status:
type: string
description: ''
example: inactive
enum:
- active
- inactive
- error
credentials:
type: object
description: ''
example: null
properties: { }
nullable: true
settings:
type: object
description: ''
example: null
properties: { }
nullable: true
required:
- name
- provider
'/api/v1/integrations/{connectionId}':
get:
summary: 'Get integration connection'
operationId: getIntegrationConnection
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Integrations
put:
summary: 'Update integration connection'
operationId: updateIntegrationConnection
description: ''
parameters: []
responses: { }
tags:
- Integrations
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
status:
type: string
description: ''
example: error
enum:
- active
- inactive
- error
credentials:
type: object
description: ''
example: null
properties: { }
nullable: true
settings:
type: object
description: ''
example: null
properties: { }
nullable: true
parameters:
-
in: path
name: connectionId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/integrations/{connectionId}/test':
post:
summary: 'Test integration connection'
operationId: testIntegrationConnection
description: ''
parameters: []
responses: { }
tags:
- Integrations
parameters:
-
in: path
name: connectionId
description: ''
example: architecto
required: true
schema:
type: string
'/api/v1/webhooks/tripletex/{tenantSlug}':
post:
summary: 'Tripletex webhook receiver'
operationId: tripletexWebhookReceiver
description: 'Inbound events from Tripletex. Authenticated via webhook signature middleware, not Bearer tokens.'
parameters: []
responses: { }
tags:
- Webhooks
security: []
parameters:
-
in: path
name: tenantSlug
description: 'Tenant slug configured for the webhook.'
example: demo
required: true
schema:
type: string