Serial Numbers API

Retrieve and separate product serial numbers (serial numbers, LOT/batch items)

Base URL

https://{tenant}.logzi.com/api/stock_serial/

Every request returns a JSON response. On success result.code == 1 (HTTP 200), on error or when no record is found result.code == 0 (HTTP 203).

Note: Serial numbers are generated automatically during the warehouse receipt/issue process. Via the API they can be retrieved and LOT (batch) items can be separated; creating new serial numbers and deleting them is not available.

How it works

The serialnumber_required setting of the product determines how the system handles serial numbers:

  • 1 – serial number required: every piece is a separate serial number row, quantity is always 1.
  • 2 – LOT (batch) number required: one row represents several pieces, quantity is the quantity in the LOT.
  • 3 – LOT number and shelf life required: like LOT, but the row also has a date_expire (expiry) value.

The separating endpoints (save_separate, save_separate_all) split LOT rows. When separating, the new row(s) receive all data of the source row (product, warehouse, locality, pallet, serial number/LOT identifier, expiry, creation date) and its document links as well; the total stock quantity does not change.

Separation is only possible on a row that is not used (used = 0) and not deleted (remove = 0).

GET /api/stock_serial/get

Retrieve a single serial number record by ID. A deleted (remove = 1) record is not returned.

Query parameters

Parameter Type Required Description
id int Unique identifier of the serial number record (db_stock_serial.id)

Response fields (data object)

FieldTypeDescription
idintIdentifier of the serial number record
product_idintIdentifier of the product
store_idintIdentifier of the warehouse (site) where the item is located
company_idintIdentifier of the company the item belongs to
serial_numberstringThe serial number or LOT (batch) identifier, up to 30 characters
quantityfloatQuantity: 1 for serial number products, the number of pieces in the LOT for LOT products
usedint0 = available (not used), 1 = used
removeintDeletion flag, the query only returns records with value 0
store_locality_idint | nullIdentifier of the warehouse locality, if the item is assigned to a locality
pallet_idint | nullIdentifier of the pallet, if the item is assigned to a pallet
date_createdatetimeCreation time of the serial number (YYYY-MM-DD HH:MM:SS)
date_expiredatetime | nullShelf life (expiry) date, only filled for LOT products that require shelf life
chkstringInternal check identifier (32 characters), not to be used in integrations

Example request

GET /api/stock_serial/get?id=42
X-API-KEY: {your_api_key}

Example response

{
  "result": { "code": 1, "message": null },
  "data": {
    "id": 42,
    "product_id": 5,
    "store_id": 1,
    "date_create": "2024-03-15 10:22:00",
    "company_id": 1,
    "serial_number": "LOT-2024-00042",
    "remove": 0,
    "used": 0,
    "chk": "5f4dcc3b5aa765d61d8327deb882cf99",
    "store_locality_id": 7,
    "pallet_id": null,
    "quantity": 50,
    "date_expire": "2026-03-15 00:00:00"
  }
}

Record not found

HTTP 203
{
  "result": { "code": 0, "message": "Not found" },
  "data": null
}
GET /api/stock_serial/list

Retrieve a paginated list of serial numbers with filtering options. Only non-deleted (remove = 0) records of stockable products are listed, in descending order of ID.

Query parameters

Parameter Type Required Description
list_offset int Pagination offset, the number of records to skip from the beginning (default: 0). A single request returns at most 10,000 records.
list_condition[product_id] int Filter by product identifier (exact match)
list_condition[used] int Usage state: 0 = available, 1 = used
list_condition[serial_number] string Filter by serial number / LOT identifier (exact match)
list_condition[partnumber] string Filter by product part number (exact match)
list_condition[item_id_used_0] int Serial numbers available for a document item: rows that are not used (used = 0) and rows already linked to this item (item_id)
list_condition[receipt_id] int Serial numbers linked to the given document. Only valid together with the receipt_type_id field.
list_condition[receipt_type_id] int Identifier of the document type. Only valid together with the receipt_id field.
list_condition[store_locality_id] int Filter by warehouse locality identifier
list_condition[product_name_partnumber] string Filter by product name or part number (LIKE, wildcard: %)
list_condition[product_name] string Filter by part of the product name
list_condition[product_partnumber_barcode] string Filter by part of the part number or by the product barcode
list_condition[date_create_from] date Creation date from (inclusive), format: YYYY-MM-DD
list_condition[date_create_to] date Creation date until (inclusive), format: YYYY-MM-DD
list_condition[date_expire_from] date Expiry date from (inclusive), format: YYYY-MM-DD
list_condition[date_expire_to] date Expiry date until (inclusive), format: YYYY-MM-DD

Response fields (elements of the data array)

The elements contain all fields of the get endpoint, with the following differences and additions:

FieldTypeDescription
stock_serial_idintIdentifier of the serial number record (same as the id field)
date_createstringCreation time, format: YYYY.MM.DD HH:MM:SS
date_expirestring | nullExpiry date, format: YYYY.MM.DD
product_unit_namestringName of the product
partnumberstringPart number of the product
store_locality_barcodestring | nullBarcode of the warehouse locality
pallet_barcodestring | nullBarcode of the pallet
store_namestringName of the warehouse (site)

