API de Carregamento

Envie a carga e receba um plano de carregamento otimizado e fisicamente válido — posições, metros de carga, pés lineares e posições de paletes faturadas. O mesmo mecanismo usado no aplicativo, validado continuamente com layouts reais de despachantes. Acesso ao sandbox em todos os planos; acesso em produção no plano Enterprise.

Comece rapidamente

  1. Faça login → clique no seu nome → API → gere uma chave.
  2. Envie um trabalho de carregamento (este é executado no sandbox — gratuito em todos os planos):
curl -X POST https://hansatic.com/api/v1/pack \
  -H "Authorization: Bearer hk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "vehicle": "CURTAINSIDER_136",
    "objective": "ldm",
    "sandbox": true,
    "items": [{
      "name": "Machine crate",
      "length": 2300, "width": 750, "height": 1400,
      "weight": 300, "quantity": 7,
      "stackable": false, "tiltable": false
    }]
  }'
{
  "job_id": "5e3617d1-abe4-4549-b7e6-d18c6baf814f",
  "status": "queued",
  "sandbox": true,
  "status_url": "https://hansatic.com/api/v1/jobs/5e3617d1-..."
}

Consulte o status_url (com o mesmo cabeçalho de autenticação) até que status seja "done":

{
  "job_id": "5e3617d1-...",
  "status": "done",
  "result": {
    "placed_count": 7,
    "unplaced_count": 0,
    "units": "metric",
    "metrics": {
      "ldm_m": 5.25,
      "span_mm": 5250,
      "linear_ft": 17.2,
      "pallet_positions_eur": 14,
      "total_weight_kg": 2100,
      "overlaps": 0
    },
    "items": [
      { "id": "...", "name": "Machine crate", "placed": true,
        "x": 8370, "y": 0, "z": 0,
        "rotation_deg": 90, "tilt_deg": 0, "...": "..." }
    ],
    "plan_url": "https://hansatic.com/en/app/plans/..."
  }
}

Endpoints

POST /api/v1/pack

Valida e enfileira um trabalho de carregamento. Retorna 202 com um job_id. Suporta o cabeçalho Idempotency-Key — novas tentativas com a mesma chave retornam o trabalho original em vez de processar o carregamento duas vezes.

GET /api/v1/jobs/{id}

Status do trabalho e, quando concluído, o resultado completo. Os resultados são mantidos por 30 dias; nos planos de produção, ficam armazenados permanentemente no seu workspace.

GET /api/v1/openapi.json

O contrato OpenAPI 3.1 legível por máquina — importe-o no Postman, geradores de código ou aponte sua ferramenta de IA de programação para ele. Os códigos de veículos são injetados a partir do mecanismo ativo, garantindo que esteja sempre atualizado. Abra a especificação ↗

Campos da resposta

O objeto result de um trabalho concluído:

CampoTipoDescrição
placed_count / unplaced_countintegerQuantos itens foram carregados / não couberam.
units"metric" | "imperial"As unidades em que todos os valores numéricos abaixo são expressos (ecoam a solicitação).
metrics.ldm_mnumberMetros de carga — a extensão do bloco de carga (máximo final − mínimo inicial).
metrics.linear_ftnumberA mesma extensão em pés lineares (LTL nos EUA).
metrics.span_mmintegerA extensão em mm, sempre métrica.
metrics.pallet_positions_eurinteger | nullPosições de paletes EUR faturadas. null quando o layout é grande demais para ser medido.
metrics.total_weight_kgnumberPeso carregado, sempre em kg.
metrics.overlapsintegerPares com interpenetração — sempre 0 em um layout válido.
items[].placedbooleanSe o item foi incluído no layout.
items[].x / y / znumber | nullPosição nas unidades da solicitação: x a partir da extremidade da porta, y a partir da parede esquerda, z a partir do chão. Todos os três são null quando placed é false.
items[].rotation_deg / tilt_deg0 | 90Orientação: rotação em torno do eixo vertical; tilt = deitado de lado.
items[].length / width / height / weightnumberO item conforme enviado, ecoado nas unidades da solicitação.
plan_urlstring | nullO plano criado no aplicativo. null para trabalhos no sandbox.

