Guía para desarrolladores de Order API
Envíe pedidos estructurados a Packlistly y consulte los resultados de las comprobaciones de documentos. Starter, Expert, Pro y Enterprise incluyen Order API, también en las pruebas sin tarjeta que correspondan. Free no incluye claves de API.
Autenticación y acceso
- El propietario de la empresa inicia sesión y configura la verificación en dos pasos.
- Abra Integrations. Asigne un nombre a la clave de integración y seleccione
importpara crear o actualizar pedidos y/oreadpara leer resultados y descargar documentos. - Use
Authorization: Bearer YOUR_INTEGRATION_KEY. Trate la clave como un secreto, guárdela en la configuración de credenciales de su servidor o automatización y revóquela desde Integrations cuando deje de necesitarla.
Las solicitudes se ejecutan dentro de la empresa del propietario de la clave. La cuenta debe conservar el plan correspondiente, la verificación en dos pasos y los permisos de creación y exportación.
POST /api/v1/orders
Envíe JSON con exactamente dos campos de nivel superior: external_id (cadena no vacía, de hasta 160 caracteres) y shipment (objeto). Tamaño máximo del cuerpo: 2 MiB (2,097,152 bytes); máximo de 2000 líneas y 2000 filas de empaque. Mantenga una referencia externa estable para los reintentos. Repetir un contenido sin cambios con el mismo external_id devuelve 200 y changed=false; un contenido nuevo o modificado devuelve 201 y changed=true. Los datos modificados actualizan el mismo envío guardado y requieren revisar nuevamente las comprobaciones y la aprobación.
201: creado o modificado. 200: reintento sin cambios. 401: clave, alcance, cuenta o permisos no válidos. Las claves creadas antes de la actualización de seguridad de noviembre de 2026 devuelven 401 y deben crearse de nuevo en Integrations. 409: rechazo por límite o cupo. 413: cuerpo superior a 2 MiB. 422: entrada mal formada o no admitida. 429: límite de solicitudes excedido (reintente después de los segundos indicados en Retry-After). Cada clave de integración está limitada a 60 solicitudes por minuto entre estas rutas; al superar el límite, la API devuelve 429 con Retry-After: 60. Siguen aplicándose los límites del cuerpo, de filas y de envíos del plan.
Solicitud ficticia
{"external_id":"fictional-cedar-24017","shipment":{"seller":{"name":"Fictional Cedar Machinery LLC","address":"100 Example Road","country":"US"},"buyer":{"name":"Fictional Buyer","address":"200 Example Road","country":"CA"},"terms":{"invoice_no":"FC-24017","invoice_date":"2026-10-30","currency":"USD"},"lines":[{"sku":"PUMP-01","description":"Fictional pump assembly","qty":"24","unit":"pcs","unit_price":"10.00","origin":"US"}]}}
Fragmento de la respuesta (los demás campos del informe se describen abajo):
{"changed":true,"report":{"shipment_id":"fictional-sample","status":"needs_attention","review_required":true}}
Referencia completa de campos de importación
Opcional significa que existe un valor predeterminado del modelo, no que el envío esté listo para exportar. El motor de reglas evalúa los datos comerciales faltantes. Los campos decimales aceptan números JSON o cadenas decimales. Los campos que terminan en _kg usan kilogramos y los que terminan en _cm usan centímetros; los valores *_in_file usan weight_unit_in_file (kg/lb) o dim_unit_in_file (cm/in). Los importes monetarios usan terms.currency. Las cadenas de fecha se documentan en los nombres de los campos y en el esquema; los tipos del modelo por sí solos no establecen validez aduanera.
Solo se pueden importar los campos de shipment indicados aquí; no se aceptan los metadatos del servidor ni otros campos del modelo Shipment. En particular, forwarder_instructions, usmca, vgm, components y la configuración de unidades de visualización no son campos de entrada de Order API. Descargue el esquema JSON exacto de entrada.
Campos de shipment
| Campo | Obligatorio | Tipo, valor predeterminado y restricciones |
|---|---|---|
seller | No | {"$ref": "#/$defs/Party"} |
buyer | No | {"$ref": "#/$defs/Party"} |
consignee | No | {"$ref": "#/$defs/Party"} |
importer_of_record | No | {"$ref": "#/$defs/Party"} |
terms | No | {"$ref": "#/$defs/Terms"} |
marks | No | {"$ref": "#/$defs/Marks"} |
notes | No | {"items": {"type": "string"}, "title": "Notes", "type": "array"} |
lines | No | {"items": {"$ref": "#/$defs/LineItem"}, "title": "Lines", "type": "array"} |
packing | No | {"items": {"$ref": "#/$defs/PackingLine"}, "title": "Packing", "type": "array"} |
flags | No | {"items": {"$ref": "#/$defs/Flag"}, "title": "Flags", "type": "array"} |
Campos de Flag
| Campo | Obligatorio | Tipo, valor predeterminado y restricciones |
|---|---|---|
path | Sí | {"title": "Path", "type": "string"} |
reason | Sí | {"title": "Reason", "type": "string"} |
resolved | No | {"default": false, "title": "Resolved", "type": "boolean"} |
Campos de LineItem
| Campo | Obligatorio | Tipo, valor predeterminado y restricciones |
|---|---|---|
id | No | {"title": "Id", "type": "string"} |
sku | No | {"default": "", "title": "Sku", "type": "string"} |
description | No | {"default": "", "title": "Description", "type": "string"} |
hs_code | No | {"default": "", "title": "Hs Code", "type": "string"} |
origin | No | {"default": "", "title": "Origin", "type": "string"} |
qty | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Qty"} |
unit | No | {"default": "pcs", "title": "Unit", "type": "string"} |
unit_price | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Unit Price"} |
no_charge | No | {"default": false, "title": "No Charge", "type": "boolean"} |
customs_value_per_unit | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Customs Value Per Unit"} |
stated_line_total | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Stated Line Total"} |
eccn | No | {"default": "", "title": "Eccn", "type": "string"} |
license_type | No | {"default": "", "maxLength": 80, "title": "License Type", "type": "string"} |
lot_no | No | {"default": "", "title": "Lot No", "type": "string"} |
expiry_date | No | {"default": "", "title": "Expiry Date", "type": "string"} |
un_number | No | {"default": "", "title": "Un Number", "type": "string"} |
dg_class | No | {"default": "", "title": "Dg Class", "type": "string"} |
packing_group | No | {"default": "", "title": "Packing Group", "type": "string"} |
proper_shipping_name | No | {"default": "", "title": "Proper Shipping Name", "type": "string"} |
declaration | No | {"default": "", "title": "Declaration", "type": "string"} |
usmca_criterion | No | {"default": "", "enum": ["", "A", "B", "C", "D"], "title": "Usmca Criterion", "type": "string"} |
usmca_confirmed | No | {"default": false, "title": "Usmca Confirmed", "type": "boolean"} |
Campos de Marks
| Campo | Obligatorio | Tipo, valor predeterminado y restricciones |
|---|---|---|
consignee_mark | No | {"default": "", "title": "Consignee Mark", "type": "string"} |
destination | No | {"default": "", "title": "Destination", "type": "string"} |
po_number | No | {"default": "", "title": "Po Number", "type": "string"} |
handling | No | {"items": {"type": "string"}, "title": "Handling", "type": "array"} |
extra_lines | No | {"items": {"type": "string"}, "title": "Extra Lines", "type": "array"} |
language | No | {"default": "en", "enum": ["en", "en_es"], "title": "Language", "type": "string"} |
paper | No | {"default": "Letter", "enum": ["Letter", "A4"], "title": "Paper", "type": "string"} |
label_size | No | {"default": "4x6", "enum": ["4x6", "letter_2", "a4_4"], "title": "Label Size", "type": "string"} |
temperature | No | {"default": "", "title": "Temperature", "type": "string"} |
Campos de PackingLine
| Campo | Obligatorio | Tipo, valor predeterminado y restricciones |
|---|---|---|
shares_cartons_with_previous | No | {"default": false, "title": "Shares Cartons With Previous", "type": "boolean"} |
pallet | No | {"default": "", "title": "Pallet", "type": "string"} |
weight_unit_unconfirmed | No | {"additionalProperties": {"type": "string"}, "title": "Weight Unit Unconfirmed", "type": "object"} |
id | No | {"title": "Id", "type": "string"} |
sku | No | {"default": "", "title": "Sku", "type": "string"} |
carton_from | No | {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Carton From"} |
carton_to | No | {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Carton To"} |
cartons | No | {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Cartons"} |
per_carton | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Per Carton"} |
packed_qty | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Packed Qty"} |
unit | No | {"default": "pcs", "title": "Unit", "type": "string"} |
length_cm | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Length Cm"} |
width_cm | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Width Cm"} |
height_cm | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Height Cm"} |
net_kg | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Net Kg"} |
gross_kg | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Gross Kg"} |
weight_unit_in_file | No | {"default": "kg", "enum": ["kg", "lb"], "title": "Weight Unit In File", "type": "string"} |
net_in_file | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Net In File"} |
gross_in_file | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Gross In File"} |
dim_unit_in_file | No | {"default": "cm", "enum": ["cm", "in"], "title": "Dim Unit In File", "type": "string"} |
length_in_file | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Length In File"} |
width_in_file | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Width In File"} |
height_in_file | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Height In File"} |
tare_kg_per_carton | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Tare Kg Per Carton"} |
glaze_pct | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Glaze Pct"} |
kit_part | No | {"default": "", "title": "Kit Part", "type": "string"} |
package | No | {"default": "", "title": "Package", "type": "string"} |
lot_no | No | {"default": "", "title": "Lot No", "type": "string"} |
expiry_date | No | {"default": "", "title": "Expiry Date", "type": "string"} |
Campos de Party
| Campo | Obligatorio | Tipo, valor predeterminado y restricciones |
|---|---|---|
name | No | {"default": "", "title": "Name", "type": "string"} |
address | No | {"default": "", "title": "Address", "type": "string"} |
country | No | {"default": "", "title": "Country", "type": "string"} |
tax_id | No | {"default": "", "title": "Tax Id", "type": "string"} |
phone | No | {"default": "", "title": "Phone", "type": "string"} |
email | No | {"default": "", "title": "Email", "type": "string"} |
Campos de Terms
| Campo | Obligatorio | Tipo, valor predeterminado y restricciones |
|---|---|---|
tracking_number | No | {"default": "", "title": "Tracking Number", "type": "string"} |
carrier_name | No | {"default": "", "title": "Carrier Name", "type": "string"} |
invoice_no | No | {"default": "", "title": "Invoice No", "type": "string"} |
invoice_date | No | {"default": "", "title": "Invoice Date", "type": "string"} |
incoterm | No | {"default": "", "title": "Incoterm", "type": "string"} |
named_place | No | {"default": "", "title": "Named Place", "type": "string"} |
transport_mode | No | {"default": "", "enum": ["sea", "inland_waterway", "air", "road", "rail", "multimodal", "courier", ""], "title": "Transport Mode", "type": "string"} |
currency | No | {"default": "USD", "title": "Currency", "type": "string"} |
payment_terms | No | {"default": "", "title": "Payment Terms", "type": "string"} |
destination_country | No | {"default": "", "title": "Destination Country", "type": "string"} |
stated_total | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Stated Total"} |
stated_cartons | No | {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Stated Cartons"} |
stated_net_kg | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Stated Net Kg"} |
stated_gross_kg | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Stated Gross Kg"} |
itn | No | {"default": "", "title": "Itn", "type": "string"} |
eei_note | No | {"default": "", "title": "Eei Note", "type": "string"} |
discount | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Discount"} |
freight | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Freight"} |
insurance | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Insurance"} |
other_charges | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Other Charges"} |
other_charges_label | No | {"default": "", "title": "Other Charges Label", "type": "string"} |
charges_scope | No | {"default": "", "title": "Charges Scope", "type": "string"} |
pallets | No | {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "title": "Pallets"} |
pallet_kg | No | {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "default": null, "title": "Pallet Kg"} |
reason_for_export | No | {"default": "Sale", "title": "Reason For Export", "type": "string"} |
signer_name | No | {"default": "", "title": "Signer Name", "type": "string"} |
signer_title | No | {"default": "", "title": "Signer Title", "type": "string"} |
GET /api/v1/shipments/{id}
Use una clave con alcance read. Devuelve 200 con {"report":{...},"shipment":{...}}, o 404 cuando la empresa no tiene ese envío; los fallos de autenticación devuelven 401; 429 cuando la clave supera 60 solicitudes por minuto. El envío contiene datos guardados del modelo, incluidos metadatos del servidor, que no deben copiarse íntegramente a una solicitud de importación.
Estructura del informe
Campos: shipment_id, invoice_no, status, version, content_fingerprint, approved, prepared_by, approved_by, documents_current, review_required, checks, not_checked, revision_count, generated_at y scope. status es needs_attention, awaiting_approval, approved o checked. checks es una matriz de objetos que contienen id, kind (fix/answer/pass/info), title, detail, compare (ternas de cadenas), options (id/label/input_label/input_placeholder), accepted_exception y source. not_checked enumera las comprobaciones fuera del alcance de la herramienta. Los resultados describen la coherencia de los documentos; el exportador sigue siendo responsable de revisarlos.
GET /api/v1/shipments/{id}/documents.zip
Use una clave con alcance read. Devuelve un ZIP llamado checked_documents.zip que contiene los PDF generados aplicables y control_report.json. Devuelve 409 con un error y un informe mientras haya comprobaciones bloqueantes o una aprobación obligatoria pendientes; 404 si falta el envío; 401 si falla la autenticación; 429 cuando la clave supera 60 solicitudes por minuto. La generación utiliza el cupo de documentos y las reglas de aprobación existentes de la cuenta.
Conecte con Zapier o Make
Use herramientas HTTP genéricas; estos pasos no requieren una aplicación específica de Packlistly.
Webhooks by Zapier
- Agregue el activador de su pedido y después Webhooks by Zapier → Custom Request.
- Elija POST y el origen de Packlistly seguido de /api/v1/orders.
- Agregue el encabezado Authorization indicado arriba y Content-Type: application/json. Mantenga privada la clave.
- Asigne external_id y un cuerpo JSON shipment anidado siguiendo el ejemplo. Mantenga intactas las matrices anidadas y deje desactivada la conversión automática a estructura anidada cuando use un cuerpo JSON sin procesar que ya esté anidado.
- Pruebe con datos ficticios en su propio espacio de trabajo de prueba autorizado. Revise changed y report.review_required; recupere los resultados con GET usando el shipment_id recibido. Conserve el mismo external_id en los reintentos.
Instrucciones de Zapier para enviar webhooks
Make
- Agregue el activador de su pedido y después HTTP → Make a request.
- Elija POST y el origen de Packlistly seguido de /api/v1/orders. Configure Authorization: Bearer mediante una credencial o encabezado privado.
- Seleccione application/json y asigne el cuerpo anidado external_id/shipment, incluidas las matrices de líneas y empaque.
- Procese la respuesta. Dirija los pedidos review_required a una persona; no suponga que todo resultado 201 está listo para su liberación.
- Use un paso GET con alcance read para obtener resultados o documents.zip después de las comprobaciones y la aprobación. Mantenga la referencia externa estable al reintentar.
La entrada de la API y el alcance de las comprobaciones corresponden a la versión documentada. Revise cada envío antes de liberarlo.