Response fields (params object)

FieldTypeDescription
list_countintMaximum number of records returned in one request (10,000)
list_offsetintThe offset given in the request
list_allintTotal number of records matching the filter

Example request

GET /api/stock_serial/list?list_offset=0&list_condition[product_id]=5&list_condition[used]=0
X-API-KEY: {your_api_key}

Example response

{
  "result": { "code": 1, "message": null },
  "data": [
    {
      "id": 42,
      "stock_serial_id": 42,
      "product_id": 5,
      "store_id": 1,
      "company_id": 1,
      "serial_number": "LOT-2024-00042",
      "quantity": 50,
      "used": 0,
      "remove": 0,
      "chk": "5f4dcc3b5aa765d61d8327deb882cf99",
      "store_locality_id": 7,
      "pallet_id": null,
      "date_create": "2024.03.15 10:22:00",
      "date_expire": "2026.03.15",
      "product_unit_name": "Laptop XYZ",
      "partnumber": "LTP-XYZ-001",
      "store_locality_barcode": "A-01-02",
      "pallet_barcode": null,
      "store_name": "Main warehouse"
    }
  ],
  "params": {
    "list_count": 10000,
    "list_offset": 0,
    "list_all": 1
  }
}
POST /api/stock_serial/save_separate

Separates the given quantity from a LOT (batch) serial number row into a new row. The quantity of the source row decreases, the new row is created with the same data (product, warehouse, locality, pallet, serial number/LOT identifier, expiry) and the separated quantity.

POST fields - data object

FieldTypeRequiredDescription
stock_serial_idintIdentifier of the serial number row to be separated. The row must not be deleted and must not be used (used = 0).
quantityfloatThe quantity to separate. It must be greater than zero and less than the total quantity of the row.

Response fields (data object)

FieldTypeDescription
stock_serial_idintIdentifier of the source row
new_stock_serial_idintIdentifier of the newly created row
quantity_separatedfloatThe quantity separated into the new row
quantity_leftfloatThe quantity left in the source row

Error messages (result.message)

MessageWhen
Not foundThe data field is missing or empty
ex_stock_serial_separate_itemThe stock_serial_id is missing, invalid, does not exist or is deleted
ex_stock_serial_separate_usedThe row is already used (used = 1)
ex_stock_serial_separate_qtyThe quantity is not a number, is not greater than zero, or is not less than the total quantity
ex_unknown_msgUnknown error during saving. On error the whole operation is rolled back.

Example request

POST /api/stock_serial/save_separate
X-API-KEY: {your_api_key}
Content-Type: application/json

{
  "data": {
    "stock_serial_id": 42,
    "quantity": 20
  }
}

Example response

{
  "result": { "code": 1, "message": "success_msg" },
  "data": {
    "stock_serial_id": 42,
    "new_stock_serial_id": 57,
    "quantity_separated": 20,
    "quantity_left": 30
  }
}
POST /api/stock_serial/save_separate_all

Splits a LOT (batch) serial number row completely into single pieces: as many rows of 1 piece are created as the quantity of the row (e.g. a row of 50 pieces becomes 50 rows of 1 piece). The original row remains and its quantity is reduced to 1, the other (quantity - 1) rows are newly created with the same data.

POST fields - data object

FieldTypeRequiredDescription
stock_serial_idintIdentifier of the serial number row to be split. The row must not be deleted and must not be used (used = 0), its quantity must be a positive integer, at least 2 and at most 25,000.

Response fields (data object)

FieldTypeDescription
stock_serial_idintIdentifier of the original row (it also becomes a row of 1 piece)
quantity_beforefloatQuantity of the original row before the split
countintNumber of rows after the split (including the original row, equal to quantity_before)
stock_serial_idsint[]Identifiers of all rows: the original row first, followed by the newly created rows in ascending order

Error messages (result.message)

MessageWhen
Not foundThe data field is missing or empty
ex_stock_serial_separate_itemThe stock_serial_id is missing, invalid, does not exist or is deleted
ex_stock_serial_separate_usedThe row is already used (used = 1)
ex_stock_serial_separate_qty_integerThe quantity of the row is not a positive integer
ex_stock_serial_separate_singleThe quantity of the row is 1, there is nothing to split
ex_stock_serial_separate_max_rowsThe quantity of the row exceeds the 25,000 pieces that can be split at once (the allowed maximum is appended to the message)
ex_unknown_msgUnknown error during saving. On error the whole operation is rolled back.
Warning: The operation cannot be undone via the API (there is no endpoint for merging the rows back). Splitting a large quantity may take longer.

Example request

POST /api/stock_serial/save_separate_all
X-API-KEY: {your_api_key}
Content-Type: application/json

{
  "data": {
    "stock_serial_id": 42
  }
}

Example response (splitting a row of 3 pieces)

{
  "result": { "code": 1, "message": "success_msg" },
  "data": {
    "stock_serial_id": 42,
    "quantity_before": 3,
    "count": 3,
    "stock_serial_ids": [42, 58, 59]
  }
}

Get in touch with us

Interested in our software? Feel free to write to us!

Need help?

If you can't find the answer and need assistance

Create your account now,
pay later!

Try it free for 3 days, no risk, no obligation!