Crear un trabajo de carga
Valida la solicitud, reserva de tus créditos el precio máximo posible y pone un trabajo en cola.
Responde 202 con el trabajo; consulta GET /v1/jobs/{id} periódicamente o pasa ?wait= para mantener la respuesta abierta hasta que termine. Los errores de validación (422) son gratuitos y no crean ningún trabajo.
Autenticación
Parámetros de consulta
waitintegerSegundos que la respuesta espera a que el trabajo termine. Si termina a tiempo: 200 con el resultado incluido. Si no: 202.
00–60Parámetros de cabecera
Idempotency-KeystringCualquier cadena única, como un UUID o tu ID de pedido. La misma clave dentro de un plazo de 24 h devuelve el trabajo original en lugar de crear y cobrar uno nuevo.
Parámetros del cuerpo
application/jsonreferencestringTu propia referencia (número de pedido, ID de envío…). Se devuelve en el trabajo.
vehiclesVehicle[]obligatorioDefiniciones de vehículos. Cada una puede tener quantity > 1. Al menos una.
idstringTu identificador, único dentro de la solicitud. Los resultados se refieren a él como vehicle_id. Por defecto, vehicle_id.
vehicle_idstringUn ID de vehículo de GET /v1/vehicles: uno predefinido o uno de los vehículos de tu organización (veh_…). Aporta el tipo, el nombre, las dimensiones, la carga útil y todos los demás valores guardados.
typestringTipo de vehículo. Obligatorio salvo que se indique vehicle_id. Solo se aceptan los tipos indicados en GET /v1/limits (allowed_vehicle_types).
trucktrailerflatbedcontainerpalletaircraftshipnamestringNombre visible (por defecto, el nombre del vehículo guardado o el ID).
lengthnumber · cmLargo interior del espacio de carga, a lo largo de x (desde la pared frontal hacia la puerta). Obligatorio salvo que se indique vehicle_id.
widthnumber · cmAncho interior del espacio de carga, a lo largo de z. Obligatorio salvo que se indique vehicle_id.
heightnumber · cmAlto interior del espacio de carga, a lo largo de y. Obligatorio salvo que se indique vehicle_id.
max_weightnumber · kgCarga útil máxima. Obligatorio salvo que se indique vehicle_id.
quantityintegerCuántos vehículos idénticos de esta definición hay disponibles.
11–100floor_load_capacitynumber · kg/m²Capacidad de carga del suelo: 0 o más (0 = sin límite).
aux_deckbooleanEl vehículo tiene un segundo piso (doble piso).
falseaux_deck_heightnumber · cmAltura del segundo piso sobre el suelo. Obligatorio cuando aux_deck es true.
aux_deck_max_weightnumber · kgLímite de carga del segundo piso. Obligatorio cuando aux_deck es true.
blocked_areasRect[]Zonas del suelo en las que no se puede colocar nada (pasos de rueda, daños, espacio reservado). Cada una debe estar dentro del suelo del vehículo.
xnumber · cmobligatorioDistancia desde la pared frontal hasta el borde más cercano del rectángulo.
znumber · cmobligatorioDistancia desde la pared derecha (z = 0; la derecha vista desde la puerta, mirando hacia dentro) hasta el borde más cercano del rectángulo.
lengthnumber · cmobligatorioExtensión a lo largo de x.
widthnumber · cmobligatorioExtensión a lo largo de z.
axle_positionsRequiere accesonumber[] · cmPosiciones de los ejes (puntos de apoyo) medidas desde la parte delantera de la zona de carga; negativo = por delante de ella. Mismo número de elementos que axle_max_loads. Cada una entre −300 (un eje por delante de la zona de carga, p. ej., el eje delantero de un camión rígido, bajo la cabina) y el largo del vehículo.
axle_max_loadsRequiere accesonumber[] · kgCarga máxima por eje, en el orden de axle_positions. Cada valor debe ser mayor que 0 y no superar 100000.
cog_range_xRequiere accesonumber · cmDesviación permitida del centro de gravedad respecto a la mitad del largo: de 0 a length / 2.
cog_range_yRequiere accesonumber · cmDesviación permitida del centro de gravedad respecto a la mitad del ancho: de 0 a width / 2.
tractor_weightRequiere accesonumber · kgModelo de ejes de semirremolque: masa de la tractora.
empty_trailer_weightRequiere accesonumber · kgModelo de ejes de semirremolque: masa en vacío del remolque.
front_axle_to_middle_axleRequiere accesonumber · cmModelo de ejes de semirremolque: del eje delantero de la tractora al eje motriz (central).
front_axle_to_tractor_cogRequiere accesonumber · cmModelo de ejes de semirremolque: del eje delantero al centro de gravedad de la tractora.
front_axle_to_kingpinRequiere accesonumber · cmModelo de ejes de semirremolque: del eje delantero al pivote de enganche (quinta rueda).
kingpin_to_rear_axleRequiere accesonumber · cmModelo de ejes de semirremolque: del pivote de enganche al grupo de ejes traseros del remolque.
trailer_cog_to_rear_axleRequiere accesonumber · cmModelo de ejes de semirremolque: del centro de gravedad del remolque al grupo de ejes traseros.
trailer_start_to_kingpinRequiere accesonumber · cmModelo de ejes de semirremolque: de la parte delantera del remolque al pivote de enganche.
max_middle_axle_weightRequiere accesonumber · kgModelo de ejes de semirremolque: límite legal del eje motriz (central).
max_rear_axle_weightRequiere accesonumber · kgModelo de ejes de semirremolque: límite legal del grupo de ejes traseros.
itemsItem[]obligatorioDefiniciones de artículos. Cada una puede tener quantity > 1. Al menos una.
idstringTu identificador, único dentro de la solicitud. Los resultados se refieren a él como item_id. Por defecto, template_id.
template_idstringUn ID de plantilla (tpl_…) de GET /v1/templates. Aporta todos los campos del artículo; los campos enviados junto a él los sustituyen.
labelstringEtiqueta visible (por defecto, el ID).
shapestringForma del artículo. cylinder y drum usan radius + height en lugar de length + width; pallet y drum siempre se mantienen en vertical.
boxcylinderpalletbagdrumPredeterminado "box"lengthnumber · cmLargo. Obligatorio salvo que shape sea cylinder o drum.
widthnumber · cmAncho. Obligatorio salvo que shape sea cylinder o drum.
heightnumber · cmobligatorioAlto (el lado vertical cuando el artículo está colocado tal como se definió).
radiusnumber · cmRadio. Obligatorio cuando shape es cylinder o drum.
weightnumber · kgobligatorioPeso de UNA unidad.
quantityintegerNúmero de unidades idénticas.
11–10000stackablebooleanSe pueden colocar otros artículos encima.
truemax_stack_weightnumber · kgPeso máximo que puede soportar una unidad. 0 = ilimitado.
0rotationstringall = cualquiera de las seis orientaciones; upright = solo puede girar sobre el eje vertical (este lado arriba); fixed = nunca se gira.
alluprightfixedPredeterminado "all"hazardousbooleanMercancía peligrosa: se mantiene cerca del suelo y separada de otros artículos peligrosos.
falsepriorityintegerPrioridad de carga. Mayor = se carga antes y se mantiene cuando falta espacio. 0 = ninguna.
0groupstringNombre del grupo al que pertenece este artículo (consulta groups y options.group_routing).
colorstringColor de visualización en formato #rrggbb (solo visor y PDF).
nesting_heightnumber · cmSolapamiento telescópico cuando se apilan unidades idénticas (cajas o cubos encajables).
0groupsGroup[]Grupos opcionales (clientes, paradas, pedidos). Obligatorios para cada grupo que indique un artículo cuando options.group_routing no es "none"; si no, los grupos se crean a partir de los nombres de grupo de los artículos, por orden de aparición.
namestringobligatorioNombre del grupo, al que hace referencia Item.group.
orderintegerOrden de carga (menor = se carga antes). Por defecto, su posición en la lista.
colorstringColor de visualización en formato #rrggbb.
optionsOptionsOpciones de carga. Todos los campos son opcionales.
packing_modestringauto = cuando los vehículos indicados se llenan, se añaden más copias del vehículo más adecuado (hasta el límite de vehículos del trabajo); fleet_only = solo se usan los vehículos indicados y lo que no cabe aparece como sin colocar.
autofleet_onlyPredeterminado "auto"group_routingstringnone = los grupos son solo informativos; wall = cada grupo tiene su propia sección del vehículo; routing = los grupos se cargan en orden y un grupo posterior puede ir encima o al lado de uno anterior, pero nunca debajo (entregas con varias paradas); no_stack = los grupos se cargan en orden, uno al lado del otro, nunca uno encima de otro.
nonewallroutingno_stackPredeterminado "none"allow_overweightbooleanIgnora los límites de carga útil de los vehículos.
falsemax_stack_itemsintegerNúmero máximo de artículos por pila. 0 = ilimitado.
0max_stack_density_kg_m2number · kg/m²Peso máximo de una pila por superficie de suelo. 0 = ilimitado.
0lock_rotationsbooleanMantiene la primera orientación que cabe en la altura del vehículo.
falsegroup_identical_binsbooleanTrata los vehículos idénticos como un único conjunto.
falsetime_limitnumber · sLímite superior del tiempo de cómputo para todo el trabajo. 0 = automático (con el tope de max_time_limit_seconds de GET /v1/limits). Al alcanzar el límite, se devuelve el mejor plan encontrado hasta ese momento. Solo pagas el tiempo de cómputo realmente usado.
0enforce_axleRequiere accesobooleanRechaza las colocaciones que sobrecargan un grupo de ejes, en los vehículos que incluyen los diez campos del modelo de ejes.
falseEjemplo de solicitud
curl -X POST "https://runner.cargoduo.com/v1/pack" \
-H "Authorization: Bearer $CARGODUO_API_KEY" \
-H "Idempotency-Key: order-1042-v1" \
-H "Content-Type: application/json" \
-d '{
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000
}
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": false
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright"
}
],
"options": {
"packing_mode": "auto"
}
}'const res = await fetch("https://runner.cargoduo.com/v1/pack", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CARGODUO_API_KEY}`,
"Idempotency-Key": "order-1042-v1",
"Content-Type": "application/json",
},
body: JSON.stringify({
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000
}
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": false
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright"
}
],
"options": {
"packing_mode": "auto"
}
}),
});
const data = await res.json();
console.log(res.status, data);import os
import requests
response = requests.post(
"https://runner.cargoduo.com/v1/pack",
headers={"Authorization": f"Bearer {os.environ['CARGODUO_API_KEY']}", "Idempotency-Key": "order-1042-v1"},
json={
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000,
},
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": False,
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright",
},
],
"options": {
"packing_mode": "auto",
},
},
)
print(response.status_code, response.json())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
body := strings.NewReader(`{
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000
}
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": false
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright"
}
],
"options": {
"packing_mode": "auto"
}
}`)
req, err := http.NewRequest("POST", "https://runner.cargoduo.com/v1/pack", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("CARGODUO_API_KEY"))
req.Header.Set("Idempotency-Key", "order-1042-v1")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.StatusCode, string(out))
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
String body = """
{
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000
}
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": false
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright"
}
],
"options": {
"packing_mode": "auto"
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://runner.cargoduo.com/v1/pack"))
.header("Authorization", "Bearer " + System.getenv("CARGODUO_API_KEY"))
.header("Idempotency-Key", "order-1042-v1")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("CARGODUO_API_KEY"));
client.DefaultRequestHeaders.Add("Idempotency-Key", "order-1042-v1");
var json = """
{
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000
}
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": false
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright"
}
],
"options": {
"packing_mode": "auto"
}
}
""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://runner.cargoduo.com/v1/pack")
{
Content = new StringContent(json, Encoding.UTF8, "application/json"),
};
var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");<?php
$payload = <<<'JSON'
{
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000
}
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": false
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright"
}
],
"options": {
"packing_mode": "auto"
}
}
JSON;
$ch = curl_init('https://runner.cargoduo.com/v1/pack');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CARGODUO_API_KEY'),
'Idempotency-Key: order-1042-v1',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $payload,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $response, PHP_EOL;require "net/http"
require "uri"
uri = URI("https://runner.cargoduo.com/v1/pack")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("CARGODUO_API_KEY")}"
request["Idempotency-Key"] = "order-1042-v1"
request["Content-Type"] = "application/json"
request.body = <<~'JSON'
{
"reference": "order-1042",
"vehicles": [
{
"id": "trailer",
"type": "trailer",
"name": "13.6 m trailer",
"length": 1360,
"width": 245,
"height": 270,
"max_weight": 24000
}
],
"items": [
{
"id": "pallet-eu",
"label": "Euro pallet",
"length": 120,
"width": 80,
"height": 140,
"weight": 450,
"quantity": 18,
"stackable": false
},
{
"id": "carton-a",
"label": "Carton A",
"length": 60,
"width": 40,
"height": 40,
"weight": 12,
"quantity": 40,
"rotation": "upright"
}
],
"options": {
"packing_mode": "auto"
}
}
JSON
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts response.code, response.bodyEjemplo de respuesta
{
"id": "job_4bK9mT2xQe7LpW1zRc8VdN3f",
"object": "job",
"status": "queued",
"reference": "order-1042",
"source": "api",
"created_at": "2026-10-19T09:12:03Z",
"started_at": null,
"finished_at": null,
"progress": {
"stage": "queued",
"vehicles_done": 0,
"placed_items": 0
},
"summary": {
"items_requested": 58,
"items_placed": 0,
"items_unplaced": 0,
"vehicles_used": 0,
"total_weight": 0,
"volume_utilization": 0,
"queue_ms": 0,
"compute_ms": 0
},
"cost": {
"credits": 0,
"reserved_credits": 1.11,
"rate_card_version": 1,
"breakdown": {
"base": 0,
"vehicles": 0,
"compute": 0,
"large_load": 0
}
},
"error": null,
"warnings": [],
"result_url": "https://runner.cargoduo.com/v1/jobs/job_4bK9mT2xQe7LpW1zRc8VdN3f/result",
"pdf_url": "",
"expires_at": "2026-11-02T09:12:03Z"
}Respuestas
200OKTrabajo terminado dentro del plazo de ?wait, con el resultado incluido. También la repetición idempotente de un trabajo terminado.
NombreTipoObligatorioDescripciónidstringobligatoriostringSíID del trabajo (job_…).
objectstringobligatoriostringSíSiempre
job.jobstatusstringobligatoriostringSíqueued→running→succeeded|failed|canceled.queuedrunningsucceededfailedcanceledreferencestringstringNoTu referencia, tomada de la solicitud.
sourcestringstringNoDónde se creó el trabajo.
apiplaygroundproject_idstringstringNoEl proyecto (prj_…) en el que un trabajo de POST /v1/projects/{id}/pack guarda su plan. Ausente en los demás trabajos.
created_atstringobligatoriostringSíMarca de tiempo RFC 3339.
started_atstring | nullstring | nullNoCuándo empezó el cálculo (RFC 3339) o
null.finished_atstring | nullstring | nullNoCuándo terminó el trabajo (RFC 3339) o
null.progressJobProgressJobProgressNoProgreso en tiempo real mientras está en cola o en curso.
stagestringstringNoFase actual, como
queued,running,finalizingodone. Solo informativa: basa tu lógica enJob.status.vehicles_doneintegerintegerNoVehículos completados hasta ahora.
placed_itemsintegerintegerNoUnidades de artículos colocadas hasta ahora.
summaryJobSummaryJobSummaryNoRecuentos y tiempos.
items_requestedintegerintegerNoTotal de unidades de artículos (suma de cantidades).
items_placedintegerintegerNoUnidades colocadas.
items_unplacedintegerintegerNoUnidades que no se pudieron colocar.
vehicles_usedintegerintegerNoVehículos que llevan al menos un artículo.
total_weightnumber · kgnumber · kgNoPeso cargado.
volume_utilizationnumbernumberNoOcupación media del volumen de los vehículos usados, 0–1.
queue_msintegerintegerNoTiempo de espera de un hueco de cómputo (no se factura).
compute_msintegerintegerNoTiempo de cómputo (se factura).
costJobCostJobCostNoCréditos cobrados (definitivos cuando el trabajo termina) y la reserva retenida mientras se ejecutaba.
creditsnumber · creditsnumber · creditsNoCréditos cobrados (0 hasta que termina el trabajo). Los trabajos fallidos no se cobran, salvo time_limit_exceeded, que se cobra como un trabajo cancelado.
reserved_creditsnumber · creditsnumber · creditsNoCréditos retenidos mientras el trabajo estaba en cola o en curso (el precio máximo posible). Se liberan al terminar.
rate_card_versionintegerintegerNoTarifa con la que se calcula el precio del trabajo.
breakdownCostBreakdownCostBreakdownNoDesglose del precio.
basenumber · creditsnumber · creditsNoTarifa por trabajo.
vehiclesnumber · creditsnumber · creditsNoPor vehículo cargado (no se cobra en trabajos cancelados ni en time_limit_exceeded).
computenumber · creditsnumber · creditsNoPor segundo de cómputo, prorrateado por milisegundo.
large_loadnumber · creditsnumber · creditsNoRecargo por cada tramo de 100 artículos (o fracción) por encima del umbral de carga grande.
errorJobError | nullJobError | nullNoPor qué falló o se canceló el trabajo;
nullen otro caso.codestringstringNoCódigo legible por máquina (consulta Errores).
messagestringstringNoExplicación en inglés.
warningsWarning[]Warning[]NoObservaciones no bloqueantes sobre la solicitud (también se repiten en el resultado).
codestringstringNoCódigo legible por máquina.
messagestringstringNoExplicación en inglés.
result_urlstringstringNoHaz una solicitud GET a esta URL para obtener el resultado completo cuando
statusseasucceeded.pdf_urlstringstringNoEnlace que, abierto en un navegador, genera el plan de carga en PDF (vistas 3D + pasos de carga). Válido hasta expires_at. Vacío tras la caducidad.
expires_atstringstringNoCuándo se eliminan los cuerpos de solicitud y de resultado y el enlace al PDF (RFC 3339). Los metadatos y los cargos del trabajo se conservan.
resultResultResultNoEl resultado completo, incluido solo si se pide (?include=result) o si POST /v1/pack?wait= terminó a tiempo.
job_idstringstringNoEl trabajo.
vehiclesResultVehicle[]ResultVehicle[]NoVehículos cargados en orden de carga (se omiten los vacíos).
indexintegerintegerNoPosición en el plan, empezando en 0.
vehicle_idstringstringNoEl ID de tu definición de vehículo (en un trabajo de proyecto: el ID del vehículo del proyecto, pv_…).
copyintegerintegerNoNúmero de copia de esa definición, empezando en 1 (quantity > 1 o añadido en modo auto).
auto_addedbooleanbooleanNoAñadido por
packing_modeautoademás de laquantityque indicaste.namestringstringNoNombre del vehículo.
typestringstringNoTipo de vehículo.
lengthnumber · cmnumber · cmNoLargo del espacio de carga.
widthnumber · cmnumber · cmNoAncho del espacio de carga.
heightnumber · cmnumber · cmNoAlto del espacio de carga.
max_weightnumber · kgnumber · kgNoLímite de carga útil.
items_placedintegerintegerNoUnidades en este vehículo.
total_weightnumber · kgnumber · kgNoPeso en este vehículo.
volume_utilizationnumbernumberNoVolumen usado / volumen del espacio de carga, 0–1.
weight_utilizationnumbernumberNototal_weight / max_weight, 0–1 (puede superar 1 con allow_overweight).
center_of_gravityPointPointNoCentro de gravedad de la carga (cm).
xnumber · cmnumber · cmNoynumber · cmnumber · cmNoznumber · cmnumber · cmNoplacementsPlacement[]Placement[]NoTodas las unidades de este vehículo.
item_idstringstringNoEl ID de tu definición de artículo (en un trabajo de proyecto: el ID del artículo, item_…).
instanceintegerintegerNoNúmero de unidad, empezando en 1, dentro de esa definición de artículo (único en todo el plan).
labelstringstringNoEtiqueta del artículo.
xnumber · cmnumber · cmNoPosición de la esquina mínima a lo largo de la longitud.
ynumber · cmnumber · cmNoAltura de la esquina mínima sobre el suelo.
znumber · cmnumber · cmNoPosición de la esquina mínima a lo ancho.
lengthnumber · cmnumber · cmNoTamaño a lo largo de x, tal como se colocó.
widthnumber · cmnumber · cmNoTamaño a lo largo de z, tal como se colocó.
heightnumber · cmnumber · cmNoTamaño a lo largo de y, tal como se colocó.
rotatedbooleanbooleanNoColocado con una orientación distinta de la definida.
orientationstringstringNoQué lado definido queda a lo largo de x, z e y:
lwh= tal como se definió,wlh= girado 90° sobre el eje vertical,lhw,hwl,whl,hlw= volcado sobre un lado.stepintegerintegerNoPaso de carga dentro del vehículo, empezando en 1 (carga en orden ascendente).
weightnumber · kgnumber · kgNoPeso unitario.
axle_loadsRequiere accesoAxleLoad[]AxleLoad[]NoCarga por eje (solo vehículos con datos de ejes).
namestringstringNoAxle 1,Axle 2… en el orden deaxle_positions.positionnumber · cmnumber · cmNoPosición del eje desde la parte delantera de la zona de carga.
loadnumber · kgnumber · kgNoCarga sobre el eje.
maxnumber · kgnumber · kgNoMáximo configurado (0 = sin máximo).
okbooleanbooleanNoload≤max(siempretruesi no hay máximo).unplacedUnplacedItem[]UnplacedItem[]NoUnidades que no se pudieron colocar, con el motivo.
item_idstringstringNoEl ID de tu definición de artículo.
instanceintegerintegerNoNúmero de unidad, empezando en 1.
labelstringstringNoEtiqueta del artículo.
reasonstringstringNoPor qué no se pudo colocar.
warningsWarning[]Warning[]NoObservaciones sobre el plan.
codestringstringNoCódigo legible por máquina.
messagestringstringNoExplicación en inglés.
pdf_urlstringstringNoEnlace que, abierto en un navegador, genera el plan en PDF.
expires_atstringstringNoCuándo se elimina este resultado (RFC 3339).
202AcceptedTrabajo aceptado (en cola o en curso).
NombreTipoObligatorioDescripciónidstringobligatoriostringSíID del trabajo (job_…).
objectstringobligatoriostringSíSiempre
job.jobstatusstringobligatoriostringSíqueued→running→succeeded|failed|canceled.queuedrunningsucceededfailedcanceledreferencestringstringNoTu referencia, tomada de la solicitud.
sourcestringstringNoDónde se creó el trabajo.
apiplaygroundproject_idstringstringNoEl proyecto (prj_…) en el que un trabajo de POST /v1/projects/{id}/pack guarda su plan. Ausente en los demás trabajos.
created_atstringobligatoriostringSíMarca de tiempo RFC 3339.
started_atstring | nullstring | nullNoCuándo empezó el cálculo (RFC 3339) o
null.finished_atstring | nullstring | nullNoCuándo terminó el trabajo (RFC 3339) o
null.progressJobProgressJobProgressNoProgreso en tiempo real mientras está en cola o en curso.
stagestringstringNoFase actual, como
queued,running,finalizingodone. Solo informativa: basa tu lógica enJob.status.vehicles_doneintegerintegerNoVehículos completados hasta ahora.
placed_itemsintegerintegerNoUnidades de artículos colocadas hasta ahora.
summaryJobSummaryJobSummaryNoRecuentos y tiempos.
items_requestedintegerintegerNoTotal de unidades de artículos (suma de cantidades).
items_placedintegerintegerNoUnidades colocadas.
items_unplacedintegerintegerNoUnidades que no se pudieron colocar.
vehicles_usedintegerintegerNoVehículos que llevan al menos un artículo.
total_weightnumber · kgnumber · kgNoPeso cargado.
volume_utilizationnumbernumberNoOcupación media del volumen de los vehículos usados, 0–1.
queue_msintegerintegerNoTiempo de espera de un hueco de cómputo (no se factura).
compute_msintegerintegerNoTiempo de cómputo (se factura).
costJobCostJobCostNoCréditos cobrados (definitivos cuando el trabajo termina) y la reserva retenida mientras se ejecutaba.
creditsnumber · creditsnumber · creditsNoCréditos cobrados (0 hasta que termina el trabajo). Los trabajos fallidos no se cobran, salvo time_limit_exceeded, que se cobra como un trabajo cancelado.
reserved_creditsnumber · creditsnumber · creditsNoCréditos retenidos mientras el trabajo estaba en cola o en curso (el precio máximo posible). Se liberan al terminar.
rate_card_versionintegerintegerNoTarifa con la que se calcula el precio del trabajo.
breakdownCostBreakdownCostBreakdownNoDesglose del precio.
basenumber · creditsnumber · creditsNoTarifa por trabajo.
vehiclesnumber · creditsnumber · creditsNoPor vehículo cargado (no se cobra en trabajos cancelados ni en time_limit_exceeded).
computenumber · creditsnumber · creditsNoPor segundo de cómputo, prorrateado por milisegundo.
large_loadnumber · creditsnumber · creditsNoRecargo por cada tramo de 100 artículos (o fracción) por encima del umbral de carga grande.
errorJobError | nullJobError | nullNoPor qué falló o se canceló el trabajo;
nullen otro caso.codestringstringNoCódigo legible por máquina (consulta Errores).
messagestringstringNoExplicación en inglés.
warningsWarning[]Warning[]NoObservaciones no bloqueantes sobre la solicitud (también se repiten en el resultado).
codestringstringNoCódigo legible por máquina.
messagestringstringNoExplicación en inglés.
result_urlstringstringNoHaz una solicitud GET a esta URL para obtener el resultado completo cuando
statusseasucceeded.pdf_urlstringstringNoEnlace que, abierto en un navegador, genera el plan de carga en PDF (vistas 3D + pasos de carga). Válido hasta expires_at. Vacío tras la caducidad.
expires_atstringstringNoCuándo se eliminan los cuerpos de solicitud y de resultado y el enlace al PDF (RFC 3339). Los metadatos y los cargos del trabajo se conservan.
resultResultResultNoEl resultado completo, incluido solo si se pide (?include=result) o si POST /v1/pack?wait= terminó a tiempo.
job_idstringstringNoEl trabajo.
vehiclesResultVehicle[]ResultVehicle[]NoVehículos cargados en orden de carga (se omiten los vacíos).
indexintegerintegerNoPosición en el plan, empezando en 0.
vehicle_idstringstringNoEl ID de tu definición de vehículo (en un trabajo de proyecto: el ID del vehículo del proyecto, pv_…).
copyintegerintegerNoNúmero de copia de esa definición, empezando en 1 (quantity > 1 o añadido en modo auto).
auto_addedbooleanbooleanNoAñadido por
packing_modeautoademás de laquantityque indicaste.namestringstringNoNombre del vehículo.
typestringstringNoTipo de vehículo.
lengthnumber · cmnumber · cmNoLargo del espacio de carga.
widthnumber · cmnumber · cmNoAncho del espacio de carga.
heightnumber · cmnumber · cmNoAlto del espacio de carga.
max_weightnumber · kgnumber · kgNoLímite de carga útil.
items_placedintegerintegerNoUnidades en este vehículo.
total_weightnumber · kgnumber · kgNoPeso en este vehículo.
volume_utilizationnumbernumberNoVolumen usado / volumen del espacio de carga, 0–1.
weight_utilizationnumbernumberNototal_weight / max_weight, 0–1 (puede superar 1 con allow_overweight).
center_of_gravityPointPointNoCentro de gravedad de la carga (cm).
xnumber · cmnumber · cmNoynumber · cmnumber · cmNoznumber · cmnumber · cmNoplacementsPlacement[]Placement[]NoTodas las unidades de este vehículo.
item_idstringstringNoEl ID de tu definición de artículo (en un trabajo de proyecto: el ID del artículo, item_…).
instanceintegerintegerNoNúmero de unidad, empezando en 1, dentro de esa definición de artículo (único en todo el plan).
labelstringstringNoEtiqueta del artículo.
xnumber · cmnumber · cmNoPosición de la esquina mínima a lo largo de la longitud.
ynumber · cmnumber · cmNoAltura de la esquina mínima sobre el suelo.
znumber · cmnumber · cmNoPosición de la esquina mínima a lo ancho.
lengthnumber · cmnumber · cmNoTamaño a lo largo de x, tal como se colocó.
widthnumber · cmnumber · cmNoTamaño a lo largo de z, tal como se colocó.
heightnumber · cmnumber · cmNoTamaño a lo largo de y, tal como se colocó.
rotatedbooleanbooleanNoColocado con una orientación distinta de la definida.
orientationstringstringNoQué lado definido queda a lo largo de x, z e y:
lwh= tal como se definió,wlh= girado 90° sobre el eje vertical,lhw,hwl,whl,hlw= volcado sobre un lado.stepintegerintegerNoPaso de carga dentro del vehículo, empezando en 1 (carga en orden ascendente).
weightnumber · kgnumber · kgNoPeso unitario.
axle_loadsRequiere accesoAxleLoad[]AxleLoad[]NoCarga por eje (solo vehículos con datos de ejes).
namestringstringNoAxle 1,Axle 2… en el orden deaxle_positions.positionnumber · cmnumber · cmNoPosición del eje desde la parte delantera de la zona de carga.
loadnumber · kgnumber · kgNoCarga sobre el eje.
maxnumber · kgnumber · kgNoMáximo configurado (0 = sin máximo).
okbooleanbooleanNoload≤max(siempretruesi no hay máximo).unplacedUnplacedItem[]UnplacedItem[]NoUnidades que no se pudieron colocar, con el motivo.
item_idstringstringNoEl ID de tu definición de artículo.
instanceintegerintegerNoNúmero de unidad, empezando en 1.
labelstringstringNoEtiqueta del artículo.
reasonstringstringNoPor qué no se pudo colocar.
warningsWarning[]Warning[]NoObservaciones sobre el plan.
codestringstringNoCódigo legible por máquina.
messagestringstringNoExplicación en inglés.
pdf_urlstringstringNoEnlace que, abierto en un navegador, genera el plan en PDF.
expires_atstringstringNoCuándo se elimina este resultado (RFC 3339).
400Bad request
invalid_jsonidempotency_key_invalidinvalid_jsonEl cuerpo no es JSON válido o un campo tiene un tipo incorrecto.idempotency_key_invalidLa cabecera Idempotency-Key tiene más de 128 caracteres.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
401Unauthorized
unauthorizedkey_revokedkey_expiredunauthorizedClave de API ausente, mal formada o desconocida.key_revokedLa clave se ha revocado.key_expiredLa clave ha superado su fecha de caducidad.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
402Payment required
insufficient_creditsinsufficient_creditsLos créditos disponibles no cubren el coste mínimo posible de este trabajo.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
403Forbidden
ip_not_allowedsubscription_inactiveaccount_inactivescope_missingip_not_allowedLa IP de origen no está en la lista de IP permitidas de la clave.subscription_inactiveLa organización no tiene ninguna suscripción activa que incluya la API.account_inactiveLa organización está suspendida o no tiene ningún propietario con la cuenta activa.scope_missingA la clave le falta un permiso que requiere este endpoint.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
413Payload too large
payload_too_largepayload_too_largeEl cuerpo de la solicitud supera los 10 MB.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
422Unprocessable entity
validation_failedvalidation_failedLa solicitud es JSON bien formado, pero describe un trabajo no válido. details[] enumera todos los problemas.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
429Too many requests
too_many_jobsrate_limitedtoo_many_jobsLa organización ya tiene el número máximo de trabajos en cola + en curso.rate_limitedDemasiadas solicitudes en el minuto, la hora o el día en curso (por clave o por organización), o más de 60 autenticaciones fallidas por minuto desde tu dirección IP.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
500Internal server error
internal_errorinternal_errorAlgo ha fallado por nuestra parte.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.
503Service unavailable
api_disabledapi_disabledLa API está desactivada temporalmente (mantenimiento) o deshabilitada para la organización.
Todos los códigos de errorNombreTipoObligatorioDescripciónerrorErrorBodyobligatorioErrorBodySícodestringobligatoriostringSíCódigo legible por máquina (snake_case). Basa tu lógica en este campo, nunca en
message.messagestringobligatoriostringSíExplicación en inglés.
request_idstringobligatoriostringSíIgual que la cabecera X-Request-Id. Indícalo al contactar con el soporte.
detailsErrorDetail[]ErrorDetail[]NoProblemas por campo (
validation_failed).pathstringstringNoRuta JSON del campo erróneo, p. ej., items[3].length.
codestringstringNorequired,invalid_value,out_of_range,duplicate_id,unknown_vehicle,unknown_template,type_not_allowed,unknown_group,does_not_fit,too_many_items,too_many_vehicles,unknown_field,invalid_json.messagestringstringNoExplicación en inglés.