Chainlink Developers

Productos y catálogo

Da de alta y consulta el catálogo de productos y categorías, y resuelve códigos (SKU, código de barras o EPC RFID).

URL base

Todas las rutas son relativas a https://tu-empresa.chainlink.mx (el subdominio de tu tenant) y requieren un token Bearer. Consulta Autenticación y Convenciones.
GET /api/v1/products

Listar productos

Lista y busca productos del catálogo con paginación.

Parámetros de consulta

search string Coincidencia parcial (LIKE %término%) sobre item_code, name y barcode. Si se omite, usa el parámetro `q`.
q string Alias de `search`; solo se usa cuando `search` no viene.
item_code string Coincidencia exacta de item_code (se aplica además de cualquier término de búsqueda).
per_page integer Tamaño de página. Valores <1 se ajustan a 1, >100 se ajustan a 100. Por defecto 25.
page integer Número de página (base 1) del conjunto de resultados paginado.
Ordenado por nombre ASC. Los resultados se ordenan antes de paginar. La lectura está abierta a cualquier token autenticado. La respuesta usa el envoltorio estándar de colección de API-resource de Laravel (data + links + meta).
cURL
curl -X GET "https://tu-empresa.chainlink.mx/api/v1/products" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"
Respuesta (ejemplo)
{
  "data": [
    {
      "id": 9,
      "item_code": "DEMO-009",
      "sku": "DEMO-009",
      "name": "Aceite Vegetal 1L",
      "barcode": "7501000100093",
      "type": null,
      "image_url": null,
      "man_btch_num": true,
      "man_ser_num": false,
      "sales_unit": "PZA",
      "purchase_unit": "PZA",
      "inventory_item": true,
      "created_at": "2026-07-05T14:10:19.000000Z",
      "updated_at": "2026-07-05T14:10:19.000000Z"
    }
  ],
  "links": {
    "first": "https://demo.chainlink.mx/api/v1/products?page=1",
    "last": "https://demo.chainlink.mx/api/v1/products?page=220",
    "prev": null,
    "next": "https://demo.chainlink.mx/api/v1/products?page=2"
  },
  "meta": {
    "current_page": 1,
    "per_page": 1,
    "from": 1,
    "to": 1,
    "last_page": 220,
    "total": 220
  }
}
GET /api/v1/products/{id}

Obtener producto

Obtiene un solo producto por su ID numérico.

Parámetros de ruta

id requerido integer Llave primaria del producto. Devuelve 404 si no hay coincidencia.
Se resuelve por route-model binding sobre el id numérico (no por item_code). El controlador precarga la relación `stocks`, pero ProductResource no la expone, por lo que las existencias no aparecen en el cuerpo de la respuesta. Objeto único envuelto en la clave `data`.
cURL
curl -X GET "https://tu-empresa.chainlink.mx/api/v1/products/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"
Respuesta (ejemplo)
{
  "data": {
    "id": "integer",
    "item_code": "string",
    "sku": "string",
    "name": "string",
    "barcode": "string",
    "type": "string",
    "image_url": "string",
    "man_btch_num": "boolean",
    "man_ser_num": "boolean",
    "sales_unit": "string",
    "purchase_unit": "string",
    "inventory_item": "boolean",
    "created_at": "string",
    "updated_at": "string"
  }
}
POST /api/v1/products inventory.manage

Crear producto

Crea un nuevo producto.

Cuerpo (JSON)