Versionamento e estabilidade

O contrato é versionado no caminho (/api/v1/). Dentro da v1, as alterações são apenas aditivas — novos campos opcionais na solicitação, novos campos na resposta, novos códigos de veículos e códigos de erro podem ser adicionados, e os clientes devem ignorar campos que não reconhecem. Campos existentes nunca mudam de significado ou tipo, e nada é removido. Uma mudança incompatível resulta em um novo caminho de versão, com a v1 mantida em paralelo por pelo menos 12 meses e aviso de descontinuação enviado por e-mail para todos os workspaces com uma chave ativa.

Campos da solicitação

CampoTipoDescrição
vehiclestringUm código de veículo das tabelas abaixo. Ou passe {customVehicleId} (um veículo da frota do seu workspace).
objective"ldm" | "pallets"Minimizar metros de carga ou minimizar posições de paletes faturadas. Padrão "ldm".
units"metric" | "imperial"Como as dimensões e pesos dos itens são interpretados E retornados: mm/kg (padrão) ou pol/lb. As posições na resposta seguem as mesmas unidades.
itemsarray, requiredA lista de carga (campos abaixo).
sandboxbooleanModo de teste: resultado completo, nada é persistido. Disponível em todos os planos.
namestringNome do plano (modo produção).
ldm_limit_mnumberRestringe a carga aos primeiros N metros de carga (caminhões).
budget_msnumberOrçamento de tempo de otimização (produção; padrão 30000, máximo 300000).
callback_urlhttps URLEnvia o resultado via POST quando o trabalho for concluído, assinado (veja Webhooks).

Campos dos itens

CampoTipoDescrição
length / width / heightnumber, requiredDimensões do item, interpretadas nas unidades da solicitação (mm por padrão, polegadas com "units": "imperial").
weightnumber, requiredPeso do item (kg por padrão, lb com "units": "imperial").
quantityinteger, default 1Expande para unidades individuais.
namestring, optionalExibido no plano e na resposta.
stackableboolean, default truePermite que outros itens sejam colocados em cima deste.
max_stacknumber, optionalPeso máximo que este item pode suportar em cima (mesmas unidades do peso).
fragileboolean, default falseItens frágeis são colocados apenas nas camadas superiores.
tiltableboolean, default trueSe o item pode ser colocado de lado.
destination_stopinteger, default 1Parada de entrega para carregamento LIFO em múltiplas paradas.

Códigos de veículos

Gerados a partir das especificações do mecanismo ativo. Veículos personalizados da frota do seu workspace funcionam via custom_vehicle_id.

Caminhões e reboques

CódigoVeículoInterior (C×L×A)Carga útil
CURTAINSIDER_13613.6m Curtainsider13.62 × 2.48 × 2.70 m24 t
BOX_13613.6m Box Trailer13.62 × 2.46 × 2.68 m24 t
MEGA_13613.6m Mega Trailer13.62 × 2.48 × 3.00 m22.5 t
MEGA_CURTAIN_13613.6m Mega Curtainsider13.62 × 2.48 × 3.00 m22 t
FLATBED_13613.6m Flatbed13.62 × 2.48 × 3.00 m25 t
REEFER_13613.6m Reefer13.32 × 2.44 × 2.54 m22 t
CURTAINSIDER_757.5m City Curtainsider7.50 × 2.48 × 2.70 m12 t
SWAPBODY_7157.15m Swap Body7.15 × 2.48 × 2.70 m12 t
SWAPBODY_7457.45m Swap Body7.45 × 2.48 × 2.70 m12 t
DRY_VAN_5353ft Dry Van16.15 × 2.59 × 2.74 m20 t
FLATBED_5353ft Flatbed16.15 × 2.59 × 3.66 m22 t
REEFER_5353ft Reefer15.85 × 2.46 × 2.59 m18.5 t
CURTAINSIDER_125_CN12.5m Curtainsider (CN)12.50 × 2.50 × 2.80 m27 t
FLATBED_40_IN40ft Flatbed (IN)12.19 × 2.50 × 3.50 m26 t
BOX_138_BR13.8m Box Van (BR)13.80 × 2.50 × 2.90 m28 t
CURTAINSIDER_12_ZA12m Curtainsider (ZA)12.00 × 2.48 × 2.70 m28 t

