forge-erp API (1.0.0)

Download OpenAPI specification:

Ramraj Patil: ramrajpatil24@gmail.com License: Proprietary

REST API for forge-erp, a single-tenant manufacturing ERP. The modules integrate around one flow: Sales Order → Production Order (via BOM) → Purchase Orders for materials → Goods Receipt → Inventory → production through Work Centers → Quality → Delivery → Invoice → Payment → auto-posted Journal Entries.

Authentication. All endpoints require a JWT bearer access token except POST /auth/login and POST /auth/refresh. Obtain a token from /auth/login, then send Authorization: Bearer <accessToken> on every other request. Access tokens expire after 20 minutes; use /auth/refresh with the refresh token to obtain a new pair.

Authorization. Access is permission-based, not role-based. Each write/read is gated by a fine-grained permission (e.g. MASTERDATA_WRITE, PO_APPROVE); a role is a bundle of permissions. The required permission is stated in each operation's description. A missing permission returns 403.

Errors. Every error is an RFC 7807 problem document (application/problem+json) with the shape shown in the ProblemDetail schema. See the Frontend Integration Guide for the full status-code taxonomy.

Pagination & sorting. List endpoints return a PagedResponse and accept page (0-based), size (default 20, max 100, clamped), and sort=field,dir. Each endpoint allows sorting only on a declared set of fields; an unknown field returns 400.

Author. Designed and built by Ramraj Patilramrajpatil24@gmail.com.

Auth

Login and token refresh. The only endpoints that do not require a token.

Log in and obtain a token pair

Exchange a username and password for an access/refresh token pair. This is one of only two endpoints that do not require a bearer token. On success, send the returned accessToken as Authorization: Bearer <accessToken> on all other requests. Invalid credentials return 401.

Request Body schema: application/json
required
username
required
string

Account username.

password
required
string <password>

Account password.

Responses

Request samples

Content type
application/json
{
  • "username": "ramraj.system",
  • "password": "local-dev-admin-change-me"
}

Response samples

Content type
application/json
{
  • "accessToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhcnVuLnN5c3RlbSIsInVpZCI6Mzg3NDAxfQ...",
  • "refreshToken": "9f2c1e7a4b3d4f8e9a0b1c2d3e4f5a6b",
  • "tokenType": "Bearer",
  • "expiresIn": 1200
}

Refresh the token pair

Exchange a valid, unexpired refresh token for a new access/refresh token pair (rotation). The old refresh token is consumed. A missing, expired, revoked, or already-used token returns 401. Does not require a bearer token.

Request Body schema: application/json
required
refreshToken
required
string

The raw refresh token returned at login/refresh time.

Responses

Request samples

Content type
application/json
{
  • "refreshToken": "9f2c1e7a4b3d4f8e9a0b1c2d3e4f5a6b"
}

Response samples

Content type
application/json
{
  • "accessToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhcnVuLnN5c3RlbSJ9...",
  • "refreshToken": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
  • "tokenType": "Bearer",
  • "expiresIn": 1200
}

Log out (revoke a refresh token)

Ends a device's session by revoking the supplied refresh token (same request body as /auth/refresh). Like the other auth endpoints it is public — no bearer token is required, so a user whose access token has already expired can still log out. Revoking an unknown, expired, or already-revoked token is a deliberate no-op: the endpoint always returns 204 and never reveals whether the token was valid. After it returns, discard both tokens on the client and send the user back to login.

Request Body schema: application/json
required
refreshToken
required
string

The raw refresh token returned at login/refresh time.

Responses

Request samples

Content type
application/json
{
  • "refreshToken": "9f2c1e7a4b3d4f8e9a0b1c2d3e4f5a6b"
}

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Validation failed",
  • "status": 400,
  • "detail": "One or more fields are invalid.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z",
  • "errors": {
    }
}

Master Data

Products, product categories, units of measure, and warehouses.

List materials

Returns a paged list of materials — things consumed to build: raw materials, consumables, and manufacturable sub-assemblies (Phase 10 split product into material + product). Optionally filter by a free-text search term (case-insensitive LIKE over SKU and name) and/or an exact type. Requires permission: MASTERDATA_READ. Sortable fields (allow-list): sku, name, type, createdAt; default sort is createdAt,desc. Sorting by any other field returns 400.

Authorizations:
bearerAuth
query Parameters
search
string
Example: search=SS316

Case-insensitive substring matched against SKU or name. Omit to match all.

type
string (MaterialType)
Enum: "RAW_MATERIAL" "WIP"

Exact material-type filter. Omit to include all types.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a material

Creates a material. sku must be unique. uomId must reference an existing unit of measure; categoryId, when supplied, must reference an existing category. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
sku
required
string <= 60 characters

Stock-keeping unit. Unique across all materials.

name
required
string <= 200 characters

Human-readable material name.

type
required
string (MaterialType)
Enum: "RAW_MATERIAL" "WIP"

Kind of material: a purchased raw material or consumable (RAW_MATERIAL), or a manufacturable sub-assembly with its own BOM (WIP).

hsnCode
string <= 8 characters

Optional HSN classification code for GST, printed on purchase-invoice lines. Validated loosely (4-8 digits) — editable master data.

categoryId
integer <int64>

Optional category reference. Must exist when supplied.

uomId
required
integer <int64>

Required unit-of-measure reference. Must exist.

Responses

Request samples

Content type
application/json
{
  • "sku": "SS316-TUBE-19",
  • "name": "Stainless Steel Tube SS316, 19mm OD",
  • "type": "RAW_MATERIAL",
  • "categoryId": 5,
  • "uomId": 2
}

Response samples