item_code requerido string Código de artículo / SKU canónico. Debe ser único entre los productos.
name requerido string Nombre visible del producto.
barcode string Código de barras EAN/UPC.
type string Tipo o clasificación del producto.
man_ser_num boolean Bandera de manejo por número de serie.
man_btch_num boolean Bandera de manejo por lote.
sales_unit string Unidad de medida de venta.
purchase_unit string Unidad de medida de compra.
inventory_item boolean Bandera de artículo con control de inventario.
La escritura requiere el permiso inventory.manage (aplicado por el middleware api.permission). La validación es inline mediante $request->validate() en el controlador — el FormRequest App\Http\Requests\Api\StoreProductRequest existe pero NO lo usa este endpoint V1 (legado). Devuelve 201 Created; 422 si falla la validación; 403 si el token no tiene inventory.manage.
Cuerpo del request
{
  "item_code": "SKU-001",
  "name": "Producto de ejemplo",
  "barcode": "7501000000001",
  "sales_unit": "<sales_unit>",
  "purchase_unit": "<purchase_unit>"
}
cURL
curl -X POST "https://tu-empresa.chainlink.mx/api/v1/products" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
  "item_code": "SKU-001",
  "name": "Producto de ejemplo",
  "barcode": "7501000000001",
  "sales_unit": "<sales_unit>",
  "purchase_unit": "<purchase_unit>"
}'
Respuesta (ejemplo)
{
  "data": {
    "id": "integer",
    "item_code": "string",
    "sku": "string",
    "name": "string",
    "barcode": "string",
    "type": "string",
    "image_url": "string",
    "man_btch_num": "boolean",
    "man_ser_num": "boolean",
    "sales_unit": "string",
    "purchase_unit": "string",
    "inventory_item": "boolean",
    "created_at": "string",
    "updated_at": "string"
  }
}
PUT /api/v1/products/{id} inventory.manage

Actualizar producto

Actualiza un producto existente (también acepta PATCH).

Parámetros de ruta

id requerido integer Llave primaria del producto. 404 si no se encuentra.

Cuerpo (JSON)

item_code string Código de artículo / SKU; único ignorando el propio registro. Solo se valida cuando viene presente.
name string Nombre visible del producto. Solo se valida cuando viene presente.
barcode string Código de barras EAN/UPC.
type string Tipo de producto.
man_ser_num boolean Bandera de manejo por número de serie.
man_btch_num boolean Bandera de manejo por lote.
sales_unit string Unidad de medida de venta.
purchase_unit string Unidad de medida de compra.
inventory_item boolean Bandera de artículo con control de inventario.
Registrado vía apiResource, por lo que tanto PUT como PATCH llegan aquí. La escritura requiere inventory.manage. Usa `sometimes` en item_code/name (se permiten actualizaciones parciales); la unicidad de item_code ignora el registro actual. La validación es inline (el FormRequest UpdateProductRequest no lo usa esta ruta V1). 422 si falla la validación; 403 sin inventory.manage.
Cuerpo del request
{
  "item_code": "SKU-001",
  "name": "Producto de ejemplo",
  "barcode": "7501000000001",
  "sales_unit": "<sales_unit>",
  "purchase_unit": "<purchase_unit>"
}
cURL
curl -X PUT "https://tu-empresa.chainlink.mx/api/v1/products/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
  "item_code": "SKU-001",
  "name": "Producto de ejemplo",
  "barcode": "7501000000001",
  "sales_unit": "<sales_unit>",
  "purchase_unit": "<purchase_unit>"
}'
Respuesta (ejemplo)
{
  "data": {
    "id": "integer",
    "item_code": "string",
    "sku": "string",
    "name": "string",
    "barcode": "string",
    "type": "string",
    "image_url": "string",
    "man_btch_num": "boolean",
    "man_ser_num": "boolean",
    "sales_unit": "string",
    "purchase_unit": "string",
    "inventory_item": "boolean",
    "created_at": "string",
    "updated_at": "string"
  }
}
DELETE /api/v1/products/{id} inventory.manage

Eliminar producto

Elimina un producto.

Parámetros de ruta

id requerido integer Llave primaria del producto. 404 si no se encuentra.
La escritura requiere inventory.manage. Devuelve 204 sin cuerpo en caso de éxito. 403 si el token no tiene inventory.manage.
cURL
curl -X DELETE "https://tu-empresa.chainlink.mx/api/v1/products/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"
GET /api/v1/products/{code}/detail

Detalle de producto (con existencias)

Devuelve el detalle completo del producto: información más las existencias disponibles agrupadas por posición, lote y serie, resolviendo por item_code, barcode o EPC RFID.

Parámetros de ruta

