Documentos de entrada y salida
Envío de órdenes de compra y pedidos para recibir o surtir, consulta del avance y confirmación al terminar.
En esta página
El ERP determina qué mercancía llega y qué se envía; Chainlink organiza el trabajo en el almacén. Esta guía describe el envío de órdenes de compra para recibir y de pedidos para surtir, la consulta del avance y la confirmación al terminar.
Alcances: receipts:write y receipts:read para entradas; pickings:write y pickings:read para salidas.
Requisitos
- Los productos de las líneas existen en el catálogo (sincronizar el catálogo).
warehouse_codees el código de un almacén de la instancia (GET /warehouses).partner_codees el código del proveedor (entradas) o del cliente (salidas) en el ERP.typeacepta la clave o el nombre:purchase_orderu «Orden de Compra»;sale_orderu «Orden de Venta».
Documento de entrada
POST /entry-documents con Idempotency-Key (obligatoria). El folio del ERP va en external_ref.
Chainlink valida cada línea con las mismas reglas que la plantilla de carga masiva (producto, almacén, ubicación destino, lote obligatorio, series). Si una línea no es válida, responde 422 con un elemento por problema en errors[] y no crea el documento.
curl -X POST "https://empresa.chainlink.mx/api/v1/entry-documents" \
-H "Authorization: Bearer $CHAINLINK_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"external_ref": "OC-2026-0042",
"type": "Orden de Compra",
"doc_date": "2026-10-06",
"due_date": "2026-10-09",
"partner_code": "PRV-001",
"partner_name": "Distribuidora del Bajío",
"warehouse_code": "CEDIS-GDL",
"lines": [
{
"item_code": "P-1001",
"qty": 48,
"batch": "L2610",
"expiry_date": "2027-04-30",
"destination_bin": "A-01-01-1"
},
{
"item_code": "P-1002",
"qty": 120
}
]
}'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://empresa.chainlink.mx/api/v1/entry-documents', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('CHAINLINK_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => (string) \Ramsey\Uuid\Uuid::uuid4(),
],
'json' => [
'external_ref' => 'OC-2026-0042',
'type' => 'Orden de Compra',
'doc_date' => '2026-10-06',
'due_date' => '2026-10-09',
'partner_code' => 'PRV-001',
'partner_name' => 'Distribuidora del Bajío',
'warehouse_code' => 'CEDIS-GDL',
'lines' => [
[
'item_code' => 'P-1001',
'qty' => 48,
'batch' => 'L2610',
'expiry_date' => '2027-04-30',
'destination_bin' => 'A-01-01-1',
],
[
'item_code' => 'P-1002',
'qty' => 120,
],
],
],
]);
$data = json_decode((string) $response->getBody(), true);
const response = await fetch('https://empresa.chainlink.mx/api/v1/entry-documents', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CHAINLINK_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"external_ref": "OC-2026-0042",
"type": "Orden de Compra",
"doc_date": "2026-10-06",
"due_date": "2026-10-09",
"partner_code": "PRV-001",
"partner_name": "Distribuidora del Bajío",
"warehouse_code": "CEDIS-GDL",
"lines": [
{
"item_code": "P-1001",
"qty": 48,
"batch": "L2610",
"expiry_date": "2027-04-30",
"destination_bin": "A-01-01-1"
},
{
"item_code": "P-1002",
"qty": 120
}
]
}),
});
const data = await response.json();
import os
import uuid
import requests
response = requests.post(
"https://empresa.chainlink.mx/api/v1/entry-documents",
headers={
"Authorization": f"Bearer {os.environ['CHAINLINK_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"external_ref": "OC-2026-0042",
"type": "Orden de Compra",
"doc_date": "2026-10-06",
"due_date": "2026-10-09",
"partner_code": "PRV-001",
"partner_name": "Distribuidora del Bajío",
"warehouse_code": "CEDIS-GDL",
"lines": [
{
"item_code": "P-1001",
"qty": 48,
"batch": "L2610",
"expiry_date": "2027-04-30",
"destination_bin": "A-01-01-1"
},
{
"item_code": "P-1002",
"qty": 120
}
]
},
)
data = response.json()
{
"error": { "code": "validation_failed", "message": "El artículo «P-9999» no existe.", "field": "lines.0.item_code", "doc_url": "https://chainlink.mx/developers/errores#validation_failed", "request_id": "req_01j9x2m4k7q8r5t6v3w0y1z2a3" },
"errors": [ { "field": "lines.0.item_code", "message": "El artículo «P-9999» no existe." } ],
"message": "El artículo «P-9999» no existe."
}
Documento de salida
POST /exit-documents funciona de la misma forma. Los campos opcionales priority (Alta, Normal, Baja) y ship_to permiten al supervisor ordenar el surtido.
curl -X POST "https://empresa.chainlink.mx/api/v1/exit-documents" \
-H "Authorization: Bearer $CHAINLINK_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"external_ref": "PED-88121",
"type": "Orden de Venta",
"doc_date": "2026-10-06",
"due_date": "2026-10-07",
"partner_code": "CLI-001",
"partner_name": "Abarrotes del Norte",
"warehouse_code": "CEDIS-GDL",
"priority": "Alta",
"ship_to": "Av. Vallarta 1200, Guadalajara",
"lines": [
{
"item_code": "P-1001",
"qty": 6
}
]
}'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://empresa.chainlink.mx/api/v1/exit-documents', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('CHAINLINK_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => (string) \Ramsey\Uuid\Uuid::uuid4(),
],
'json' => [
'external_ref' => 'PED-88121',
'type' => 'Orden de Venta',
'doc_date' => '2026-10-06',
'due_date' => '2026-10-07',
'partner_code' => 'CLI-001',
'partner_name' => 'Abarrotes del Norte',
'warehouse_code' => 'CEDIS-GDL',
'priority' => 'Alta',
'ship_to' => 'Av. Vallarta 1200, Guadalajara',
'lines' => [
[
'item_code' => 'P-1001',
'qty' => 6,
],
],
],
]);
$data = json_decode((string) $response->getBody(), true);
const response = await fetch('https://empresa.chainlink.mx/api/v1/exit-documents', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CHAINLINK_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"external_ref": "PED-88121",
"type": "Orden de Venta",
"doc_date": "2026-10-06",
"due_date": "2026-10-07",
"partner_code": "CLI-001",
"partner_name": "Abarrotes del Norte",
"warehouse_code": "CEDIS-GDL",
"priority": "Alta",
"ship_to": "Av. Vallarta 1200, Guadalajara",
"lines": [
{
"item_code": "P-1001",
"qty": 6
}
]
}),
});
const data = await response.json();
import os
import uuid
import requests
response = requests.post(
"https://empresa.chainlink.mx/api/v1/exit-documents",
headers={
"Authorization": f"Bearer {os.environ['CHAINLINK_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"external_ref": "PED-88121",
"type": "Orden de Venta",
"doc_date": "2026-10-06",
"due_date": "2026-10-07",
"partner_code": "CLI-001",
"partner_name": "Abarrotes del Norte",
"warehouse_code": "CEDIS-GDL",
"priority": "Alta",
"ship_to": "Av. Vallarta 1200, Guadalajara",
"lines": [
{
"item_code": "P-1001",
"qty": 6
}
]
},
)
data = response.json()
Prevención de duplicados
Un documento con un type y un external_ref existentes no se crea otra vez: la respuesta es 200 con el documento existente. En combinación con la llave de idempotencia, un reenvío después de un error de red no genera duplicados.
Consulta del avance
El documento se consulta por su id o por su folio. Cada línea indica la cantidad pendiente (open_qty) y la recibida (received_qty) o surtida (picked_qty).
El detalle del trabajo (operador, lotes, series, horas) está en recepciones y surtidos: GET /receipts?external_ref=OC-2026-0042 o GET /pickings?external_ref=PED-88121.
curl "https://empresa.chainlink.mx/api/v1/entry-documents?external_ref=OC-2026-0042" \
-H "Authorization: Bearer $CHAINLINK_TOKEN" \
-H "Accept: application/json"
Aviso de finalización
En lugar de consultas periódicas, use las suscripciones a receipt.completed y picking.completed. Cada aviso trae las líneas recibidas o surtidas con sus lotes y series, que se registran en el ERP. Ver Webhooks.