Contêineres

CódigoContêinerInterior (C×L×A)Carga útil
20DC20' Dry Container5.89 × 2.35 × 2.39 m21.727 t
20HC20' High Cube5.89 × 2.35 × 2.70 m21.58 t
40DC40' Dry Container12.03 × 2.35 × 2.39 m26.63 t
40HC40' High Cube12.03 × 2.35 × 2.70 m26.58 t
45HC45' High Cube13.56 × 2.35 × 2.70 m25.68 t
20OT20' Open Top5.89 × 2.35 × 2.39 m21.64 t
40OT40' Open Top12.03 × 2.35 × 2.39 m26.58 t
20RF20' Reefer5.44 × 2.29 × 2.27 m21 t
40RF40' Reefer11.58 × 2.29 × 2.21 m25.6 t
40RFHC40' Reefer High Cube11.58 × 2.29 × 2.54 m25.88 t
53DC53' Domestic16.15 × 2.59 × 2.90 m26 t

Níveis de acesso e limites

Sandbox (todos os planos)Produção (Enterprise)
Chamadas25 bem-sucedidas / mês5.000 carregamentos bem-sucedidos / mês
Itens por lista de carga205,000
Trabalhos simultâneos110
Orçamento de otimização10 s30 s padrão, até 300 s
PersistênciaNada é armazenadoCada carregamento cria um plano real no seu workspace

Apenas carregamentos bem-sucedidos são contabilizados — validações e jobs com falha nunca são cobrados na cota. Ambos os contadores são reiniciados no dia 1º (UTC). Os resultados da sandbox são completos e sem limitações — os limites são a barreira, não o resultado. Precisa de mais de 5.000 carregamentos por mês? Fale conosco sobre preços para volumes elevados e licenciamento OEM.

Webhooks

Passe callback_url para receber o resultado via POST quando o trabalho for concluído. Cada callback inclui X-Hansatic-Signature: um HMAC-SHA256 do corpo bruto com o segredo do webhook da sua chave (exibido uma vez na criação da chave). Verifique-o:

const crypto = require('crypto');

function verify(rawBody, signatureHeader, webhookSecret) {
  const expected = crypto.createHmac('sha256', webhookSecret)
    .update(rawBody).digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(signatureHeader));
}

A entrega é feita em uma única tentativa com timeout de 5s — o status_url permanece sempre como a fonte da verdade.

Erros

Todos os erros seguem o formato { "error": { "code", "message", ... } } — código legível por máquina, mensagem legível por humanos e field quando um campo específico da entrada está incorreto.

CódigoHTTPSignificado
invalid_key401Chave de API ausente, malformada ou revogada.
invalid_json400O corpo não é um JSON válido.
invalid_vehicle400Código de veículo ou {customVehicleId} desconhecido.
invalid_items400Um campo de item está ausente, não é numérico ou está fora do intervalo válido.
suspicious_dimensions400Todas as dimensões abaixo de 100mm — provavelmente polegadas enviadas como mm. Passe "units": "imperial".
invalid_units400units deve ser "metric" ou "imperial".
invalid_objective400objective deve ser "ldm" ou "pallets".
invalid_callback400callback_url deve ser https.
too_many_items400A lista de carga excede o limite de itens para o seu nível de acesso.
upgrade_required402O modo produção requer o plano Enterprise. Use o sandbox ou faça upgrade.
sandbox_limit_reached402Cota mensal do sandbox esgotada — reinicia no dia 1º.
quota_exceeded402Cota mensal de 5.000 carregamentos atingida — reinicia no dia 1º. Para volumes maiores: entre em contato.
too_many_jobs429Limite de trabalhos simultâneos atingido. Consulte os trabalhos em execução e tente novamente.
not_found404Nenhum trabalho encontrado para este workspace.

Dúvidas, limites maiores ou um conector que você precisa (Zapier, Excel, MCP)? hello@hansatic.com