Packing API

Geben Sie Fracht auf und erhalten Sie einen optimierten, physikalisch validierten Ladeplan — mit Positionen, Lademetern, Linearfuß und abgerechneten Palettenplätzen. Derselbe Algorithmus wie in der App, kontinuierlich gegen reale Disponenten-Layouts validiert. Sandbox-Zugang in jedem Tarif; Produktionszugang im Enterprise-Tarif.

Schnellstart

  1. Melden Sie sich an → klicken Sie auf Ihren Namen → API → generieren Sie einen Schlüssel.
  2. Senden Sie einen Pack-Job ab (dieser läuft in der Sandbox — kostenlos in jedem Tarif):
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-..."
}

Fragen Sie die status_url ab (gleicher Auth-Header), bis status "done" ist:

{
  "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/..."
  }
}

Endpunkte

POST /api/v1/pack

Validiert und stellt einen Pack-Job in die Warteschlange. Gibt 202 mit einer job_id zurück. Unterstützt einen Idempotency-Key-Header — Wiederholungen mit demselben Schlüssel geben den ursprünglichen Job zurück, statt doppelt zu packen.

GET /api/v1/jobs/{id}

Job-Status und, wenn abgeschlossen, das vollständige Ergebnis. Ergebnisse werden 30 Tage lang gespeichert; Produktionspläne bleiben dauerhaft in Ihrem Arbeitsbereich.

GET /api/v1/openapi.json

Der maschinenlesbare OpenAPI 3.1-Vertrag — importieren Sie ihn in Postman, Code-Generatoren oder nutzen Sie ihn mit Ihrem KI-Coding-Tool. Fahrzeugcodes werden aus dem Live-System übernommen, sodass er immer aktuell ist. Spec öffnen ↗

Antwortfelder

Das result-Objekt eines abgeschlossenen Jobs:

FeldTypBeschreibung
placed_count / unplaced_countintegerAnzahl der platzierten / nicht platzierten Artikel.
units"metric" | "imperial"Die Einheiten, in denen alle nachfolgenden Zahlen angegeben sind (entspricht der Anfrage).
metrics.ldm_mnumberLademeter — die Ausdehnung des Ladungsblocks (max. Ende − min. Anfang).
metrics.linear_ftnumberDieselbe Ausdehnung in Linearfuß (US-LTL).
metrics.span_mmintegerDie Ausdehnung in mm, immer metrisch.
metrics.pallet_positions_eurinteger | nullAbgerechnete EUR-Palettenpositionen. null, wenn das Layout zu groß für eine Messung ist.
metrics.total_weight_kgnumberPlatziertes Gewicht, immer in kg.
metrics.overlapsintegerSich durchdringende Paare — immer 0 bei einem gültigen Layout.
items[].placedbooleanOb der Artikel im Layout platziert wurde.
items[].x / y / znumber | nullPosition in den Anfrageeinheiten: x vom Türende, y von der linken Wand, z vom Boden. Alle drei sind null, wenn placed false ist.
items[].rotation_deg / tilt_deg0 | 90Ausrichtung: Drehung um die vertikale Achse; tilt = seitlich abgelegt.
items[].length / width / height / weightnumberDer Artikel wie in der Anfrage übermittelt, in den Anfrageeinheiten.
plan_urlstring | nullDer erstellte Plan in der App. null für Sandbox-Jobs.

Versionierung & Stabilität

Der Vertrag ist in der Pfadangabe (/api/v1/) versioniert. Innerhalb von v1 sind Änderungen nur additiv — neue optionale Anfragefelder, neue Antwortfelder, neue Fahrzeugcodes und Fehlercodes können hinzugefügt werden, und Clients sollten Felder ignorieren, die sie nicht kennen. Bestehende Felder ändern niemals ihre Bedeutung oder ihren Typ, und nichts wird entfernt. Eine Breaking Change führt zu einem neuen Versionspfad, wobei v1 mindestens 12 Monate parallel gepflegt und die Abschaltung per E-Mail an jeden Arbeitsbereich mit einem aktiven Schlüssel angekündigt wird.

Anfragefelder

FeldTypBeschreibung
vehiclestringEin Fahrzeugcode aus den untenstehenden Tabellen. Oder geben Sie {customVehicleId} an (ein Fahrzeug aus Ihrer Arbeitsbereichsflotte).
objective"ldm" | "pallets"Minimierung der Lademeter oder der abgerechneten Palettenpositionen. Standardmäßig "ldm".
units"metric" | "imperial"Wie Artikelabmessungen und -gewichte gelesen UND zurückgegeben werden: mm/kg (Standard) oder in/lb. Positionen in der Antwort folgen denselben Einheiten.
itemsarray, requiredDas Frachtmanifest (Felder siehe unten).
sandboxbooleanTestmodus: vollständiges Ergebnis, nichts wird gespeichert. Verfügbar in jedem Tarif.
namestringName des Plans (Produktionsmodus).
ldm_limit_mnumberBeschränkung der Ladung auf die ersten N Lademeter (LKW).
budget_msnumberOptimierungszeitbudget (Produktion; Standard 30000, Maximum 300000).
callback_urlhttps URLWird per POST mit dem Ergebnis aufgerufen, wenn der Job abgeschlossen ist, signiert (siehe Webhooks).