Content type
application/json
{
  • "id": 88,
  • "sku": "SS316-TUBE-19",
  • "name": "Stainless Steel Tube SS316, 19mm OD",
  • "type": "RAW_MATERIAL",
  • "hsnCode": "7304",
  • "categoryId": 5,
  • "categoryName": "Tubes & Piping",
  • "uomId": 2,
  • "uomCode": "M",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a material

Returns one material by id. Requires permission: MASTERDATA_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Material id.

Responses

Response samples

Content type
application/json
{
  • "id": 88,
  • "sku": "SS316-TUBE-19",
  • "name": "Stainless Steel Tube SS316, 19mm OD",
  • "type": "RAW_MATERIAL",
  • "hsnCode": "7304",
  • "categoryId": 5,
  • "categoryName": "Tubes & Piping",
  • "uomId": 2,
  • "uomCode": "M",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a material

Updates an existing material. sku must remain unique; uomId (and categoryId when supplied) must reference existing rows. Subject to optimistic locking — a concurrent modification returns 409. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Material id.

Request Body schema: application/json
required
sku
required
string <= 60 characters

Stock-keeping unit. Unique across all materials.

name
required
string <= 200 characters

Human-readable material name.

type
required
string (MaterialType)
Enum: "RAW_MATERIAL" "WIP"

Kind of material: a purchased raw material or consumable (RAW_MATERIAL), or a manufacturable sub-assembly with its own BOM (WIP).

hsnCode
string <= 8 characters

Optional HSN classification code for GST, printed on purchase-invoice lines. Validated loosely (4-8 digits) — editable master data.

categoryId
integer <int64>

Optional category reference. Must exist when supplied.

uomId
required
integer <int64>

Required unit-of-measure reference. Must exist.

Responses

Request samples

Content type
application/json
{
  • "sku": "SS316-TUBE-19",
  • "name": "Stainless Steel Tube SS316, 19mm OD",
  • "type": "RAW_MATERIAL",
  • "categoryId": 5,
  • "uomId": 2
}

Response samples

Content type
application/json
{
  • "id": 88,
  • "sku": "SS316-TUBE-19",
  • "name": "Stainless Steel Tube SS316, 19mm OD",
  • "type": "RAW_MATERIAL",
  • "hsnCode": "7304",
  • "categoryId": 5,
  • "categoryName": "Tubes & Piping",
  • "uomId": 2,
  • "uomCode": "M",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a material

Deletes a material. A material still referenced by any other record (a BOM component, supplier catalog entry, purchase-order or goods-receipt line, a design/production target, stock, or an AP invoice line) cannot be deleted and returns 422 — remove or reassign the references first. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Material id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List products

Returns a paged list of products. Optionally filter by a free-text search term (case-insensitive LIKE over SKU and name) and/or an exact product type. Requires permission: MASTERDATA_READ. Sortable fields (allow-list): sku, name, type, createdAt; default sort is createdAt,desc. Sorting by any other field returns 400.

Authorizations:
bearerAuth
query Parameters
search
string
Example: search=HX

Case-insensitive substring matched against SKU or name. Omit to match all.

type
string (ProductType)
Enum: "RAW_MATERIAL" "WIP" "FINISHED_GOOD"

Exact product-type filter. Omit to include all types.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a product

Creates a product. sku must be unique. uomId must reference an existing unit of measure; categoryId, when supplied, must reference an existing category. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
sku
required
string <= 60 characters

Stock-keeping unit. Unique across all products.

name
required
string <= 200 characters

Human-readable product name.

type
required
string (ProductType)
Enum: "RAW_MATERIAL" "WIP" "FINISHED_GOOD"

Where a product sits in the manufacturing flow: a purchased input (RAW_MATERIAL), an intermediate produced and consumed internally (WIP), or a sellable output (FINISHED_GOOD).

hsnCode
string <= 8 characters

Optional HSN classification code for GST, printed on tax-invoice lines. Validated loosely (4-8 digits) — editable master data.

categoryId
integer <int64>

Optional product-category reference. Must exist when supplied.

uomId
required
integer <int64>

Required unit-of-measure reference. Must exist.

materialId
integer <int64>

Optional spare-face link — the material this product is the sellable face of. When set, the product carries no BOM and its stock draws from the linked material. Create-only: ignored on update.

Responses

Request samples

Content type
application/json
{
  • "sku": "FG-ST-001",
  • "name": "Shell & Tube HX, SS316 Tubes, 4.5 m2, BEM Type",
  • "type": "FINISHED_GOOD",
  • "categoryId": 3,
  • "uomId": 1
}

Response samples

Content type
application/json
{
  • "id": 42,
  • "sku": "FG-ST-001",
  • "name": "Shell & Tube HX, SS316 Tubes, 4.5 m2, BEM Type",
  • "type": "RAW_MATERIAL",
  • "hsnCode": "8419",
  • "categoryId": 3,
  • "categoryName": "Shell & Tube Exchangers",
  • "uomId": 1,
  • "uomCode": "NOS",
  • "materialId": 88,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a product

Returns one product by id. Requires permission: MASTERDATA_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Product id.

Responses

Response samples

Content type
application/json
{
  • "id": 42,
  • "sku": "FG-ST-001",
  • "name": "Shell & Tube HX, SS316 Tubes, 4.5 m2, BEM Type",
  • "type": "RAW_MATERIAL",
  • "hsnCode": "8419",
  • "categoryId": 3,
  • "categoryName": "Shell & Tube Exchangers",
  • "uomId": 1,
  • "uomCode": "NOS",
  • "materialId": 88,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a product

Updates an existing product. sku must remain unique; uomId (and categoryId when supplied) must reference existing rows. Subject to optimistic locking — a concurrent modification returns 409. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Product id.

Request Body schema: application/json
required
sku
required
string <= 60 characters

Stock-keeping unit. Unique across all products.

name
required
string <= 200 characters

Human-readable product name.

type
required
string (ProductType)
Enum: "RAW_MATERIAL" "WIP" "FINISHED_GOOD"

Where a product sits in the manufacturing flow: a purchased input (RAW_MATERIAL), an intermediate produced and consumed internally (WIP), or a sellable output (FINISHED_GOOD).

hsnCode
string <= 8 characters

Optional HSN classification code for GST, printed on tax-invoice lines. Validated loosely (4-8 digits) — editable master data.

categoryId
integer <int64>

Optional product-category reference. Must exist when supplied.

uomId
required
integer <int64>

Required unit-of-measure reference. Must exist.

materialId
integer <int64>

Optional spare-face link — the material this product is the sellable face of. When set, the product carries no BOM and its stock draws from the linked material. Create-only: ignored on update.

Responses

Request samples

Content type
application/json
{
  • "sku": "FG-ST-001",
  • "name": "Shell & Tube HX, SS316 Tubes, 4.5 m2, BEM Type",
  • "type": "FINISHED_GOOD",
  • "categoryId": 3,
  • "uomId": 1
}

Response samples

Content type
application/json
{
  • "id": 42,
  • "sku": "FG-ST-001",
  • "name": "Shell & Tube HX, SS316 Tubes, 4.5 m2, BEM Type",
  • "type": "RAW_MATERIAL",
  • "hsnCode": "8419",
  • "categoryId": 3,
  • "categoryName": "Shell & Tube Exchangers",
  • "uomId": 1,
  • "uomCode": "NOS",
  • "materialId": 88,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a product

Deletes a product. A product still referenced by any other record (inventory, procurement, manufacturing, sales, or finance) cannot be deleted and returns 422 — remove or reassign the references first. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Product id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List product categories

Returns a paged list of product categories. Optionally filter by a free-text search term (case-insensitive LIKE over the category name). Requires permission: MASTERDATA_READ. Sortable fields (allow-list): name, createdAt; default sort is name,asc. Sorting by any other field returns 400.

Authorizations:
bearerAuth
query Parameters
search
string
Example: search=Exchangers

Case-insensitive substring matched against the category name. Omit to match all.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a product category

Creates a product category. name must be unique. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string <= 120 characters

Category name. Unique across all categories.

Responses

Request samples

Content type
application/json
{
  • "name": "Shell & Tube Exchangers"
}

Response samples

Content type
application/json
{
  • "id": 3,
  • "name": "Shell & Tube Exchangers",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a product category

Returns one product category by id. Requires permission: MASTERDATA_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Product category id.

Responses

Response samples

Content type
application/json
{
  • "id": 3,
  • "name": "Shell & Tube Exchangers",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a product category

Updates a product category. name must remain unique. Subject to optimistic locking — a concurrent modification returns 409. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Product category id.

Request Body schema: application/json
required
name
required
string <= 120 characters

Category name. Unique across all categories.

Responses

Request samples

Content type
application/json
{
  • "name": "Shell & Tube Exchangers"
}

Response samples

Content type
application/json
{
  • "id": 3,
  • "name": "Shell & Tube Exchangers",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a product category

Deletes a product category. A category still assigned to one or more products cannot be deleted and returns 422 — reassign or remove those products first. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Product category id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List units of measure

Returns a paged list of units of measure. Optionally filter by a free-text search term (case-insensitive LIKE over code and name). Requires permission: MASTERDATA_READ. Sortable fields (allow-list): code, name; default sort is code,asc. Sorting by any other field returns 400.

Authorizations:
bearerAuth
query Parameters
search
string
Example: search=KG

Case-insensitive substring matched against code or name. Omit to match all.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a unit of measure

Creates a unit of measure. code must be unique. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
code
required
string <= 20 characters

Short unit code. Unique across all units.

name
required
string <= 80 characters

Full unit name.

Responses

Request samples

Content type
application/json
{
  • "code": "NOS",
  • "name": "Numbers"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "code": "NOS",
  • "name": "Numbers",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a unit of measure

Returns one unit of measure by id. Requires permission: MASTERDATA_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Unit-of-measure id.

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "code": "NOS",
  • "name": "Numbers",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a unit of measure

Updates a unit of measure. code must remain unique. Subject to optimistic locking — a concurrent modification returns 409. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Unit-of-measure id.

Request Body schema: application/json
required
code
required
string <= 20 characters

Short unit code. Unique across all units.

name
required
string <= 80 characters

Full unit name.

Responses

Request samples

Content type
application/json
{
  • "code": "NOS",
  • "name": "Numbers"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "code": "NOS",
  • "name": "Numbers",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a unit of measure

Deletes a unit of measure. A unit still used by one or more products cannot be deleted and returns 422 — reassign or remove those products first. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Unit-of-measure id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List warehouses

Returns a paged list of warehouses. Optionally filter by a free-text search term (case-insensitive LIKE over name and location). Requires permission: MASTERDATA_READ. Sortable fields (allow-list): name, location, createdAt; default sort is name,asc. Sorting by any other field returns 400.

Authorizations:
bearerAuth
query Parameters
search
string
Example: search=Chennai

Case-insensitive substring matched against name or location. Omit to match all.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a warehouse

Creates a warehouse. name must be unique. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string <= 120 characters

Warehouse name. Unique across all warehouses.

location
string <= 255 characters

Optional free-text physical location.

Responses

Request samples

Content type
application/json
{
  • "name": "Main Raw Material Store",
  • "location": "Ambattur Industrial Estate, Chennai, TN"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Main Raw Material Store",
  • "location": "Ambattur Industrial Estate, Chennai, TN",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a warehouse

Returns one warehouse by id. Requires permission: MASTERDATA_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Warehouse id.

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Main Raw Material Store",
  • "location": "Ambattur Industrial Estate, Chennai, TN",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a warehouse

Updates a warehouse. name must remain unique. Subject to optimistic locking — a concurrent modification returns 409. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Warehouse id.

Request Body schema: application/json
required
name
required
string <= 120 characters

Warehouse name. Unique across all warehouses.

location
string <= 255 characters

Optional free-text physical location.

Responses

Request samples

Content type
application/json
{
  • "name": "Main Raw Material Store",
  • "location": "Ambattur Industrial Estate, Chennai, TN"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Main Raw Material Store",
  • "location": "Ambattur Industrial Estate, Chennai, TN",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a warehouse

Deletes a warehouse. A warehouse referenced by stock levels/movements, goods receipts, or orders cannot be deleted and returns 422 — remove or reassign those references first. Requires permission: MASTERDATA_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Warehouse id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Inventory

Stock levels (on-hand / reserved / QC-hold projection) and the append-only stock-movement ledger.

List stock levels

Paginated projection of current stock levels, one row per (item, warehouse). Each row exposes the three independent quantity dimensions: quantityOnHand (physically available and issuable), reserved (committed to confirmed sales orders, moved out of on-hand at confirm), and quantityQcHold (produced but not yet released by quality — invisible to availability until a quality PASS). Levels are always derived from the append-only movement ledger, never written directly.

Since the Phase-10 product/material split there are two parallel ledgers. kind (material/product, case-insensitive) selects which ledger to list, so each can be browsed in full without naming an item. When kind is absent it resolves from the item: productId here is a generic item id that routes to the material ledger when a material has that id, otherwise the product ledger (with neither kind nor productId, the product ledger is listed). A material row's id/sku/name come back in the productId/productSku/productName fields. Optionally filtered by productId and/or warehouseId (independent AND filters). Sortable fields: quantityOnHand, updatedAt (default updatedAt,desc); any other sort field returns 400.

Requires permission: INVENTORY_READ.

Authorizations:
bearerAuth
query Parameters
kind
string
Enum: "material" "product"
Example: kind=material

Which ledger to list — material or product (case-insensitive). Absent, the ledger is resolved from productId (material-first, product default).

productId
integer <int64>
Example: productId=42

Restrict to a single item (material or product id).

warehouseId
integer <int64>
Example: warehouseId=3

Restrict to a single warehouse.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Get the current stock level for one item in one warehouse

Returns the single stock-level row for the given (item, warehouse) pair — its on-hand, reserved, and QC-hold quantities. productId is a generic item id (Phase-10 split): a material id routes to the material ledger, otherwise the product ledger, and a material's id/sku/name come back in the product* fields. Returns 404 when no movement has ever been recorded for that pair (no level row exists yet). Both query parameters are required; a missing one is a 400.

Requires permission: INVENTORY_READ.

Authorizations:
bearerAuth
query Parameters
productId
required
integer <int64>
Example: productId=42

The item to look up (material or product id).

warehouseId
required
integer <int64>
Example: warehouseId=3

The warehouse to look up.

Responses

Response samples

Content type
application/json
{
  • "id": 512,
  • "productId": 42,
  • "productSku": "FG-ST-001",
  • "productName": "Structural Steel Bracket",
  • "warehouseId": 3,
  • "warehouseName": "Main Raw Material Store",
  • "quantityOnHand": 1240,
  • "reserved": 120,
  • "quantityQcHold": 0,
  • "updatedAt": "2026-07-09T11:02:44.113Z"
}

List the warehouses that stock a material

Returns every warehouse in which the given material currently has positive on-hand stock (on-hand > 0), each with its on-hand quantity — the lookup behind a production planner's per-component source-warehouse picker, so only the stores that can actually supply a component are offered. Reads the material ledger only (a production component is always drawn from material stock). A material with no on-hand anywhere returns an empty array. The result is a plain array, not a paged response.

Requires permission: INVENTORY_READ or MASTERDATA_READ.

Authorizations:
bearerAuth
query Parameters
materialId
required
integer <int64>
Example: materialId=42

The material to look up on-hand stock for, per warehouse.

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

List stock movements

Paginated view of the append-only stock-movement ledger — the immutable, insert-only record of every quantity change (there is no update or delete). Each row carries a signed quantity (inbound positive, outbound negative), its movementType, and optional refType/refId lineage back to the source document (goods receipt, delivery, production or quality event) plus an optional lotNumber (heat number) for traceability.

Since the Phase-10 split there are two parallel ledgers. kind (material/product, case-insensitive) selects which ledger to list, so a whole ledger can be browsed without naming an item. When kind is absent it resolves from the item: productId is a generic item id that routes to the material ledger when a material has that id, otherwise the product ledger (with neither kind nor productId, the product ledger is listed), and a material row's id/sku/name come back in the productId/productSku/productName fields. Optionally filtered by productId, warehouseId, movementType, and/or the source-document reference (refType + refId) — independent AND filters. Filtering by refType/refId lists exactly the movements one document produced (e.g. a production order's issues and output). An unrecognised movementType value is a 400. Sortable fields: createdAt, movementType, quantity (default createdAt,desc); any other sort field returns 400.

Requires permission: INVENTORY_READ.

Authorizations:
bearerAuth
query Parameters
kind
string
Enum: "material" "product"
Example: kind=material

Which ledger to list — material or product (case-insensitive). Absent, the ledger is resolved from productId (material-first, product default).

productId
integer <int64>
Example: productId=42

Restrict to a single item (material or product id).

warehouseId
integer <int64>
Example: warehouseId=3

Restrict to a single warehouse.

movementType
string
Enum: "RECEIPT" "ISSUE" "ADJUSTMENT" "PRODUCTION_ISSUE" "PRODUCTION_OUTPUT" "QC_RELEASE" "QC_REJECT" "SALES_SHIPMENT"
Example: movementType=ADJUSTMENT

Restrict to a single movement type. An unrecognised value returns 400.

refType
string
Example: refType=PRODUCTION_ORDER

Source-document type of the movement's lineage (e.g. GOODS_RECEIPT, PRODUCTION_ORDER, DELIVERY, QUALITY_INSPECTION). Pair with refId to list a single document's movements.

refId
integer <int64>
Example: refId=7100

Source-document id of the movement's lineage; typically used together with refType.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Record a manual receipt

Records an inbound RECEIPT movement: the positive quantity is added to on-hand for the (product, warehouse) pair. The ledger row and the atomic on-hand upsert happen in one transaction, so concurrent movements cannot lose an update. Inbound movements can never breach the no-negative-stock rule, so a receipt is always accepted. refType/refId optionally link the movement to a source document.

This is the manual entry point; the system-driven receipt from a goods receipt runs through an internal, non-HTTP entry point that stamps its own lineage. An unknown product or warehouse returns 404.

Requires permission: INVENTORY_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
productId
required
integer <int64>

Item being moved (Phase-10 split) — a material id routes to material stock, otherwise product stock.

warehouseId
required
integer <int64>

Warehouse the movement applies to.

quantity
required
number > 0

Positive amount to move (up to 15 integer digits, 4 fraction digits).

refType
string <= 30 characters

Optional source-document type for lineage.

refId
integer <int64>

Optional source-document identifier.

Responses

Request samples

Content type
application/json
{
  • "productId": 42,
  • "warehouseId": 3,
  • "quantity": 500,
  • "refType": "GOODS_RECEIPT",
  • "refId": 8801
}

Response samples

Content type
application/json
{
  • "id": 90231,
  • "movementType": "RECEIPT",
  • "productId": 42,
  • "productSku": "FG-ST-001",
  • "productName": "Structural Steel Bracket",
  • "warehouseId": 3,
  • "warehouseName": "Main Raw Material Store",
  • "quantity": 500,
  • "refType": "GOODS_RECEIPT",
  • "refId": 8801,
  • "note": null,
  • "lotNumber": null,
  • "createdBy": 387401,
  • "createdAt": "2026-07-09T11:05:12.004Z"
}

Record a manual issue

Records an outbound ISSUE movement: the positive quantity in the request is stored as a negative delta and subtracted from on-hand for the (product, warehouse) pair, atomically alongside the ledger insert. Guarded by the no-negative-stock rule — if the issue would drive on-hand below zero the whole transaction rolls back (no phantom movement is persisted) and the request returns 422. refType/refId optionally link the movement to a source document. An unknown product or warehouse returns 404.

Requires permission: INVENTORY_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
productId
required
integer <int64>

Item being moved (Phase-10 split) — a material id routes to material stock, otherwise product stock.

warehouseId
required
integer <int64>

Warehouse the movement applies to.

quantity
required
number > 0

Positive amount to move (up to 15 integer digits, 4 fraction digits).

refType
string <= 30 characters

Optional source-document type for lineage.

refId
integer <int64>

Optional source-document identifier.

Responses

Request samples

Content type
application/json
{
  • "productId": 42,
  • "warehouseId": 3,
  • "quantity": 20,
  • "refType": "DELIVERY",
  • "refId": 4410
}

Response samples

Content type
application/json
{
  • "id": 90232,
  • "movementType": "ISSUE",
  • "productId": 42,
  • "productSku": "FG-ST-001",
  • "productName": "Structural Steel Bracket",
  • "warehouseId": 3,
  • "warehouseName": "Main Raw Material Store",
  • "quantity": -20,
  • "refType": "DELIVERY",
  • "refId": 4410,
  • "note": null,
  • "lotNumber": null,
  • "createdBy": 387401,
  • "createdAt": "2026-07-09T11:06:41.552Z"
}

Record a manual stock adjustment

Records a manual ADJUSTMENT movement — a signed correction such as a write-off (negative) or a recount correction (positive). Unlike a receipt or issue, quantity here is a signed delta and MAY drive on-hand to any value, including negative, so the no-negative-stock rule does not apply. The quantity must be non-zero (a zero adjustment returns 422). The optional reason is recorded on the ledger row for the audit trail; refType is stamped as ADJUSTMENT. An unknown product or warehouse returns 404.

This is the segregated, higher-privilege write: it is gated by STOCK_ADJUST, separate from the ordinary INVENTORY_WRITE used for receipts and issues.

Requires permission: STOCK_ADJUST.

Authorizations:
bearerAuth
Request Body schema: application/json
required
productId
required
integer <int64>

Item being adjusted (Phase-10 split) — a material id routes to material stock, otherwise product stock.

warehouseId
required
integer <int64>

Warehouse the adjustment applies to.

quantity
required
number

Signed, non-zero delta (up to 15 integer digits, 4 fraction digits). Negative writes off, positive corrects up.

reason
string <= 255 characters

Optional reason recorded on the ledger row for the audit trail.

Responses

Request samples

Content type
application/json
{
  • "productId": 42,
  • "warehouseId": 3,
  • "quantity": -12,
  • "reason": "Cycle count write-off — damaged units"
}

Response samples

Content type
application/json
{
  • "id": 90233,
  • "movementType": "ADJUSTMENT",
  • "productId": 42,
  • "productSku": "FG-ST-001",
  • "productName": "Structural Steel Bracket",
  • "warehouseId": 3,
  • "warehouseName": "Main Raw Material Store",
  • "quantity": -12,
  • "refType": "ADJUSTMENT",
  • "refId": null,
  • "note": "Cycle count write-off — damaged units",
  • "lotNumber": null,
  • "createdBy": 387401,
  • "createdAt": "2026-07-09T11:08:19.870Z"
}

Design

Engineering design documents (drawings/specs) with a DRAFT → RELEASED lifecycle.

List design documents

Returns a paginated page of engineering design documents (drawings/specs). Optionally filter by target (productId or materialId — a document targets a product XOR a material) and/or status (independent AND filters). Sortable fields: revision, status, createdAt (default sort createdAt,desc); an unlisted sort field returns 400. Requires permission: DESIGN_READ.

Authorizations:
bearerAuth
query Parameters
productId
integer <int64>

Only documents targeting this product.

materialId
integer <int64>

Only documents targeting this material (sub-assembly).

status
string (DesignStatus)
Enum: "DRAFT" "IN_REVIEW" "CHANGES_REQUESTED" "RELEASED"
Example: status=DRAFT

Only documents in this lifecycle state.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a design document

Creates a new design document. It is always created in DRAFT status; the status cannot be set through this payload — a document moves through its review lifecycle only via the submit / release / request-changes / revise endpoints. The revision is assigned by the system (1.0 for the target item's first document, then the next whole number) and cannot be supplied. The referenced product must exist (else 404). Requires permission: DESIGN_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
productId
integer <int64>

Product target (exactly one of productId / materialId). Set when the document designs a sellable product.

materialId
integer <int64>

Material target (exactly one of productId / materialId). Set when the document designs a manufacturable material (sub-assembly).

title
required
string <= 200 characters

Human-readable document title.

Responses

Request samples

Content type
application/json
{
  • "productId": 42,
  • "title": "Shell & Tube HX GA Drawing"
}

Response samples

Content type
application/json
{
  • "id": 501,
  • "productId": 42,
  • "productSku": "HX-1200",
  • "revision": "1.0",
  • "title": "Shell & Tube HX GA Drawing",
  • "status": "DRAFT",
  • "createdAt": "2026-07-09T14:12:03.221Z",
  • "updatedAt": "2026-07-09T14:12:03.221Z"
}

Preview the next revision for a target

The revision a create would assign for a target item — 1.0 for its first design document, then the next whole number (2.0, 3.0, …). Supply exactly one of productId / materialId (zero or both is a 422). Lets the create form show the read-only revision before saving; it uses the same computation as create. Requires permission: DESIGN_WRITE.

Authorizations:
bearerAuth
query Parameters
productId
integer <int64>

Product target (exactly one of productId / materialId).

materialId
integer <int64>

Material target (exactly one of productId / materialId).

Responses

Response samples

Content type
application/json
{
  • "revision": "2.0"
}

Get a design document

Returns a single design document by id. Requires permission: DESIGN_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Design document id.

Responses

Response samples

Content type
application/json
{
  • "id": 501,
  • "productId": 42,
  • "productSku": "HX-1200",
  • "materialId": 88,
  • "materialSku": "SS316-TUBE-19",
  • "revision": "1.0",
  • "title": "Shell & Tube HX GA Drawing",
  • "status": "DRAFT",
  • "createdBy": 51001,
  • "createdByName": "dana.designer",
  • "submittedBy": 51001,
  • "submittedByName": "dana.designer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 51007,
  • "approvedByName": "raj.designmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "changesRequestedBy": 51007,
  • "changesRequestedByName": "raj.designmgr",
  • "changesRequestedAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2026-07-09T14:12:03.221Z",
  • "updatedAt": "2026-07-09T14:12:03.221Z"
}

Update a design document

Updates a design document — allowed only while it is DRAFT. Once submitted it is under review, and a RELEASED document is a controlled record; editing in any non-draft state returns 422 (revise a CHANGES_REQUESTED document back to DRAFT, or supersede a release with a new revision, first). The referenced product must exist (else 404). Requires permission: DESIGN_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Design document id.

Request Body schema: application/json
required
productId
integer <int64>

Product target (exactly one of productId / materialId). Set when the document designs a sellable product.

materialId
integer <int64>

Material target (exactly one of productId / materialId). Set when the document designs a manufacturable material (sub-assembly).

title
required
string <= 200 characters

Human-readable document title.

Responses

Request samples

Content type
application/json
{
  • "productId": 42,
  • "title": "Shell & Tube HX GA Drawing (updated)"
}

Response samples

Content type
application/json
{
  • "id": 501,
  • "productId": 42,
  • "productSku": "HX-1200",
  • "materialId": 88,
  • "materialSku": "SS316-TUBE-19",
  • "revision": "1.0",
  • "title": "Shell & Tube HX GA Drawing",
  • "status": "DRAFT",
  • "createdBy": 51001,
  • "createdByName": "dana.designer",
  • "submittedBy": 51001,
  • "submittedByName": "dana.designer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 51007,
  • "approvedByName": "raj.designmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "changesRequestedBy": 51007,
  • "changesRequestedByName": "raj.designmgr",
  • "changesRequestedAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2026-07-09T14:12:03.221Z",
  • "updatedAt": "2026-07-09T14:12:03.221Z"
}

Delete a design document

Deletes a design document — allowed only while it is DRAFT. A document under review is mid-decision, and a RELEASED document is a controlled record that may be referenced by downstream production, quality, or procurement records; deleting in any non-draft state returns 422. Requires permission: DESIGN_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Design document id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Release a design document

Approves and releases a document under review, transitioning it IN_REVIEWRELEASED. Segregation of duties is enforced two ways: DESIGN_APPROVE is required (a DESIGN_WRITE author gets 403) and a user may not release a document they authored (self-release → 422). Only a document currently IN_REVIEW can be released — any other state returns 422. Once released the document is immutable and its BOM locks. Requires permission: DESIGN_APPROVE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Design document id.

Responses

Response samples

Content type
application/json
{
  • "id": 501,
  • "productId": 42,
  • "productSku": "HX-1200",
  • "revision": "1.0",
  • "title": "Shell & Tube HX GA Drawing",
  • "status": "RELEASED",
  • "createdAt": "2026-07-09T14:12:03.221Z",
  • "updatedAt": "2026-07-09T15:02:41.108Z"
}

Submit a design document for review

Submits a draft for review, transitioning it DRAFTIN_REVIEW and stamping the submitter. Only a DRAFT document can be submitted — any other state returns 422. Requires permission: DESIGN_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Design document id.

Responses

Response samples

Content type
application/json
{
  • "id": 501,
  • "productId": 42,
  • "productSku": "HX-1200",
  • "materialId": 88,
  • "materialSku": "SS316-TUBE-19",
  • "revision": "1.0",
  • "title": "Shell & Tube HX GA Drawing",
  • "status": "DRAFT",
  • "createdBy": 51001,
  • "createdByName": "dana.designer",
  • "submittedBy": 51001,
  • "submittedByName": "dana.designer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 51007,
  • "approvedByName": "raj.designmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "changesRequestedBy": 51007,
  • "changesRequestedByName": "raj.designmgr",
  • "changesRequestedAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2026-07-09T14:12:03.221Z",
  • "updatedAt": "2026-07-09T14:12:03.221Z"
}

Request changes on a design document

A reviewer sends a document under review back for rework, transitioning it IN_REVIEWCHANGES_REQUESTED. The decision must carry a justification (body, non-blank), recorded as a review remark in the same transaction. Only an IN_REVIEW document is eligible — any other state returns 422. Requires permission: DESIGN_APPROVE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Design document id.

Request Body schema: application/json
required
body
required
string <= 4000 characters

The remark text.

Responses

Request samples

Content type
application/json
{
  • "body": "Wall thickness on nozzle N2 is below the design pressure requirement; revise and resubmit."
}

Response samples

Content type
application/json
{
  • "id": 501,
  • "productId": 42,
  • "productSku": "HX-1200",
  • "materialId": 88,
  • "materialSku": "SS316-TUBE-19",
  • "revision": "1.0",
  • "title": "Shell & Tube HX GA Drawing",
  • "status": "DRAFT",
  • "createdBy": 51001,
  • "createdByName": "dana.designer",
  • "submittedBy": 51001,
  • "submittedByName": "dana.designer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 51007,
  • "approvedByName": "raj.designmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "changesRequestedBy": 51007,
  • "changesRequestedByName": "raj.designmgr",
  • "changesRequestedAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2026-07-09T14:12:03.221Z",
  • "updatedAt": "2026-07-09T14:12:03.221Z"
}

Reopen a design document for revision

Reopens a document that had changes requested, transitioning it CHANGES_REQUESTEDDRAFT so the author can edit and resubmit. Only a CHANGES_REQUESTED document is eligible — any other state returns 422. Requires permission: DESIGN_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Design document id.

Responses

Response samples

Content type
application/json
{
  • "id": 501,
  • "productId": 42,
  • "productSku": "HX-1200",
  • "materialId": 88,
  • "materialSku": "SS316-TUBE-19",
  • "revision": "1.0",
  • "title": "Shell & Tube HX GA Drawing",
  • "status": "DRAFT",
  • "createdBy": 51001,
  • "createdByName": "dana.designer",
  • "submittedBy": 51001,
  • "submittedByName": "dana.designer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 51007,
  • "approvedByName": "raj.designmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "changesRequestedBy": 51007,
  • "changesRequestedByName": "raj.designmgr",
  • "changesRequestedAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2026-07-09T14:12:03.221Z",
  • "updatedAt": "2026-07-09T14:12:03.221Z"
}

List review remarks

Returns a paginated page of review remarks on a design document, each with its resolved author username (default sort newest first). Requires permission: DESIGN_READ.

Authorizations:
bearerAuth
path Parameters
documentId
required
integer <int64>

Design document id.

query Parameters
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Add a review remark

Posts a free-text review remark against a design document (a reviewer decision). The body is required and non-blank. Requires permission: DESIGN_APPROVE.

Authorizations:
bearerAuth
path Parameters
documentId
required
integer <int64>

Design document id.

Request Body schema: application/json
required
body
required
string <= 4000 characters

The remark text.

Responses

Request samples

Content type
application/json
{
  • "body": "Approved subject to the corrosion allowance being called out on sheet 2."
}

Response samples

Content type
application/json
{
  • "id": 8801,
  • "designDocumentId": 501,
  • "body": "Approved subject to the corrosion allowance being called out on sheet 2.",
  • "author": 51007,
  • "authorName": "raj.designmgr",
  • "createdAt": "2019-08-24T14:15:22Z"
}

Attachments

Cross-cutting file metadata and binary upload/download; bytes live in object storage.

List attachments for an owner

Returns a paginated page of attachment metadata for one owning entity, identified by ownerType + ownerId. Bytes are not returned here — only metadata; use the download endpoint for the file itself. Sortable fields: fileName, sizeBytes, createdAt (default sort createdAt,desc); an unlisted sort field returns 400. Authorization is derived from the owning entity: requires that owner's view permission — DESIGN_READ for a DESIGN_DOCUMENT owner, MASTERDATA_READ for a PRODUCT owner.

Authorizations:
bearerAuth
query Parameters
ownerType
required
string
Example: ownerType=DESIGN_DOCUMENT

Owning entity type, e.g. DESIGN_DOCUMENT or PRODUCT.

ownerId
required
integer <int64>
Example: ownerId=501

Id of the owning entity.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Upload an attachment

Uploads a file and attaches it to the owning entity identified by ownerType + ownerId. The bytes are streamed to object storage; only metadata (name, content type, size, SHA-256 checksum, storage key, uploader) is persisted in the database. The owning entity must exist (else 404) and the uploaded file must be non-empty (an empty file, or an unsupported ownerType, returns 422). Authorization is derived from the owning entity: requires that owner's manage permission — DESIGN_WRITE for a DESIGN_DOCUMENT owner, MASTERDATA_WRITE for a PRODUCT owner.

Authorizations:
bearerAuth
Request Body schema: multipart/form-data
required
file
required
string <binary>

The file bytes to store.

ownerType
required
string

Owning entity type, e.g. DESIGN_DOCUMENT or PRODUCT.

ownerId
required
integer <int64>

Id of the owning entity.

Responses

Response samples

Content type
application/json
{
  • "id": 9001,
  • "ownerType": "DESIGN_DOCUMENT",
  • "ownerId": 501,
  • "fileName": "HX-GA-RevA.pdf",
  • "contentType": "application/pdf",
  • "sizeBytes": 284913,
  • "checksum": "9f2c1e7a4b3d4f8e9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f",
  • "uploadedBy": 387401,
  • "createdAt": "2026-07-09T14:12:03.221Z"
}

Download an attachment

Streams the raw file bytes for an attachment. The response is the binary content with a Content-Disposition: attachment header carrying the original file name; the content type is the stored MIME type (falling back to application/octet-stream). Authorization is derived from the owning entity: requires the same view permission as viewing that entity — DESIGN_READ for a DESIGN_DOCUMENT owner, MASTERDATA_READ for a PRODUCT owner — so a user who cannot see the parent cannot reach its files even by guessing an attachment id.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Attachment id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Delete an attachment

Deletes an attachment's metadata and its stored bytes. Authorization is derived from the owning entity: requires that owner's manage permission — DESIGN_WRITE for a DESIGN_DOCUMENT owner, MASTERDATA_WRITE for a PRODUCT owner.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Attachment id.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Procurement

Suppliers, the supplier→product catalog, purchase orders, and goods receipts.

List suppliers

Return a paged list of suppliers. Requires permission: PROCUREMENT_READ. Sortable fields: name, active, createdAt (default createdAt,desc); any other sort field returns 400.

Authorizations:
bearerAuth
query Parameters
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a supplier

Create a supplier. Requires permission: SUPPLIER_WRITE. The supplier name must be unique (duplicate → 409). pan, isIndividual and defaultTdsSectionId drive TDS on this vendor's payments (Phase 7D).

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string <= 200 characters

Supplier name; must be unique.

email
string <email> <= 255 characters

Contact email.

phone
string <= 40 characters

Contact phone.

stateCode
string = 2 characters

Two-digit GST state code of the supplier.

gstin
string <= 15 characters

Optional 15-character GST registration number, printed on purchase invoices. Validated loosely (15 alphanumerics) — editable master data.

pan
string <= 20 characters

Vendor PAN; drives TDS on payments (Phase 7D).

isIndividual
boolean

Whether the vendor is an individual (affects the applicable TDS rate).

defaultTdsSectionId
integer <int64>

Default TDS section applied to this vendor's payments.

active
boolean

Whether the supplier is active.

Responses

Request samples

Content type
application/json
{
  • "name": "Bharat Steel Tubes Pvt Ltd",
  • "email": "sales@bharatsteeltubes.example",
  • "phone": "+91 22 4000 1234",
  • "stateCode": "27",
  • "pan": "AABCB1234C",
  • "isIndividual": false,
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 42,
  • "name": "Bharat Steel Tubes Pvt Ltd",
  • "email": "sales@bharatsteeltubes.example",
  • "phone": "+91 22 4000 1234",
  • "stateCode": "27",
  • "gstin": "27ABCDE1234F1Z5",
  • "pan": "AABCB1234C",
  • "isIndividual": false,
  • "defaultTdsSectionId": 4,
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a supplier

Fetch one supplier by id. Requires permission: PROCUREMENT_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 42,
  • "name": "Bharat Steel Tubes Pvt Ltd",
  • "email": "sales@bharatsteeltubes.example",
  • "phone": "+91 22 4000 1234",
  • "stateCode": "27",
  • "gstin": "27ABCDE1234F1Z5",
  • "pan": "AABCB1234C",
  • "isIndividual": false,
  • "defaultTdsSectionId": 4,
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a supplier

Replace a supplier's fields. Requires permission: SUPPLIER_WRITE. The name must stay unique (duplicate → 409); a concurrent modification of the same row fails optimistic locking (409, reload and retry). Omitting active/isIndividual leaves the current value unchanged.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
name
required
string <= 200 characters

Supplier name; must be unique.

email
string <email> <= 255 characters

Contact email.

phone
string <= 40 characters

Contact phone.

stateCode
string = 2 characters

Two-digit GST state code of the supplier.

gstin
string <= 15 characters

Optional 15-character GST registration number, printed on purchase invoices. Validated loosely (15 alphanumerics) — editable master data.

pan
string <= 20 characters

Vendor PAN; drives TDS on payments (Phase 7D).

isIndividual
boolean

Whether the vendor is an individual (affects the applicable TDS rate).

defaultTdsSectionId
integer <int64>

Default TDS section applied to this vendor's payments.

active
boolean

Whether the supplier is active.

Responses

Request samples

Content type
application/json
{
  • "name": "Bharat Steel Tubes Pvt Ltd",
  • "email": "accounts@bharatsteeltubes.example",
  • "phone": "+91 22 4000 5678",
  • "stateCode": "27",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 42,
  • "name": "Bharat Steel Tubes Pvt Ltd",
  • "email": "sales@bharatsteeltubes.example",
  • "phone": "+91 22 4000 1234",
  • "stateCode": "27",
  • "gstin": "27ABCDE1234F1Z5",
  • "pan": "AABCB1234C",
  • "isIndividual": false,
  • "defaultTdsSectionId": 4,
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a supplier

Delete a supplier. Requires permission: SUPPLIER_WRITE. A supplier referenced by any purchase order is part of that order's record and cannot be deleted — deactivate it instead (422). Deleting a supplier with no orders cascade-removes its catalog rows.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List a supplier's catalog

Return a paged list of the supplier's product catalog entries (supplier SKU, unit price, lead time). Requires permission: PROCUREMENT_READ. Scoped to the supplier — an entry belonging to another supplier is a 404. Sortable fields: unitPrice, leadTimeDays, createdAt (default createdAt,desc); any other sort field returns 400.

Authorizations:
bearerAuth
path Parameters
supplierId
required
integer <int64>
query Parameters
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Add a catalog entry

Add a product to the supplier's catalog with its commercial terms. Requires permission: SUPPLIER_WRITE. A product may appear at most once per supplier (duplicate supplier+product → 409). The product must exist (else 404).

Authorizations:
bearerAuth
path Parameters
supplierId
required
integer <int64>
Request Body schema: application/json
required
materialId
required
integer <int64>

The material this catalog entry prices; fixed once created.

supplierSku
string <= 60 characters

The supplier's own SKU for the material.

unitPrice
required
number >= 0

Catalogued unit price for the material from this supplier.

leadTimeDays
integer >= 0

Quoted lead time in days.

Responses

Request samples

Content type
application/json
{
  • "materialId": 305,
  • "supplierSku": "BST-SS304-25NB",
  • "unitPrice": 4500,
  • "leadTimeDays": 14
}

Response samples

Content type
application/json
{
  • "id": 128,
  • "supplierId": 42,
  • "materialId": 305,
  • "materialSku": "SS304-25NB",
  • "materialName": "Stainless Steel Tube 304 25NB",
  • "uomCode": "M",
  • "supplierSku": "BST-SS304-25NB",
  • "unitPrice": 4500,
  • "leadTimeDays": 14,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a catalog entry

Revise a catalog entry's commercial terms (supplier SKU, unit price, lead time). Requires permission: SUPPLIER_WRITE. The entry's product is fixed once created — changing productId returns 422 (remove the entry and add a new one). A concurrent modification of the same row fails optimistic locking (409).

Authorizations:
bearerAuth
path Parameters
supplierId
required
integer <int64>
entryId
required
integer <int64>
Request Body schema: application/json
required
materialId
required
integer <int64>

The material this catalog entry prices; fixed once created.

supplierSku
string <= 60 characters

The supplier's own SKU for the material.

unitPrice
required
number >= 0

Catalogued unit price for the material from this supplier.

leadTimeDays
integer >= 0

Quoted lead time in days.

Responses

Request samples

Content type
application/json
{
  • "materialId": 305,
  • "supplierSku": "BST-SS304-25NB",
  • "unitPrice": 4650,
  • "leadTimeDays": 10
}

Response samples

Content type
application/json
{
  • "id": 128,
  • "supplierId": 42,
  • "materialId": 305,
  • "materialSku": "SS304-25NB",
  • "materialName": "Stainless Steel Tube 304 25NB",
  • "uomCode": "M",
  • "supplierSku": "BST-SS304-25NB",
  • "unitPrice": 4500,
  • "leadTimeDays": 14,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a catalog entry

Remove a product from the supplier's catalog. Requires permission: SUPPLIER_WRITE. Scoped to the supplier — an entry belonging to another supplier is a 404.

Authorizations:
bearerAuth
path Parameters
supplierId
required
integer <int64>
entryId
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List purchase orders

Return a paged list of purchase-order summaries (header plus derived total, without the line array). Requires permission: PROCUREMENT_READ. Optionally filter by supplierId and/or status. Sortable fields: orderDate, status, createdAt (default createdAt,desc); any other sort field returns 400.

Authorizations:
bearerAuth
query Parameters
supplierId
integer <int64>

Filter to purchase orders for this supplier.

status
string (PurchaseOrderStatus)
Enum: "DRAFT" "SUBMITTED" "APPROVED" "PARTIALLY_RECEIVED" "CLOSED" "CANCELLED"
Example: status=DRAFT

Filter to purchase orders in this lifecycle state.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Raise a purchase order

Raise a new purchase order in DRAFT. Requires permission: PROCUREMENT_WRITE. A PO must carry at least one line, and every line may only order a product that exists in the ordering supplier's catalog — a product not in the catalog is rejected (422). A line's unitPrice defaults to the catalogued price when omitted, and is then fixed on the line. The supplier must exist (else 404).

Authorizations:
bearerAuth
Request Body schema: application/json
required
supplierId
required
integer <int64>

The supplier to order from.

orderDate
required
string <date>

The order date.

required
Array of objects (PurchaseOrderLineRequest) non-empty

The order lines (at least one).

Responses

Request samples

Content type
application/json
{
  • "supplierId": 42,
  • "orderDate": "2026-06-15",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "status": "DRAFT",
  • "orderDate": "2026-06-15",
  • "total": 540000,
  • "createdBy": 38740,
  • "createdByName": "ravi.buyer",
  • "submittedBy": 38741,
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 38742,
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a purchase order

Fetch one purchase order in full — header, derived total, the lines, and the full who-did-what trail (raiser, submitter, and approver, each with a resolved username and the submit/approve timestamps). Requires permission: PROCUREMENT_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "status": "DRAFT",
  • "orderDate": "2026-06-15",
  • "total": 540000,
  • "createdBy": 38740,
  • "createdByName": "ravi.buyer",
  • "submittedBy": 38741,
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 38742,
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Edit a draft purchase order

Replace a purchase order's header and lines. Requires permission: PROCUREMENT_WRITE. Only a DRAFT order is editable — a SUBMITTED or APPROVED order is locked and returns 422 (cancel and re-raise instead). Every line's product must be in the supplier's catalog (else 422). A concurrent modification of the same row fails optimistic locking (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
supplierId
required
integer <int64>

The supplier to order from.

orderDate
required
string <date>

The order date.

required
Array of objects (PurchaseOrderLineRequest) non-empty

The order lines (at least one).

Responses

Request samples

Content type
application/json
{
  • "supplierId": 42,
  • "orderDate": "2026-06-15",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "status": "DRAFT",
  • "orderDate": "2026-06-15",
  • "total": 540000,
  • "createdBy": 38740,
  • "createdByName": "ravi.buyer",
  • "submittedBy": 38741,
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 38742,
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Submit a purchase order for approval

Transition a purchase order DRAFT → SUBMITTED, committing it for approval. Requires permission: PROCUREMENT_WRITE. Only a DRAFT order can be submitted; any other state returns 422. A concurrent modification of the same row fails optimistic locking (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "status": "DRAFT",
  • "orderDate": "2026-06-15",
  • "total": 540000,
  • "createdBy": 38740,
  • "createdByName": "ravi.buyer",
  • "submittedBy": 38741,
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 38742,
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Approve a purchase order

Transition a purchase order SUBMITTED → APPROVED. Requires permission: PO_APPROVE — a buyer holding only PROCUREMENT_WRITE is rejected with 403. Segregation of duties: a user may not approve a purchase order they raised themselves (self-approval → 422), forcing a different approver. Only a SUBMITTED order can be approved; any other state returns 422. Once APPROVED the order is immutable (edit → 422; cancel instead). A concurrent modification of the same row fails optimistic locking (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "status": "DRAFT",
  • "orderDate": "2026-06-15",
  • "total": 540000,
  • "createdBy": 38740,
  • "createdByName": "ravi.buyer",
  • "submittedBy": 38741,
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 38742,
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Cancel a purchase order

Transition a purchase order to CANCELLED. Requires permission: PROCUREMENT_WRITE. Cancellable only before any goods are received — a PARTIALLY_RECEIVED, CLOSED, or already CANCELLED order cannot be cancelled (422). Cancel is the way to retire an APPROVED order, since APPROVED orders are immutable. A concurrent modification of the same row fails optimistic locking (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "status": "DRAFT",
  • "orderDate": "2026-06-15",
  • "total": 540000,
  • "createdBy": 38740,
  • "createdByName": "ravi.buyer",
  • "submittedBy": 38741,
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 38742,
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List goods receipts

Return a paged list of goods-receipt summaries (header without the line array). Requires permission: PROCUREMENT_READ. Optionally filter by poId. Sortable fields: receivedDate, createdAt (default createdAt,desc); any other sort field returns 400.

Authorizations:
bearerAuth
query Parameters
poId
integer <int64>

Filter to receipts recorded against this purchase order.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Record a goods receipt

Record a delivery received against a purchase order into a destination warehouse. Requires permission: GOODS_RECEIPT_WRITE. Goods can only be received against an APPROVED or PARTIALLY_RECEIVED order (any other state → 422). The whole receive flow is one transaction: it writes the immutable, append-only receipt, atomically accumulates each PO line's received quantity (receiving more than the ordered quantity → 422, and rolls the whole receipt back), raises RECEIPT stock movements into the warehouse through the inventory service (stamped with this receipt's ref), and auto-transitions the PO to PARTIALLY_RECEIVED or CLOSED once every line is fully received. Goods receipts are immutable once recorded (no edit/delete; corrections via reversal are deferred). The PO and warehouse must exist (else 404); a receipt line whose poLineId does not belong to the PO → 422.

Authorizations:
bearerAuth
Request Body schema: application/json
required
poId
required
integer <int64>

The purchase order being received against (must be APPROVED or PARTIALLY_RECEIVED).

warehouseId
required
integer <int64>

Destination warehouse for the received stock.

receivedDate
required
string <date>

The date the goods were received.

required
Array of objects (GoodsReceiptLineRequest) non-empty

The received lines (at least one).

Responses

Request samples

Content type
application/json
{
  • "poId": 1234,
  • "warehouseId": 3,
  • "receivedDate": "2026-06-20",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 900,
  • "poId": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "orderDate": "2026-06-15",
  • "warehouseId": 3,
  • "warehouseName": "Main Raw Material Store",
  • "receivedDate": "2026-06-20",
  • "createdBy": 38743,
  • "filedByName": "ravi.buyer",
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "receivedByName": "kiran.clerk",
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z"
}

Get a goods receipt

Fetch one goods receipt in full — the GRN: its header, the purchase-order context it was received against (supplier, order date, priced lines), and the who-did-what trail (who filed, submitted, approved, and received). Requires permission: PROCUREMENT_READ. Unknown id → 404.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 900,
  • "poId": 1234,
  • "supplierId": 42,
  • "supplierName": "Bharat Steel Tubes Pvt Ltd",
  • "orderDate": "2026-06-15",
  • "warehouseId": 3,
  • "warehouseName": "Main Raw Material Store",
  • "receivedDate": "2026-06-20",
  • "createdBy": 38743,
  • "filedByName": "ravi.buyer",
  • "submittedByName": "ravi.buyer",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedByName": "meena.procmgr",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "receivedByName": "kiran.clerk",
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z"
}

Download the goods receipt as a PDF (GRN)

Generate the goods-receipt note (GRN) for this receipt on the fly and stream it as a downloadable PDF. Requires permission: PROCUREMENT_READ — the same permission as viewing the receipt, so no file is reachable without it. The response is application/pdf with a Content-Disposition: attachment; filename="GRN-{id}.pdf" header. Unknown id → 404. Nothing is stored: the PDF is rendered per request from the current receipt data.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Manufacturing

BOMs, work centers, production orders, quality inspections, and maintenance orders.

List BOMs

Returns a page of bills of materials (summary rows with a derived line count). Requires permission: DESIGN_READ. Filter by designDocumentId, active, and/or the target being produced (productId or materialId — a BOM produces a product XOR a material, resolved through its design document).

Authorizations:
bearerAuth
query Parameters
designDocumentId
integer <int64>
active
boolean
productId
integer <int64>

Only BOMs that produce this product.

materialId
integer <int64>

Only BOMs that produce this material (sub-assembly).

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a BOM

Creates a bill of materials under a design document. Requires permission: DESIGN_WRITE. The BOM is authored/edited only while its design document is DRAFT; it locks when the document is RELEASED. Must have at least one component line. Duplicate version for the same document → 409.

Authorizations:
bearerAuth
Request Body schema: application/json
required
designDocumentId
required
integer <int64>

Owning design document (must be DRAFT to edit; one BOM per document).

active
boolean

Optional; defaults active on create, unchanged on update.

required
Array of objects (BomLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "designDocumentId": 387300,
  • "active": true,
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "designDocumentId": 0,
  • "designDocumentRevision": "string",
  • "designStatus": "DRAFT",
  • "productId": 0,
  • "productSku": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "active": true,
  • "lines": [
    ],
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a BOM

Returns one BOM with its component lines and the owning document's release status. Requires permission: DESIGN_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "designDocumentId": 0,
  • "designDocumentRevision": "string",
  • "designStatus": "DRAFT",
  • "productId": 0,
  • "productSku": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "active": true,
  • "lines": [
    ],
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a BOM

Replaces a BOM's version/active flag and lines (as a set). Requires permission: DESIGN_WRITE. Permitted only while the owning design document is DRAFT — once the document leaves DRAFT (in review, changes-requested, or released) the BOM is locked (422). designDocumentId must match the BOM's existing document (a BOM cannot be re-parented).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
designDocumentId
required
integer <int64>

Owning design document (must be DRAFT to edit; one BOM per document).

active
boolean

Optional; defaults active on create, unchanged on update.

required
Array of objects (BomLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "designDocumentId": 0,
  • "active": true,
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "designDocumentId": 0,
  • "designDocumentRevision": "string",
  • "designStatus": "DRAFT",
  • "productId": 0,
  • "productSku": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "active": true,
  • "lines": [
    ],
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a BOM

Deletes a BOM. Requires permission: DESIGN_WRITE. A BOM whose design document has left DRAFT (in review, changes-requested, or released) is locked and cannot be deleted; nor can one referenced by a production order (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List work centers

Returns a page of work centers. Optionally filter by search (case-insensitive substring match on the work-center name) and/or status — independent AND filters. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
query Parameters
search
string
Example: search=cutting

Case-insensitive substring match on the work-center name.

status
string
Enum: "ACTIVE" "INACTIVE" "MAINTENANCE"
Example: status=ACTIVE

Restrict to a single operational state.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a work center

Creates a work center (shop-floor resource). Requires permission: MANUFACTURING_WRITE. name is unique (409).

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string <= 200 characters

Work center name (unique).

capacityPerHour
number

Optional throughput per hour (>= 0).

status
string
Enum: "ACTIVE" "INACTIVE" "MAINTENANCE"

Optional; defaults ACTIVE on create, unchanged on update.

Responses

Request samples

Content type
application/json
{
  • "name": "Tube Cutting & Bending",
  • "capacityPerHour": 40,
  • "status": "ACTIVE"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "capacityPerHour": 0,
  • "status": "ACTIVE",
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a work center

Returns one work center. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "capacityPerHour": 0,
  • "status": "ACTIVE",
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a work center

Replaces a work center's fields. Requires permission: MANUFACTURING_WRITE. name uniqueness enforced (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
name
required
string <= 200 characters

Work center name (unique).

capacityPerHour
number

Optional throughput per hour (>= 0).

status
string
Enum: "ACTIVE" "INACTIVE" "MAINTENANCE"

Optional; defaults ACTIVE on create, unchanged on update.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "capacityPerHour": 0,
  • "status": "ACTIVE"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "capacityPerHour": 0,
  • "status": "ACTIVE",
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a work center

Deletes a work center. Requires permission: MANUFACTURING_WRITE. A work center referenced by an operation or maintenance order cannot be deleted (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List production orders

Returns a page of production orders (summary rows). Optionally filter by productId, status, salesOrderId (the linked make-to-order sales order), and/or a planned-start date range (dateFrom/dateTo, inclusive) — independent AND filters. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
query Parameters
productId
integer <int64>

Restrict to a single product.

status
string
Enum: "DRAFT" "SUBMITTED" "APPROVED" "IN_PROGRESS" "PARTIALLY_COMPLETED" "COMPLETED" "CANCELLED"

Restrict to a single lifecycle state.

salesOrderId
integer <int64>

Restrict to orders linked to one sales order (make-to-order).

dateFrom
string <date>
Example: dateFrom=2026-07-01

Inclusive lower bound on the planned start date.

dateTo
string <date>
Example: dateTo=2026-07-31

Inclusive upper bound on the planned start date.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a production order

Creates a production order in DRAFT. Requires permission: MANUFACTURING_WRITE. The BOM must belong to a RELEASED design document (else 422); the product is derived from the BOM. components are the component lines to issue at start (seeded from the BOM on the client), each with its own source warehouse — a warehouse where the material currently has stock (else 422); there is no order-level source warehouse. salesOrderId is an optional make-to-order link.

Authorizations:
bearerAuth
Request Body schema: application/json
required
bomId
required
integer <int64>

BOM to produce (must be under a RELEASED design document).

salesOrderId
integer or null <int64>

Optional make-to-order link.

destinationWarehouseId
required
integer <int64>

Warehouse finished goods land in (QC-hold).

orderedQuantity
required
number

Quantity to produce (> 0).

plannedStart
string <date>
jobNumber
string <= 50 characters

Optional unique job/traceability number.

required
Array of objects (ProductionOrderComponentRequest)

The component lines to issue at start, each drawn from its own source warehouse.

Array of objects (ProductionOrderOperationRequest)

Optional routing (may be empty).

Responses

Request samples

Content type
application/json
{
  • "bomId": 387340,
  • "salesOrderId": null,
  • "destinationWarehouseId": 387062,
  • "orderedQuantity": 5,
  • "plannedStart": "2026-07-15",
  • "jobNumber": "JOB-2026-0042",
  • "components": [
    ],
  • "operations": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a production order

Returns one production order with its routing operations and produced/ordered progress. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a production order

Replaces a production order's fields and routing. Requires permission: MANUFACTURING_WRITE. Permitted only while the order is DRAFT (422 otherwise).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
bomId
required
integer <int64>

BOM to produce (must be under a RELEASED design document).

salesOrderId
integer or null <int64>

Optional make-to-order link.

destinationWarehouseId
required
integer <int64>

Warehouse finished goods land in (QC-hold).

orderedQuantity
required
number

Quantity to produce (> 0).

plannedStart
string <date>
jobNumber
string <= 50 characters

Optional unique job/traceability number.

required
Array of objects (ProductionOrderComponentRequest)

The component lines to issue at start, each drawn from its own source warehouse.

Array of objects (ProductionOrderOperationRequest)

Optional routing (may be empty).

Responses

Request samples

Content type
application/json
{
  • "bomId": 0,
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "orderedQuantity": 0,
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "components": [
    ],
  • "operations": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Submit a production order for approval

Submits a DRAFT production order for approval (→ SUBMITTED) and stamps the submitter. Only a DRAFT order can be submitted — any other state → 422. Requires permission: MANUFACTURING_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Approve a production order

Approves a SUBMITTED production order (→ APPROVED). Requires permission: PRODUCTION_ORDER_APPROVE (a planner with only MANUFACTURING_WRITE is 403). A user cannot approve an order they raised (self-approval → 422); approving a non-submitted order → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Cancel a production order

Cancels a production order. Requires permission: MANUFACTURING_WRITE. A completed order (or an illegal transition) → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Start a production order (backflush materials)

Starts an APPROVED production order (→ IN_PROGRESS) and backflushes all component materials at once as PRODUCTION_ISSUE movements. Requires permission: PRODUCTION_EXECUTE. A hard availability check reads on-hand only; insufficient stock for any component → 422 and nothing is issued (the whole start rolls back). Starting a non-approved order → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Report a production completion

Reports a produced quantity for an IN_PROGRESS order; finished goods land in QC-hold as a PRODUCTION_OUTPUT movement. Requires permission: PRODUCTION_EXECUTE. Cumulative produced quantity may not exceed the ordered quantity (over-completion → 422). An optional lotNumber (heat number) is captured for traceability.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
quantity
required
number

Quantity produced in this report (> 0; cumulative may not exceed ordered).

lotNumber
string <= 60 characters

Optional lot / heat number (traceability).

Responses

Request samples

Content type
application/json
{
  • "quantity": 2,
  • "lotNumber": "HEAT-7734"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "productId": 0,
  • "productSku": "string",
  • "productName": "string",
  • "materialId": 0,
  • "materialSku": "string",
  • "materialName": "string",
  • "bomId": 0,
  • "bomRevision": "string",
  • "salesOrderId": 0,
  • "destinationWarehouseId": 0,
  • "destinationWarehouseName": "string",
  • "orderedQuantity": 0,
  • "producedQuantity": 0,
  • "status": "DRAFT",
  • "plannedStart": "2019-08-24",
  • "jobNumber": "string",
  • "operations": [
    ],
  • "components": [
    ],
  • "createdBy": 0,
  • "createdByName": "string",
  • "submittedBy": 0,
  • "submittedByName": "string",
  • "submittedAt": "2019-08-24T14:15:22Z",
  • "approvedBy": 0,
  • "approvedByName": "string",
  • "approvedAt": "2019-08-24T14:15:22Z",
  • "startedBy": 0,
  • "startedByName": "string",
  • "startedAt": "2019-08-24T14:15:22Z",
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List quality inspections

Returns a page of quality inspections (append-only records). Optionally filter by productionOrderId, result, and/or an inspection-date range (dateFrom/dateTo, inclusive) — independent AND filters. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
query Parameters
productionOrderId
integer <int64>

Restrict to inspections of one production order.

result
string
Enum: "PASS" "FAIL"

Restrict to a single outcome.

dateFrom
string <date>
Example: dateFrom=2026-07-01

Inclusive lower bound on the inspection date.

dateTo
string <date>
Example: dateTo=2026-07-31

Inclusive upper bound on the inspection date.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Record a quality inspection

Inspects a produced quantity in QC-hold. Requires permission: QUALITY_WRITE. A PASS releases the quantity from QC-hold into on-hand (QC_RELEASE); a FAIL scraps it (QC_REJECT). The quantity must be available in QC-hold for the order (else 422). Inspections are append-only.

Authorizations:
bearerAuth
Request Body schema: application/json
required
productionOrderId
required
integer <int64>
quantity
required
number

Quantity inspected (> 0; must be available in QC-hold).

result
required
string
Enum: "PASS" "FAIL"

PASS releases QC-hold → on-hand; FAIL scraps it.

notes
string <= 500 characters

Optional free-text inspection detail.

Responses

Request samples

Content type
application/json
{
  • "productionOrderId": 387500,
  • "quantity": 2,
  • "result": "PASS",
  • "notes": "Visual and dimensional check per QP-07; all within tolerance."
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "productionOrderId": 0,
  • "quantity": 0,
  • "result": "PASS",
  • "notes": "string",
  • "inspectedAt": "2019-08-24T14:15:22Z",
  • "createdBy": 0
}

Get a quality inspection

Returns one quality inspection. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "productionOrderId": 0,
  • "quantity": 0,
  • "result": "PASS",
  • "notes": "string",
  • "inspectedAt": "2019-08-24T14:15:22Z",
  • "createdBy": 0
}

List maintenance orders

Returns a page of maintenance orders. Optionally filter by workCenterId, status, and/or type — independent AND filters. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
query Parameters
workCenterId
integer <int64>

Restrict to maintenance on one work center.

status
string
Enum: "SCHEDULED" "IN_PROGRESS" "COMPLETED" "CANCELLED"

Restrict to a single status.

type
string
Enum: "PREVENTIVE" "CORRECTIVE"

Restrict to planned upkeep (PREVENTIVE) or a repair (CORRECTIVE).

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a maintenance order

Schedules maintenance on a work center. Requires permission: MAINTENANCE_WRITE. status defaults to SCHEDULED.

Authorizations:
bearerAuth
Request Body schema: application/json
required
workCenterId
required
integer <int64>
type
required
string
Enum: "PREVENTIVE" "CORRECTIVE"
status
string
Enum: "SCHEDULED" "IN_PROGRESS" "COMPLETED" "CANCELLED"

Optional; defaults SCHEDULED on create, unchanged on update.

scheduledFor
string <date>

Responses

Request samples

Content type
application/json
{
  • "workCenterId": 387360,
  • "type": "PREVENTIVE",
  • "status": "SCHEDULED",
  • "scheduledFor": "2026-08-01"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "workCenterId": 0,
  • "workCenterName": "string",
  • "type": "PREVENTIVE",
  • "status": "SCHEDULED",
  • "scheduledFor": "2019-08-24",
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a maintenance order

Returns one maintenance order. Requires permission: MANUFACTURING_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "workCenterId": 0,
  • "workCenterName": "string",
  • "type": "PREVENTIVE",
  • "status": "SCHEDULED",
  • "scheduledFor": "2019-08-24",
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a maintenance order

Replaces a maintenance order's fields (including status). Requires permission: MAINTENANCE_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
workCenterId
required
integer <int64>
type
required
string
Enum: "PREVENTIVE" "CORRECTIVE"
status
string
Enum: "SCHEDULED" "IN_PROGRESS" "COMPLETED" "CANCELLED"

Optional; defaults SCHEDULED on create, unchanged on update.

scheduledFor
string <date>

Responses

Request samples

Content type
application/json
{
  • "workCenterId": 0,
  • "type": "PREVENTIVE",
  • "status": "SCHEDULED",
  • "scheduledFor": "2019-08-24"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "workCenterId": 0,
  • "workCenterName": "string",
  • "type": "PREVENTIVE",
  • "status": "SCHEDULED",
  • "scheduledFor": "2019-08-24",
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a maintenance order

Deletes a maintenance order. Requires permission: MAINTENANCE_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Sales

Customers, quotations, sales orders (confirm reserves stock), deliveries, and milestone billing.

List customers

Returns a page of customers. Optionally filter by search (case-insensitive substring match on name, email, or phone) and/or active — independent AND filters. Requires permission: SALES_READ.

Authorizations:
bearerAuth
query Parameters
search
string
Example: search=acme

Case-insensitive substring match on customer name, email, or phone.

active
boolean

Restrict to active (true) or inactive (false) customers.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a customer

Creates a customer. Requires permission: SALES_WRITE. stateCode is the 2-digit GST state code (place of supply), needed before an invoice can be posted.

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string <= 200 characters
email
string <email> <= 255 characters
phone
string <= 40 characters
stateCode
string = 2 characters

2-digit GST state code (place of supply).

gstin
string <= 15 characters

Optional 15-character GST registration number, printed on tax invoices. Validated loosely (15 alphanumerics) — editable master data.

active
boolean

Optional; defaults active on create, unchanged on update.

Responses

Request samples

Content type
application/json
{
  • "name": "Reliance Petrochemicals Ltd",
  • "email": "procurement@relpetro.example.in",
  • "phone": "+91 22 4477 1200",
  • "stateCode": "27",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "email": "user@example.com",
  • "phone": "string",
  • "stateCode": "string",
  • "gstin": "29ABCDE1234F1Z5",
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a customer

Returns one customer. Requires permission: SALES_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "email": "user@example.com",
  • "phone": "string",
  • "stateCode": "string",
  • "gstin": "29ABCDE1234F1Z5",
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a customer

Replaces a customer's fields. Requires permission: SALES_WRITE. Send active: false to retire a customer referenced by history.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
name
required
string <= 200 characters
email
string <email> <= 255 characters
phone
string <= 40 characters
stateCode
string = 2 characters

2-digit GST state code (place of supply).

gstin
string <= 15 characters

Optional 15-character GST registration number, printed on tax invoices. Validated loosely (15 alphanumerics) — editable master data.

active
boolean

Optional; defaults active on create, unchanged on update.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "email": "user@example.com",
  • "phone": "string",
  • "stateCode": "st",
  • "gstin": "29ABCDE1234F1Z5",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "email": "user@example.com",
  • "phone": "string",
  • "stateCode": "string",
  • "gstin": "29ABCDE1234F1Z5",
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a customer

Deletes a customer. Requires permission: SALES_WRITE. A customer referenced by a quotation or order cannot be deleted — deactivate instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List quotations

Returns a page of quotations (summary rows with derived total). Requires permission: SALES_READ. Filter by customerId and/or status.

Authorizations:
bearerAuth
query Parameters
customerId
integer <int64>
status
string
Enum: "DRAFT" "SENT" "ACCEPTED" "REJECTED" "EXPIRED"
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a quotation

Creates a quotation (DRAFT) with at least one line. Requires permission: SALES_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
customerId
required
integer <int64>
validUntil
string <date>
required
Array of objects (QuotationLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "customerId": 387600,
  • "validUntil": "2026-08-31",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "status": "DRAFT",
  • "validUntil": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a quotation

Returns one quotation with its lines and derived total. Requires permission: SALES_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "status": "DRAFT",
  • "validUntil": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a quotation

Replaces a quotation's fields and lines. Requires permission: SALES_WRITE. Permitted only while the quotation is DRAFT (422 otherwise).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
customerId
required
integer <int64>
validUntil
string <date>
required
Array of objects (QuotationLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "customerId": 0,
  • "validUntil": "2019-08-24",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "status": "DRAFT",
  • "validUntil": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Send a quotation

Transitions a DRAFT quotation to SENT. Requires permission: SALES_WRITE. Illegal transition → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "status": "DRAFT",
  • "validUntil": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Accept a quotation

Marks a SENT quotation ACCEPTED (a sales order may then be seeded from it). Requires permission: SALES_WRITE. Illegal transition → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "status": "DRAFT",
  • "validUntil": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Reject a quotation

Marks a quotation REJECTED. Requires permission: SALES_WRITE. Illegal transition → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "status": "DRAFT",
  • "validUntil": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Expire a quotation

Marks a quotation EXPIRED. Requires permission: SALES_WRITE. Illegal transition → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "status": "DRAFT",
  • "validUntil": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List sales orders

Returns a page of sales orders (summary rows). Optionally filter by customerId, status, quotationId, and/or an inclusive order-date range (dateFrom/dateTo) — independent AND filters. Requires permission: SALES_READ.

Authorizations:
bearerAuth
query Parameters
customerId
integer <int64>

Restrict to orders for one customer.

status
string
Enum: "DRAFT" "CONFIRMED" "PARTIALLY_SHIPPED" "SHIPPED" "CLOSED" "CANCELLED"

Restrict to a single lifecycle state.

quotationId
integer <int64>

Restrict to the order created from one quotation.

dateFrom
string <date>
Example: dateFrom=2026-07-01

Inclusive lower bound on the order date.

dateTo
string <date>
Example: dateTo=2026-07-31

Inclusive upper bound on the order date.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a sales order

Creates a sales order (DRAFT) with at least one line. Requires permission: SALES_WRITE. warehouseId is optional on a draft but required before confirm.

Authorizations:
bearerAuth
Request Body schema: application/json
required
customerId
required
integer <int64>
warehouseId
integer <int64>

Fulfilment warehouse; optional on a draft, required before confirm.

orderDate
required
string <date>
required
Array of objects (SalesOrderLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "customerId": 387600,
  • "warehouseId": 387062,
  • "orderDate": "2026-06-20",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "warehouseId": 0,
  • "warehouseName": "string",
  • "quotationId": 0,
  • "status": "DRAFT",
  • "orderDate": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a sales order

Returns one sales order with its lines (ordered/reserved/shipped quantities) and derived total. Requires permission: SALES_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "warehouseId": 0,
  • "warehouseName": "string",
  • "quotationId": 0,
  • "status": "DRAFT",
  • "orderDate": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a sales order

Replaces a sales order's fields and lines. Requires permission: SALES_WRITE. Permitted only while the order is DRAFT (422 otherwise).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
customerId
required
integer <int64>
warehouseId
integer <int64>

Fulfilment warehouse; optional on a draft, required before confirm.

orderDate
required
string <date>
required
Array of objects (SalesOrderLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "customerId": 0,
  • "warehouseId": 0,
  • "orderDate": "2019-08-24",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "warehouseId": 0,
  • "warehouseName": "string",
  • "quotationId": 0,
  • "status": "DRAFT",
  • "orderDate": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Confirm a sales order (reserve stock)

Confirms a DRAFT sales order (→ CONFIRMED) and reserves stock, moving on-hand → reserved for each line from the order's fulfilment warehouse. Requires permission: SALES_APPROVE (a rep with only SALES_WRITE is 403). A user cannot confirm an order they created (self-approval → 422). An atomic availability guard reads on-hand only; a shortfall on any line → 422 and the order stays DRAFT (nothing reserved). Confirming without a fulfilment warehouse → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "warehouseId": 0,
  • "warehouseName": "string",
  • "quotationId": 0,
  • "status": "DRAFT",
  • "orderDate": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Cancel a sales order

Cancels a sales order; if it was confirmed (not yet shipped), releases the reservation (reserved → on-hand). Requires permission: SALES_WRITE. Cancelling a shipped order → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "customerId": 0,
  • "customerName": "string",
  • "warehouseId": 0,
  • "warehouseName": "string",
  • "quotationId": 0,
  • "status": "DRAFT",
  • "orderDate": "2019-08-24",
  • "total": 0,
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List deliveries

Returns a page of deliveries (append-only). Optionally filter by salesOrderId and/or an inclusive dispatch-date range (dateFrom/dateTo) — independent AND filters. Requires permission: SALES_READ.

Authorizations:
bearerAuth
query Parameters
salesOrderId
integer <int64>

Restrict to deliveries against one sales order.

dateFrom
string <date>
Example: dateFrom=2026-07-01

Inclusive lower bound on the dispatch date.

dateTo
string <date>
Example: dateTo=2026-07-31

Inclusive upper bound on the dispatch date.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Dispatch a delivery

Dispatches a delivery against a CONFIRMED (or PARTIALLY_SHIPPED) sales order. Requires permission: SALES_WRITE. Converts reserved → shipped and writes negative SALES_SHIPMENT stock movements. A line cannot ship more than its outstanding reserved quantity (over-ship → 422). Deliveries are append-only.

Authorizations:
bearerAuth
Request Body schema: application/json
required
salesOrderId
required
integer <int64>
dispatchedDate
required
string <date>
required
Array of objects (DeliveryLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "salesOrderId": 387700,
  • "dispatchedDate": "2026-07-05",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "salesOrderId": 0,
  • "dispatchedDate": "2019-08-24",
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z"
}

Get a delivery

Returns one delivery with its shipped lines. Requires permission: SALES_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "salesOrderId": 0,
  • "dispatchedDate": "2019-08-24",
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z"
}

List a sales order's milestones

Returns the milestone schedule for a sales order. Requires permission: SALES_READ. Sortable field: sequence (default).

Authorizations:
bearerAuth
path Parameters
soId
required
integer <int64>
query Parameters
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Replace a sales order's milestone schedule

Replaces the whole milestone schedule for a sales order. Requires permission: SALES_WRITE. The milestone percentages must sum to exactly 100 (99/101 → 422). The schedule locks once any milestone is INVOICED or referenced by an advance/invoice (422).

Authorizations:
bearerAuth
path Parameters
soId
required
integer <int64>
Request Body schema: application/json
required
required
Array of objects (MilestoneItemRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "milestones": [
    ]
}

Response samples

Content type
application/json
[
  • {
    }
]

Raise a milestone's invoice

Creates a DRAFT AR invoice for a milestone (one line = the milestone percentage of the sales order value). Requires permission: FINANCE_WRITE. taxCodeId is required (the sales order carries none). The invoice then flows through the normal invoice lifecycle (post/cancel). The milestone must still be PENDING.

Authorizations:
bearerAuth
path Parameters
soId
required
integer <int64>
milestoneId
required
integer <int64>
Request Body schema: application/json
required
taxCodeId
required
integer <int64>

GST tax code to apply (required — the SO carries none).

productId
integer <int64>

Optional; defaults to the first order line's product.

invoiceDate
string <date>

Optional; defaults to today.

Responses

Request samples

Content type
application/json
{
  • "taxCodeId": 387260,
  • "productId": 387001,
  • "invoiceDate": "2026-07-06"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "AR",
  • "invoiceNumber": "string",
  • "invoiceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "placeOfSupply": "string",
  • "supplyType": "INTRA",
  • "status": "DRAFT",
  • "subtotal": 0,
  • "totalCgst": 0,
  • "totalSgst": 0,
  • "totalIgst": 0,
  • "roundingAdjustment": 0,
  • "totalAmount": 0,
  • "journalEntryId": 0,
  • "settled": true,
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Finance

Chart of accounts, journal entries, tax master data, invoices (AR/AP), payments, and advances.

List accounts

Returns a page of chart-of-accounts entries. Requires permission: FINANCE_READ. Filter by type.

Authorizations:
bearerAuth
query Parameters
type
string
Enum: "ASSET" "LIABILITY" "EQUITY" "INCOME" "EXPENSE"
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create an account

Creates a chart-of-accounts entry. Requires permission: FINANCE_WRITE. code is unique (409).

Authorizations:
bearerAuth
Request Body schema: application/json
required
code
required
string <= 20 characters

Account code (unique).

name
required
string <= 120 characters
type
required
string
Enum: "ASSET" "LIABILITY" "EQUITY" "INCOME" "EXPENSE"
active
boolean

Optional; defaults active on create, unchanged on update.

Responses

Request samples

Content type
application/json
{
  • "code": "1100",
  • "name": "Accounts Receivable",
  • "type": "ASSET",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "code": "string",
  • "name": "string",
  • "type": "ASSET",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get an account

Returns one account. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "code": "string",
  • "name": "string",
  • "type": "ASSET",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update an account

Replaces an account's fields. Requires permission: FINANCE_WRITE. code uniqueness enforced (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
code
required
string <= 20 characters

Account code (unique).

name
required
string <= 120 characters
type
required
string
Enum: "ASSET" "LIABILITY" "EQUITY" "INCOME" "EXPENSE"
active
boolean

Optional; defaults active on create, unchanged on update.

Responses

Request samples

Content type
application/json
{
  • "code": "string",
  • "name": "string",
  • "type": "ASSET",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "code": "string",
  • "name": "string",
  • "type": "ASSET",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete an account

Deletes an account. Requires permission: FINANCE_WRITE. An account referenced by a journal line cannot be deleted — deactivate instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List tax codes

Returns a page of GST tax codes. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
query Parameters
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a tax code

Creates a GST tax code. Requires permission: FINANCE_WRITE. code is unique (409). Rates are attached separately via tax rates.

Authorizations:
bearerAuth
Request Body schema: application/json
required
code
required
string <= 20 characters

Tax code (unique), e.g. GST18.

name
required
string <= 120 characters
active
boolean

Responses

Request samples

Content type
application/json
{
  • "code": "GST18",
  • "name": "GST 18%",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "code": "string",
  • "name": "string",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a tax code

Returns one tax code. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "code": "string",
  • "name": "string",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a tax code

Replaces a tax code's fields. Requires permission: FINANCE_WRITE. code uniqueness enforced (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
code
required
string <= 20 characters

Tax code (unique), e.g. GST18.

name
required
string <= 120 characters
active
boolean

Responses

Request samples

Content type
application/json
{
  • "code": "string",
  • "name": "string",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "code": "string",
  • "name": "string",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a tax code

Deletes a tax code. Requires permission: FINANCE_WRITE. A tax code that has rates cannot be deleted — deactivate instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List tax rates

Returns a page of effective-dated tax rates. Requires permission: FINANCE_READ. Filter by taxCodeId.

Authorizations:
bearerAuth
query Parameters
taxCodeId
integer <int64>
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a tax rate

Adds an effective-dated rate for a tax code. Requires permission: FINANCE_WRITE. Date windows for one code may not overlap (409/422). A rate change is a new row, not an edit.

Authorizations:
bearerAuth
Request Body schema: application/json
required
taxCodeId
required
integer <int64>
totalRatePct
required
number

Full GST rate percent (>= 0). The CGST/SGST/IGST split is derived at posting time.

validFrom
required
string <date>

Inclusive start of the window.

validTo
string <date>

Inclusive end; null = open-ended. Windows for one code may not overlap.

Responses

Request samples

Content type
application/json
{
  • "taxCodeId": 387260,
  • "totalRatePct": 18,
  • "validFrom": "2025-09-22"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "taxCodeId": 0,
  • "taxCodeCode": "string",
  • "totalRatePct": 0,
  • "validFrom": "2019-08-24",
  • "validTo": "2019-08-24",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Resolve the effective rate for a date

Returns the single tax rate in effect for a tax code on a given date. Requires permission: FINANCE_READ. No rate covering the date → 422.

Authorizations:
bearerAuth
query Parameters
taxCodeId
required
integer <int64>
onDate
required
string <date>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "taxCodeId": 0,
  • "taxCodeCode": "string",
  • "totalRatePct": 0,
  • "validFrom": "2019-08-24",
  • "validTo": "2019-08-24",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a tax rate

Deletes an effective-dated tax rate. Requires permission: FINANCE_WRITE.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List TDS sections

Returns a page of TDS section rules. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
query Parameters
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a TDS section

Creates a TDS section rule. Requires permission: FINANCE_WRITE. internalCode is unique (409). thresholdMode FULL taxes the whole base once a threshold is crossed; EXCESS (194Q) taxes only the slice above the annual threshold.

Authorizations:
bearerAuth
Request Body schema: application/json
required
internalCode
required
string <= 30 characters

Stable key (unique), e.g. TDS_CONTRACTOR.

description
required
string <= 200 characters
ratePct
required
number

Default (non-individual) rate percent (>= 0).

ratePctIndividual
number

Optional lower individual/HUF rate.

thresholdSingle
number

Optional per-transaction trigger.

thresholdAnnual
required
number

Annual aggregate threshold (>= 0).

section393Code
string <= 20 characters

Filing code (data).

penalRateNoPan
required
number

Rate applied when the payee has no PAN (>= 0).

thresholdMode
string
Enum: "FULL" "EXCESS"

Optional; FULL taxes the whole base past a threshold, EXCESS (194Q) only the slice above the annual threshold.

active
boolean

Responses

Request samples

Content type
application/json
{
  • "internalCode": "TDS_CONTRACTOR",
  • "description": "Contractor / works / transport / labour (old 194C)",
  • "ratePct": 2,
  • "ratePctIndividual": 1,
  • "thresholdSingle": 30000,
  • "thresholdAnnual": 100000,
  • "section393Code": "1001",
  • "penalRateNoPan": 20,
  • "thresholdMode": "FULL",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "internalCode": "string",
  • "description": "string",
  • "ratePct": 0,
  • "ratePctIndividual": 0,
  • "thresholdSingle": 0,
  • "thresholdAnnual": 0,
  • "section393Code": "string",
  • "penalRateNoPan": 0,
  • "thresholdMode": "FULL",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a TDS section

Returns one TDS section rule. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "internalCode": "string",
  • "description": "string",
  • "ratePct": 0,
  • "ratePctIndividual": 0,
  • "thresholdSingle": 0,
  • "thresholdAnnual": 0,
  • "section393Code": "string",
  • "penalRateNoPan": 0,
  • "thresholdMode": "FULL",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a TDS section

Replaces a TDS section rule. Requires permission: FINANCE_WRITE. internalCode uniqueness enforced (409).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
internalCode
required
string <= 30 characters

Stable key (unique), e.g. TDS_CONTRACTOR.

description
required
string <= 200 characters
ratePct
required
number

Default (non-individual) rate percent (>= 0).

ratePctIndividual
number

Optional lower individual/HUF rate.

thresholdSingle
number

Optional per-transaction trigger.

thresholdAnnual
required
number

Annual aggregate threshold (>= 0).

section393Code
string <= 20 characters

Filing code (data).

penalRateNoPan
required
number

Rate applied when the payee has no PAN (>= 0).

thresholdMode
string
Enum: "FULL" "EXCESS"

Optional; FULL taxes the whole base past a threshold, EXCESS (194Q) only the slice above the annual threshold.

active
boolean

Responses

Request samples

Content type
application/json
{
  • "internalCode": "string",
  • "description": "string",
  • "ratePct": 0,
  • "ratePctIndividual": 0,
  • "thresholdSingle": 0,
  • "thresholdAnnual": 0,
  • "section393Code": "string",
  • "penalRateNoPan": 0,
  • "thresholdMode": "FULL",
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "internalCode": "string",
  • "description": "string",
  • "ratePct": 0,
  • "ratePctIndividual": 0,
  • "thresholdSingle": 0,
  • "thresholdAnnual": 0,
  • "section393Code": "string",
  • "penalRateNoPan": 0,
  • "thresholdMode": "FULL",
  • "active": true,
  • "createdBy": 0,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a TDS section

Deletes a TDS section rule. Requires permission: FINANCE_WRITE. A section referenced by a payment or ledger cannot be deleted (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Get company configuration

Returns the singleton company configuration (home GST state and tax-applicability flags). Requires permission: FINANCE_READ.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "stateCode": "string",
  • "gstin": "string",
  • "tds194qApplicable": true,
  • "gstRegistered": true,
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update company configuration

Updates the singleton company configuration. Requires permission: FINANCE_WRITE.

Authorizations:
bearerAuth
Request Body schema: application/json
required
stateCode
required
string = 2 characters

Home-state 2-digit GST code.

gstin
string <= 15 characters

Optional 15-character GST registration number, printed on tax invoices. Validated loosely (15 alphanumerics) — editable master data.

tds194qApplicable
required
boolean
gstRegistered
required
boolean

Responses

Request samples

Content type
application/json
{
  • "stateCode": "27",
  • "tds194qApplicable": false,
  • "gstRegistered": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "stateCode": "string",
  • "gstin": "string",
  • "tds194qApplicable": true,
  • "gstRegistered": true,
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List GST state codes

Returns the full reference list of the 37 India GST states/UTs (2-digit code, name, optional alpha), ordered by code. Readable by any authenticated user — the same list feeds the place-of-supply / state pickers on customers, suppliers, invoices, advances and company config. Read-only; the list is seeded.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

List journal entries

Returns a page of journal entries (summary rows). Requires permission: FINANCE_READ. Filter by status, fromDate, toDate.

Authorizations:
bearerAuth
query Parameters
status
string
Enum: "DRAFT" "POSTED"
fromDate
string <date>
toDate
string <date>
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a journal entry

Creates a DRAFT journal entry. Requires permission: FINANCE_WRITE. Each line posts to exactly one side (debit XOR credit > 0). A draft may be unbalanced while being built; balance is enforced on post.

Authorizations:
bearerAuth
Request Body schema: application/json
required
entryDate
required
string <date>
description
string
required
Array of objects (JournalEntryLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "entryDate": "2026-07-09",
  • "description": "Manual reclass",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "entryDate": "2019-08-24",
  • "description": "string",
  • "status": "DRAFT",
  • "refType": "string",
  • "refId": 0,
  • "reversalOfId": 0,
  • "totalDebit": 0,
  • "totalCredit": 0,
  • "postedAt": "2019-08-24T14:15:22Z",
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a journal entry

Returns one journal entry with its lines and debit/credit totals. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "entryDate": "2019-08-24",
  • "description": "string",
  • "status": "DRAFT",
  • "refType": "string",
  • "refId": 0,
  • "reversalOfId": 0,
  • "totalDebit": 0,
  • "totalCredit": 0,
  • "postedAt": "2019-08-24T14:15:22Z",
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a journal entry

Replaces a DRAFT entry's fields and lines. Requires permission: FINANCE_WRITE. A POSTED entry is immutable (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
entryDate
required
string <date>
description
string
required
Array of objects (JournalEntryLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "entryDate": "2019-08-24",
  • "description": "string",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "entryDate": "2019-08-24",
  • "description": "string",
  • "status": "DRAFT",
  • "refType": "string",
  • "refId": 0,
  • "reversalOfId": 0,
  • "totalDebit": 0,
  • "totalCredit": 0,
  • "postedAt": "2019-08-24T14:15:22Z",
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a journal entry

Deletes a DRAFT journal entry. Requires permission: FINANCE_WRITE. A POSTED entry cannot be deleted — reverse it instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Post a journal entry

Posts a DRAFT entry (→ POSTED, stamps postedAt). Requires permission: JOURNAL_POST. Debits must equal credits and there must be at least one line (else 422). A posted entry is immutable.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "entryDate": "2019-08-24",
  • "description": "string",
  • "status": "DRAFT",
  • "refType": "string",
  • "refId": 0,
  • "reversalOfId": 0,
  • "totalDebit": 0,
  • "totalCredit": 0,
  • "postedAt": "2019-08-24T14:15:22Z",
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Reverse a posted journal entry

Creates a new POSTED entry with debits and credits swapped, linked via reversalOfId. Requires permission: JOURNAL_POST. Only a POSTED entry can be reversed (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "entryDate": "2019-08-24",
  • "description": "string",
  • "status": "DRAFT",
  • "refType": "string",
  • "refId": 0,
  • "reversalOfId": 0,
  • "totalDebit": 0,
  • "totalCredit": 0,
  • "postedAt": "2019-08-24T14:15:22Z",
  • "createdBy": 0,
  • "lines": [
    ],
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List invoices

Returns a page of invoices (summary rows). Optionally filter by type (AR/AP), status, counterpartyId, and/or an inclusive invoice-date range (dateFrom/dateTo) — independent AND filters. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
query Parameters
type
string
Enum: "AR" "AP"

Restrict to receivable (AR) or payable (AP) invoices.

status
string
Enum: "DRAFT" "POSTED" "CANCELLED"

Restrict to a single lifecycle state.

counterpartyId
integer <int64>

Restrict to one counterparty — the customer on an AR invoice or the supplier on an AP one.

dateFrom
string <date>
Example: dateFrom=2026-07-01

Inclusive lower bound on the invoice date.

dateTo
string <date>
Example: dateTo=2026-07-31

Inclusive upper bound on the invoice date.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create an invoice

Creates a DRAFT invoice. Requires permission: FINANCE_WRITE. An AR invoice must name a customer, an AP invoice a supplier (matching the type; else 422). Tax amounts are computed and frozen at post, not here.

Authorizations:
bearerAuth
Request Body schema: application/json
required
type
required
string
Enum: "AR" "AP"
invoiceDate
required
string <date>
customerId
integer <int64>

Required for AR (and must be null for AP).

supplierId
integer <int64>

Required for AP (and must be null for AR).

placeOfSupply
string = 2 characters

2-digit GST state code; defaults from the counterparty at post.

note
string <= 500 characters
required
Array of objects (InvoiceLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "type": "AR",
  • "invoiceDate": "2026-07-06",
  • "customerId": 387600,
  • "placeOfSupply": "27",
  • "note": "Milestone 1 - advance",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "AR",
  • "invoiceNumber": "string",
  • "invoiceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "placeOfSupply": "string",
  • "supplyType": "INTRA",
  • "status": "DRAFT",
  • "subtotal": 0,
  • "totalCgst": 0,
  • "totalSgst": 0,
  • "totalIgst": 0,
  • "roundingAdjustment": 0,
  • "totalAmount": 0,
  • "journalEntryId": 0,
  • "settled": true,
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Invoice totals summary (AR/AP overview)

Aggregate money and counts across all invoices for the finance overview, split into receivables (receivable, AR — what customers owe us) and payables (payable, AP — what we owe suppliers). Each side reports four buckets: billed (posted total), of which paid (posted and settled) and outstanding (posted, not yet settled) — so billed = paid + outstanding — plus draft (not yet posted). CANCELLED invoices are void and excluded from every bucket. Amounts are rupee-scaled (2 dp) and computed over the whole invoice set, so the figures are exact regardless of row count. Takes no parameters.

Requires permission: FINANCE_READ.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "receivable": {
    },
  • "payable": {
    }
}

Get an invoice

Returns one invoice with its lines and frozen tax snapshot. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "AR",
  • "invoiceNumber": "string",
  • "invoiceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "placeOfSupply": "string",
  • "supplyType": "INTRA",
  • "status": "DRAFT",
  • "subtotal": 0,
  • "totalCgst": 0,
  • "totalSgst": 0,
  • "totalIgst": 0,
  • "roundingAdjustment": 0,
  • "totalAmount": 0,
  • "journalEntryId": 0,
  • "settled": true,
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update an invoice

Replaces a DRAFT invoice's fields and lines. Requires permission: FINANCE_WRITE. A POSTED or CANCELLED invoice is immutable (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
type
required
string
Enum: "AR" "AP"
invoiceDate
required
string <date>
customerId
integer <int64>

Required for AR (and must be null for AP).

supplierId
integer <int64>

Required for AP (and must be null for AR).

placeOfSupply
string = 2 characters

2-digit GST state code; defaults from the counterparty at post.

note
string <= 500 characters
required
Array of objects (InvoiceLineRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "type": "AR",
  • "invoiceDate": "2019-08-24",
  • "customerId": 0,
  • "supplierId": 0,
  • "placeOfSupply": "st",
  • "note": "string",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "AR",
  • "invoiceNumber": "string",
  • "invoiceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "placeOfSupply": "string",
  • "supplyType": "INTRA",
  • "status": "DRAFT",
  • "subtotal": 0,
  • "totalCgst": 0,
  • "totalSgst": 0,
  • "totalIgst": 0,
  • "roundingAdjustment": 0,
  • "totalAmount": 0,
  • "journalEntryId": 0,
  • "settled": true,
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete an invoice

Deletes a DRAFT invoice. Requires permission: FINANCE_WRITE. A POSTED invoice cannot be deleted — cancel it instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Download the invoice as a GST tax-invoice PDF

Generate the GST tax invoice for this invoice on the fly and stream it as a downloadable PDF. Requires permission: FINANCE_READ — the same permission as viewing the invoice, so no file is reachable without it. The response is application/pdf with a Content-Disposition: attachment; filename="AR-000089.pdf" header (the invoice number). Everything is read from the frozen posted snapshot (place of supply, supply type, the CGST/SGST or IGST split, totals) — nothing is recomputed. Only a posted or cancelled invoice has a frozen snapshot to print; a DRAFT is rejected (422 — post it first). Unknown id → 404. Nothing is stored: the PDF is rendered per request.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Post an invoice

Posts a DRAFT invoice (→ POSTED) and auto-posts its balanced journal entry. Requires permission: JOURNAL_POST. The GST split (CGST+SGST vs IGST) is derived from place of supply vs the company state and frozen onto the lines; rounding posts to the Rounding account. A missing counterparty state or no resolvable tax rate → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "AR",
  • "invoiceNumber": "string",
  • "invoiceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "placeOfSupply": "string",
  • "supplyType": "INTRA",
  • "status": "DRAFT",
  • "subtotal": 0,
  • "totalCgst": 0,
  • "totalSgst": 0,
  • "totalIgst": 0,
  • "roundingAdjustment": 0,
  • "totalAmount": 0,
  • "journalEntryId": 0,
  • "settled": true,
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Cancel an invoice

Cancels a POSTED invoice (→ CANCELLED) and reverses its journal entry. Requires permission: JOURNAL_POST. Cancelling a DRAFT → 422 (delete it instead).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "AR",
  • "invoiceNumber": "string",
  • "invoiceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "placeOfSupply": "string",
  • "supplyType": "INTRA",
  • "status": "DRAFT",
  • "subtotal": 0,
  • "totalCgst": 0,
  • "totalSgst": 0,
  • "totalIgst": 0,
  • "roundingAdjustment": 0,
  • "totalAmount": 0,
  • "journalEntryId": 0,
  • "settled": true,
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "lines": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List payments

Returns a page of payments (summary rows). Optionally filter by type (IN/OUT), status, counterpartyId, and/or an inclusive payment-date range (dateFrom/dateTo) — independent AND filters. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
query Parameters
type
string
Enum: "IN" "OUT"

Restrict to incoming (IN) or outgoing (OUT) payments.

status
string
Enum: "DRAFT" "POSTED" "CANCELLED"

Restrict to a single lifecycle state.

counterpartyId
integer <int64>

Restrict to one counterparty — the customer on an IN payment or the supplier on an OUT one.

dateFrom
string <date>
Example: dateFrom=2026-07-01

Inclusive lower bound on the payment date.

dateTo
string <date>
Example: dateTo=2026-07-31

Inclusive upper bound on the payment date.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a payment

Creates a DRAFT payment allocated to one or more posted invoices. Requires permission: FINANCE_WRITE. An IN payment names a customer, an OUT payment a supplier (matching type; else 422). bankAccountId must be a Cash/Bank ASSET account. v1 requires FULL settlement of each allocated invoice. For OUT, TDS is resolved at post; for IN, tdsAmount is the amount the customer withheld.

Authorizations:
bearerAuth
Request Body schema: application/json
required
type
required
string
Enum: "IN" "OUT"
paymentDate
required
string <date>
customerId
integer <int64>

Required for IN.

supplierId
integer <int64>

Required for OUT.

bankAccountId
required
integer <int64>

Cash/Bank ASSET account.

tdsSectionId
integer <int64>

Optional TDS section override (OUT).

tdsAmount
number

For IN, the amount the customer withheld (>= 0); for OUT it is resolved at post.

note
string <= 500 characters
required
Array of objects (PaymentAllocationRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "type": "OUT",
  • "paymentDate": "2026-07-10",
  • "supplierId": 387500,
  • "bankAccountId": 387202,
  • "tdsSectionId": 387280,
  • "note": "Vendor settlement",
  • "allocations": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "IN",
  • "paymentNumber": "string",
  • "paymentDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "tdsSectionId": 0,
  • "tdsSectionCode": "string",
  • "grossAmount": 0,
  • "tdsAmount": 0,
  • "tdsBaseAmount": 0,
  • "netAmount": 0,
  • "status": "DRAFT",
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "allocations": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a payment

Returns one payment with its allocations and TDS breakdown. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "IN",
  • "paymentNumber": "string",
  • "paymentDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "tdsSectionId": 0,
  • "tdsSectionCode": "string",
  • "grossAmount": 0,
  • "tdsAmount": 0,
  • "tdsBaseAmount": 0,
  • "netAmount": 0,
  • "status": "DRAFT",
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "allocations": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a payment

Replaces a DRAFT payment's fields and allocations. Requires permission: FINANCE_WRITE. A POSTED or CANCELLED payment is immutable (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
type
required
string
Enum: "IN" "OUT"
paymentDate
required
string <date>
customerId
integer <int64>

Required for IN.

supplierId
integer <int64>

Required for OUT.

bankAccountId
required
integer <int64>

Cash/Bank ASSET account.

tdsSectionId
integer <int64>

Optional TDS section override (OUT).

tdsAmount
number

For IN, the amount the customer withheld (>= 0); for OUT it is resolved at post.

note
string <= 500 characters
required
Array of objects (PaymentAllocationRequest) non-empty

Responses

Request samples

Content type
application/json
{
  • "type": "IN",
  • "paymentDate": "2019-08-24",
  • "customerId": 0,
  • "supplierId": 0,
  • "bankAccountId": 0,
  • "tdsSectionId": 0,
  • "tdsAmount": 0,
  • "note": "string",
  • "allocations": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "IN",
  • "paymentNumber": "string",
  • "paymentDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "tdsSectionId": 0,
  • "tdsSectionCode": "string",
  • "grossAmount": 0,
  • "tdsAmount": 0,
  • "tdsBaseAmount": 0,
  • "netAmount": 0,
  • "status": "DRAFT",
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "allocations": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a payment

Deletes a DRAFT payment. Requires permission: FINANCE_WRITE. A POSTED payment cannot be deleted — cancel it instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Post a payment

Posts a DRAFT payment (→ POSTED), resolves TDS (for OUT), settles the allocated invoice(s), and auto-posts the journal entry. Requires permission: PAYMENT_APPROVE. A second payment settling an already-settled or mismatched-type invoice → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "IN",
  • "paymentNumber": "string",
  • "paymentDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "tdsSectionId": 0,
  • "tdsSectionCode": "string",
  • "grossAmount": 0,
  • "tdsAmount": 0,
  • "tdsBaseAmount": 0,
  • "netAmount": 0,
  • "status": "DRAFT",
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "allocations": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Cancel a payment

Cancels a POSTED payment (→ CANCELLED), reverses its journal entry, unsettles the invoice, and rolls back the TDS ledger. Requires permission: PAYMENT_APPROVE. Cancelling a DRAFT → 422.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "type": "IN",
  • "paymentNumber": "string",
  • "paymentDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "supplierId": 0,
  • "supplierName": "string",
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "tdsSectionId": 0,
  • "tdsSectionCode": "string",
  • "grossAmount": 0,
  • "tdsAmount": 0,
  • "tdsBaseAmount": 0,
  • "netAmount": 0,
  • "status": "DRAFT",
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "allocations": [
    ],
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

List advance receipts

Returns a page of customer advance receipts (summary rows). Requires permission: FINANCE_READ. Filter by customerId and/or status.

Authorizations:
bearerAuth
query Parameters
customerId
integer <int64>
status
string
Enum: "DRAFT" "POSTED" "CANCELLED"
page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create an advance receipt

Creates a DRAFT customer advance against a milestone. Requires permission: FINANCE_WRITE. amount is pre-tax; a service advance (gstOnAdvance) also collects output GST and must name a taxCodeId. bankAccountId must be an ASSET account.

Authorizations:
bearerAuth
Request Body schema: application/json
required
advanceDate
required
string <date>
customerId
required
integer <int64>
salesOrderId
required
integer <int64>
milestoneId
required
integer <int64>
bankAccountId
required
integer <int64>

Cash/Bank ASSET account.

amount
required
number

Pre-tax amount (> 0).

gstOnAdvance
boolean

A service advance collects output GST at receipt.

taxCodeId
integer <int64>

Required when gstOnAdvance is true.

placeOfSupply
string = 2 characters
note
string <= 500 characters

Responses

Request samples

Content type
application/json
{
  • "advanceDate": "2026-07-02",
  • "customerId": 387600,
  • "salesOrderId": 387700,
  • "milestoneId": 387710,
  • "bankAccountId": 387202,
  • "amount": 256500,
  • "gstOnAdvance": true,
  • "taxCodeId": 387260,
  • "placeOfSupply": "27",
  • "note": "Advance for milestone 1"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "advanceNumber": "string",
  • "advanceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "amount": 0,
  • "gstOnAdvance": true,
  • "taxCodeId": 0,
  • "taxCodeCode": "string",
  • "placeOfSupply": "string",
  • "cgstAmt": 0,
  • "sgstAmt": 0,
  • "igstAmt": 0,
  • "grossAmount": 0,
  • "status": "DRAFT",
  • "adjusted": true,
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get an advance receipt

Returns one advance receipt with its frozen GST split. Requires permission: FINANCE_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "advanceNumber": "string",
  • "advanceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "amount": 0,
  • "gstOnAdvance": true,
  • "taxCodeId": 0,
  • "taxCodeCode": "string",
  • "placeOfSupply": "string",
  • "cgstAmt": 0,
  • "sgstAmt": 0,
  • "igstAmt": 0,
  • "grossAmount": 0,
  • "status": "DRAFT",
  • "adjusted": true,
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update an advance receipt

Replaces a DRAFT advance's fields. Requires permission: FINANCE_WRITE. A POSTED or CANCELLED advance is immutable (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
advanceDate
required
string <date>
customerId
required
integer <int64>
salesOrderId
required
integer <int64>
milestoneId
required
integer <int64>
bankAccountId
required
integer <int64>

Cash/Bank ASSET account.

amount
required
number

Pre-tax amount (> 0).

gstOnAdvance
boolean

A service advance collects output GST at receipt.

taxCodeId
integer <int64>

Required when gstOnAdvance is true.

placeOfSupply
string = 2 characters
note
string <= 500 characters

Responses

Request samples

Content type
application/json
{
  • "advanceDate": "2019-08-24",
  • "customerId": 0,
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "bankAccountId": 0,
  • "amount": 0,
  • "gstOnAdvance": true,
  • "taxCodeId": 0,
  • "placeOfSupply": "st",
  • "note": "string"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "advanceNumber": "string",
  • "advanceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "amount": 0,
  • "gstOnAdvance": true,
  • "taxCodeId": 0,
  • "taxCodeCode": "string",
  • "placeOfSupply": "string",
  • "cgstAmt": 0,
  • "sgstAmt": 0,
  • "igstAmt": 0,
  • "grossAmount": 0,
  • "status": "DRAFT",
  • "adjusted": true,
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete an advance receipt

Deletes a DRAFT advance receipt. Requires permission: FINANCE_WRITE. A POSTED advance cannot be deleted — cancel it instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

Post an advance receipt

Posts a DRAFT advance (→ POSTED) and auto-posts the journal entry (Dr Bank / Cr Customer Advances, plus output GST for a service advance). Requires permission: PAYMENT_APPROVE. The amount must not exceed the milestone's taxable value and the milestone must still be PENDING (else 422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "advanceNumber": "string",
  • "advanceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "amount": 0,
  • "gstOnAdvance": true,
  • "taxCodeId": 0,
  • "taxCodeCode": "string",
  • "placeOfSupply": "string",
  • "cgstAmt": 0,
  • "sgstAmt": 0,
  • "igstAmt": 0,
  • "grossAmount": 0,
  • "status": "DRAFT",
  • "adjusted": true,
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Cancel an advance receipt

Cancels a POSTED advance (→ CANCELLED) and reverses its journal entry. Requires permission: PAYMENT_APPROVE. Only permitted while the advance is unadjusted — cancel the milestone invoice first if it has been adjusted (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "advanceNumber": "string",
  • "advanceDate": "2019-08-24",
  • "customerId": 0,
  • "customerName": "string",
  • "salesOrderId": 0,
  • "milestoneId": 0,
  • "bankAccountId": 0,
  • "bankAccountCode": "string",
  • "amount": 0,
  • "gstOnAdvance": true,
  • "taxCodeId": 0,
  • "taxCodeCode": "string",
  • "placeOfSupply": "string",
  • "cgstAmt": 0,
  • "sgstAmt": 0,
  • "igstAmt": 0,
  • "grossAmount": 0,
  • "status": "DRAFT",
  • "adjusted": true,
  • "journalEntryId": 0,
  • "note": "string",
  • "createdBy": 0,
  • "cancelledBy": 0,
  • "cancelledAt": "2019-08-24T14:15:22Z",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

HR

Departments and employees.

List departments

Returns a page of departments. Requires permission: HR_READ. Sortable fields: name (default) and code.

Authorizations:
bearerAuth
query Parameters
active
boolean

Filter by active flag. Omit to return both active and inactive departments.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create a department

Creates a department. Requires permission: HR_WRITE. name and (if given) code are unique — a duplicate returns 409. managerId, if given, must reference an existing employee.

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string <= 150 characters

Department name (unique).

code
string <= 40 characters

Optional short code (unique when present).

description
string <= 500 characters
managerId
integer <int64>

Optional employee who leads the department.

active
boolean

Optional. Absent leaves the default (active) on create or the current value on update.

Responses

Request samples

Content type
application/json
{
  • "name": "Production",
  • "code": "PROD",
  • "description": "Fabrication and assembly of heat exchangers.",
  • "managerId": 387412,
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "code": "string",
  • "description": "string",
  • "managerId": 0,
  • "managerName": "string",
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get a department

Returns one department by id. Requires permission: HR_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "code": "string",
  • "description": "string",
  • "managerId": 0,
  • "managerName": "string",
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update a department

Replaces a department's fields. Requires permission: HR_WRITE. name/code uniqueness is enforced (409). Send managerId: null to clear the manager link.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
name
required
string <= 150 characters

Department name (unique).

code
string <= 40 characters

Optional short code (unique when present).

description
string <= 500 characters
managerId
integer <int64>

Optional employee who leads the department.

active
boolean

Optional. Absent leaves the default (active) on create or the current value on update.

Responses

Request samples

Content type
application/json
{
  • "name": "Production",
  • "code": "PROD",
  • "description": "Fabrication, welding, and assembly.",
  • "managerId": 387412,
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "code": "string",
  • "description": "string",
  • "managerId": 0,
  • "managerName": "string",
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete a department

Deletes a department. Requires permission: HR_WRITE. A department that still has employees cannot be deleted — deactivate it instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}

List employees

Returns a page of employees (summary rows with the resolved department name). Requires permission: HR_READ. Sortable fields: employeeCode (default), lastName, hireDate.

Authorizations:
bearerAuth
query Parameters
departmentId
integer <int64>

Filter to employees in this department.

active
boolean

Filter by active flag. Omit to return both active and inactive employees.

page
integer >= 0
Default: 0

Zero-based page index.

size
integer [ 1 .. 100 ]
Default: 20

Page size. Defaults to 20; requests above 100 are clamped to 100.

sort
string
Example: sort=name,asc

Sort clause as field,direction (e.g. name,asc). May be repeated for multi-field sort. Each endpoint permits only a specific allow-list of fields; an unlisted field returns 400.

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "page": 0,
  • "size": 20,
  • "totalElements": 137,
  • "totalPages": 7,
  • "sort": [
    ]
}

Create an employee

Creates an employee. Requires permission: HR_WRITE. employeeCode, email, and userId are each unique (duplicate → 409). departmentId and userId are optional links; a userId may be linked to at most one employee.

Authorizations:
bearerAuth
Request Body schema: application/json
required
employeeCode
required
string <= 40 characters

Employee code (unique).

firstName
required
string <= 100 characters
lastName
required
string <= 100 characters
email
required
string <email> <= 255 characters

Email address (unique).

phone
string <= 40 characters
jobTitle
string <= 150 characters
hireDate
required
string <date>

Hire date. Future dates are allowed for onboarding.

departmentId
integer <int64>

Optional department link (send null to clear).

userId
integer <int64>

Optional login-user link (unique; at most one employee per user; send null to clear).

active
boolean

Optional. Absent leaves the default (active) on create or the current value on update.

Responses

Request samples

Content type
application/json
{
  • "employeeCode": "EMP013",
  • "firstName": "Sanjay",
  • "lastName": "Kulkarni",
  • "email": "sanjay.kulkarni@forgethermal.co.in",
  • "phone": "+91 98200 11334",
  • "jobTitle": "Production Manager",
  • "hireDate": "2019-04-01",
  • "departmentId": 387405,
  • "userId": 387360,
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "employeeCode": "string",
  • "firstName": "string",
  • "lastName": "string",
  • "email": "user@example.com",
  • "phone": "string",
  • "jobTitle": "string",
  • "hireDate": "2019-08-24",
  • "departmentId": 0,
  • "departmentName": "string",
  • "userId": 0,
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Get an employee

Returns one employee by id, with the resolved department name. Requires permission: HR_READ.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "employeeCode": "string",
  • "firstName": "string",
  • "lastName": "string",
  • "email": "user@example.com",
  • "phone": "string",
  • "jobTitle": "string",
  • "hireDate": "2019-08-24",
  • "departmentId": 0,
  • "departmentName": "string",
  • "userId": 0,
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Update an employee

Replaces an employee's fields. Requires permission: HR_WRITE. employeeCode/email/userId uniqueness is enforced (409). Send departmentId: null or userId: null to clear those links.

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>
Request Body schema: application/json
required
employeeCode
required
string <= 40 characters

Employee code (unique).

firstName
required
string <= 100 characters
lastName
required
string <= 100 characters
email
required
string <email> <= 255 characters

Email address (unique).

phone
string <= 40 characters
jobTitle
string <= 150 characters
hireDate
required
string <date>

Hire date. Future dates are allowed for onboarding.

departmentId
integer <int64>

Optional department link (send null to clear).

userId
integer <int64>

Optional login-user link (unique; at most one employee per user; send null to clear).

active
boolean

Optional. Absent leaves the default (active) on create or the current value on update.

Responses

Request samples

Content type
application/json
{
  • "employeeCode": "EMP013",
  • "firstName": "Sanjay",
  • "lastName": "Kulkarni",
  • "email": "sanjay.kulkarni@forgethermal.co.in",
  • "phone": "+91 98200 11334",
  • "jobTitle": "Senior Production Manager",
  • "hireDate": "2019-04-01",
  • "departmentId": 387405,
  • "userId": 387360,
  • "active": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "employeeCode": "string",
  • "firstName": "string",
  • "lastName": "string",
  • "email": "user@example.com",
  • "phone": "string",
  • "jobTitle": "string",
  • "hireDate": "2019-08-24",
  • "departmentId": 0,
  • "departmentName": "string",
  • "userId": 0,
  • "active": true,
  • "createdAt": "2019-08-24T14:15:22Z",
  • "updatedAt": "2019-08-24T14:15:22Z"
}

Delete an employee

Deletes an employee. Requires permission: HR_WRITE. An employee who manages a department cannot be deleted — reassign the department's manager or deactivate the employee instead (422).

Authorizations:
bearerAuth
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "about:blank",
  • "title": "Unauthorized",
  • "status": 401,
  • "detail": "Authentication is required to access this resource.",
  • "instance": "/products",
  • "timestamp": "2026-07-09T14:12:03.221Z"
}