code requerido string Un código escaneable: item_code, barcode (EAN/UPC) o EPC RFID. Se resuelve vía Product::findByCode (item_code/barcode, luego EPC de RfidTagDetail → detailable/stock → producto). Devuelve un envoltorio de error 404 personalizado si no se resuelve.
NO usa ProductResource — arma a mano el envoltorio JSON (status/code/data). Solo cuenta existencias mediante el scope inStock() con qty > 0, ordenadas por id de stock. El 404 devuelve {status:'error', code:404, message:'Producto no encontrado.'}. El segmento de ruta {code} admite cualquier carácter (where '.*'), así que funcionan barcodes/EPCs que contengan diagonales.
cURL
curl -X GET "https://tu-empresa.chainlink.mx/api/v1/products/{code}/detail" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"
Respuesta (ejemplo)
{
  "data": {
    "status": "string",
    "code": "integer",
    "data.product.id": "integer",
    "data.product.item_code": "string",
    "data.product.sku": "string",
    "data.product.name": "string",
    "data.product.barcode": "string",
    "data.product.type": "string",
    "data.product.image_url": "string",
    "data.product.man_ser_num": "boolean",
    "data.product.man_btch_num": "boolean",
    "data.product.sales_unit": "string",
    "data.on_hand": "number (float)",
    "data.locations[].qty": "number (float)",
    "data.locations[].serial_number": "string",
    "data.locations[].batch_num": "string",
    "data.locations[].bin_code": "string",
    "data.locations[].whs_code": "string",
    "data.locations[].warehouse": "string"
  }
}
GET /api/v1/product-categories

Listar categorías de producto

Lista las categorías de producto con paginación.

Parámetros de consulta

search string Coincidencia parcial (LIKE %término%) sobre el nombre de la categoría.
per_page integer Tamaño de página, ajustado a 1..100. Por defecto 25.
page integer Número de página (base 1).
Sin API Resource — devuelve el paginador crudo vía response()->json($categories), por lo que el envoltorio es la forma completa de LengthAwarePaginator de Laravel (no el formato data/links/meta que usa ProductResource). Ordenado por nombre ASC. Las categorías son la salida cruda del modelo; los campos reflejan el modelo de categoría de la tabla de productos (name, description).
cURL
curl -X GET "https://tu-empresa.chainlink.mx/api/v1/product-categories" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"
Respuesta (ejemplo)
{
  "data": [],
  "meta": {
    "current_page": 1,
    "per_page": 1,
    "from": null,
    "to": null,
    "last_page": 1,
    "total": 0
  },
  "links": {
    "first": "https://demo.chainlink.mx/api/v1/product-categories?page=1",
    "last": "https://demo.chainlink.mx/api/v1/product-categories?page=1",
    "prev": null,
    "next": null
  }
}
GET /api/v1/product-categories/{id}

Obtener categoría de producto

Obtiene una sola categoría de producto por su ID.

Parámetros de ruta

id requerido integer Llave primaria de la categoría. 404 si no se encuentra.
Sin API Resource y sin envoltorio `data` — el modelo se devuelve directamente vía response()->json($productCategory). Solo lectura (para product-categories únicamente se registran index/show).
cURL
curl -X GET "https://tu-empresa.chainlink.mx/api/v1/product-categories/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"
Respuesta (ejemplo)
{
  "data": {
    "id": "integer",
    "name": "string",
    "description": "string",
    "created_at": "string",
    "updated_at": "string"
  }
}
GET /api/v1/lookup/{code}

Resolver un código (lookup)

Búsqueda universal de cualquier escaneo: resuelve cualquier código escaneado a un producto, una unidad de existencias o una posición de almacén.

Parámetros de ruta

code requerido string Cualquier valor escaneado: item_code/barcode/EPC RFID de producto, serial_number o batch_num de existencias, o un bin_code de posición de almacén. Se resuelve por orden de prioridad (producto → existencias → posición); gana la primera coincidencia.
Orden de resolución (LookupResolver): 1) Product::findByCode (item_code/barcode, luego EPC RFID vía RfidTagDetail), 2) Stock por serial_number o batch_num, 3) WarehousePosition por bin_code. La ruta {code} admite diagonales (where '.*') y se le aplica rawurldecode(), así que funcionan barcodes/EPCs codificados. Devuelve LookupResultResource que envuelve el propio resource V1 de la entidad encontrada; un código vacío o en blanco produce 404.
cURL
curl -X GET "https://tu-empresa.chainlink.mx/api/v1/lookup/{code}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"
Respuesta (ejemplo)
{
  "data": {
    "type": "string",
    "data": "object"
  }
}

¿Necesitas habilitar un endpoint o tienes dudas? Contáctanos.

← Volver al inicio de Developers