Artikelfelder

FeldTypBeschreibung
length / width / heightnumber, requiredArtikelabmessungen, gelesen in den Einheiten der Anfrage (Standard mm, Zoll mit "units": "imperial").
weightnumber, requiredArtikelgewicht (Standard kg, lb mit "units": "imperial").
quantityinteger, default 1Wird in einzelne Einheiten aufgelöst.
namestring, optionalWird im Plan und in der Antwort angezeigt.
stackableboolean, default trueAndere Fracht darf auf diesem Artikel gestapelt werden.
max_stacknumber, optionalMaximales Gewicht, das dieser Artikel tragen kann (gleiche Einheiten wie Gewicht).
fragileboolean, default falseZerbrechliche Artikel werden nur in den oberen Lagen platziert.
tiltableboolean, default trueDarf der Artikel seitlich abgelegt werden.
destination_stopinteger, default 1Lieferstopp für Mehrstopp-LIFO-Ladung.

Fahrzeugcodes

Generiert aus den Live-Engine-Spezifikationen. Benutzerdefinierte Fahrzeuge aus Ihrer Arbeitsbereichsflotte funktionieren über custom_vehicle_id.

LKW & Anhänger

CodeFahrzeugInnenmaße (L×B×H)Nutzlast
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

Container

CodeContainerInnenmaße (L×B×H)Nutzlast
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

Zugriffsebenen & Limits

Sandbox (jeder Tarif)Produktion (Enterprise)
Aufrufe25 erfolgreiche / Monat5.000 erfolgreiche Packungen / Monat
Artikel pro Manifest205,000
Gleichzeitige Jobs110
Optimierungsbudget10 s30 s Standard, bis zu 300 s
PersistenzNichts gespeichertJeder Pack-Vorgang erstellt einen echten Plan in Ihrem Arbeitsbereich

Nur erfolgreiche Packungen werden gezählt – fehlgeschlagene Validierungen und Jobs belasten das Kontingent nicht. Beide Zähler werden am 1. (UTC) zurückgesetzt. Sandbox-Ergebnisse sind vollständig und uneingeschränkt – die Limits sind die Grenze, nicht die Ausgabe. Brauchen Sie mehr als 5.000 Packungen pro Monat? Sprechen Sie mit uns über Volumen- und OEM-Preise.

Webhooks

Geben Sie callback_url an, um das Ergebnis per POST zu erhalten, wenn der Job abgeschlossen ist. Jeder Callback enthält eine X-Hansatic-Signature: ein HMAC-SHA256 der Rohdaten mit dem Webhook-Geheimnis Ihres Schlüssels (wird einmalig bei der Schlüsselerstellung angezeigt). Überprüfen Sie diese:

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));
}

Die Zustellung erfolgt in einem Versuch mit 5s Timeout — die status_url bleibt immer die Quelle der Wahrheit.

Fehler

Alle Fehler haben die Form { "error": { "code", "message", ... } } — maschinenlesbarer Code, menschenlesbare Nachricht und field, wenn ein bestimmtes Eingabefeld fehlerhaft ist.

CodeHTTPBedeutung
invalid_key401Fehlender, falsch formatierter oder widerrufener API-Schlüssel.
invalid_json400Der Body ist kein gültiges JSON.
invalid_vehicle400Unbekannter Fahrzeugcode / {customVehicleId}.
invalid_items400Ein Artikelfeld fehlt, ist nicht numerisch oder außerhalb des gültigen Bereichs.
suspicious_dimensions400Alle Abmessungen unter 100 mm — vermutlich Zoll als mm gesendet. Geben Sie "units": "imperial" an.
invalid_units400units muss "metric" oder "imperial" sein.
invalid_objective400objective muss "ldm" oder "pallets" sein.
invalid_callback400callback_url muss https sein.
too_many_items400Manifest überschreitet das Artikel-Limit für Ihre Zugriffsebene.
upgrade_required402Produktionsmodus erfordert den Enterprise-Tarif. Nutzen Sie die Sandbox oder upgraden Sie.
sandbox_limit_reached402Monatliches Sandbox-Kontingent aufgebraucht — wird am 1. zurückgesetzt.
quota_exceeded402Monatliches Produktionskontingent von 5.000 Packungen aufgebraucht – wird am 1. zurückgesetzt. Bei höherem Volumen: Kontaktieren Sie uns.
too_many_jobs429Limit für gleichzeitige Jobs erreicht. Fragen Sie laufende Jobs ab und versuchen Sie es erneut.
not_found404Kein solcher Job für diesen Arbeitsbereich vorhanden.

Fragen, höhere Limits oder ein benötigter Connector (Zapier, Excel, MCP)? hello@hansatic.com