Zum Inhalt springen
LOGICAR Entwickler Suchen

#Angebote

Auf dieser Seite

Manche Fälle bepreist LOGICAR nicht nach Ihrer Vereinbarung, sondern mit einem eigenen Angebot — etwa eine Strecke außerhalb der vereinbarten Standardfälle. Dann entsteht zuerst eine Anfrage, LOGICAR erstellt das Angebot, und erst nach der Annahme wird daraus ein Auftrag.

#Ein Angebot entsteht

Auf zwei Wegen:

  • POST /orders — braucht der Fall nach Ihrer Vereinbarung ein Angebot, antwortet die Schnittstelle mit 202 und kind: "REQUEST" (Auftrag anlegen).
  • POST /quotes (Recht quotes:write) — Sie fordern ausdrücklich ein Angebot an, auch wo Ihre Vereinbarung den Fall sonst direkt bepreisen würde. Der Rumpf ist derselbe wie bei POST /orders; die Antwort ist das Angebot mit Status REQUESTED (HTTP 202). Wie beim Auftrag gilt der Idempotency-Key, ohne ihn die externalOrderId (Wiederholungen).

In beiden Fällen ist die Kennung des Angebots die der Anfrage: dieselbe id für GET /orders/{id} und GET /quotes/{id}. GET /quotes/{id} nimmt auch die Anfragenummer (TR-…) und die Angebotsnummer (AN-…).

#Stand

StatusBedeutungEreignis
REQUESTEDAngefragt — LOGICAR erstellt das Angebot.
OFFEREDDas Angebot liegt vor und kann angenommen oder abgelehnt werden.
ACCEPTEDAngenommen; der Auftrag entsteht.
ORDEREDAus dem Angebot ist ein Auftrag geworden (order).order.created
DECLINEDVom Auftraggeber abgelehnt.order.rejected
EXPIREDAbgelaufen, ohne angenommen zu werden.
REJECTEDVon LOGICAR abgelehnt oder zurückgezogen, oder die Anfrage wurde zurückgezogen.order.rejected

Solange die Anfrage auf das Angebot wartet, zeigt GET /orders/{id} sie als kind: "REQUEST" mit den Ständen QUOTE_REQUIRED, QUOTE_SENT und QUOTE_ACCEPTED (Status). Beträge, Fassung und Annahme zeigt nur GET /quotes/{id}.

Eigene Ereignisse für Angebote gibt es nicht. Ihr Webhook-Endpunkt bekommt order.created, sobald aus dem Angebot ein Auftrag wird, und order.rejected, wenn die Anfrage endet. Ob ein Angebot vorliegt, fragen Sie mit GET /quotes/{id} ab.

#Das Angebot lesen

GET /quotes/{id} (Recht quotes:read) zeigt, sobald das Angebot vorliegt (OFFERED), genau die versendete Fassung:

json
{
  "id": "3f2a9c1e-7b4d-4e8a-9c2f-1a2b3c4d5e6f",
  "requestNumber": "TR-2026-00821",
  "quoteNumber": "AN-2026-00412",
  "externalOrderId": "4500019283",
  "status": "OFFERED",
  "version": 1,
  "validUntil": "2026-10-07T21:59:59.000Z",
  "sentAt": "2026-09-23T13:40:00.000Z",
  "currency": "EUR",
  "amount": {
    "net": 690,
    "vat": 131.1,
    "gross": 821.1
  },
  "items": [
    {
      "position": 1,
      "description": "Überführung Hamburg → München, Fahrer",
      "quantity": 1,
      "unitPriceNet": 640,
      "totalNet": 640,
      "vatRate": 19
    },
    {
      "position": 2,
      "description": "Kurzzeitkennzeichen",
      "quantity": 1,
      "unitPriceNet": 50,
      "totalNet": 50,
      "vatRate": 19
    }
  ],
  "conditions": "Abholung innerhalb von drei Werktagen nach Annahme.",
  "document": {
    "fileName": "AN-2026-00412-v1.pdf",
    "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "downloadUrl": "/api/v1/extern/quotes/3f2a9c1e-7b4d-4e8a-9c2f-1a2b3c4d5e6f/document"
  },
  "acceptance": {
    "viaApi": true,
    "acceptedAt": null,
    "channel": null
  },
  "declinedAt": null,
  "order": null,
  "sandbox": false,
  "createdAt": "2026-09-23T10:15:00.000Z",
  "updatedAt": "2026-09-23T13:40:00.000Z"
}
  • version — die Fassung. Wird nachverhandelt, entsteht eine neue; bis sie versendet ist, steht das Angebot wieder auf REQUESTED, ohne Beträge.
  • amount und items — wie im Angebotsdokument, vatRate in Prozent. Was LOGICAR im Dokument zu einer Zeile zusammenfasst, steht auch hier als eine Zeile.
  • validUntil — bis dahin lässt es sich annehmen; danach steht es auf EXPIRED.
  • document — das Angebot als PDF: GET /quotes/{id}/document. Prüfen Sie nach dem Herunterladen die sha256.
  • acceptance.viaApi — ob Ihr System selbst annehmen darf, siehe unten.

#Annehmen

POST /quotes/{id}/accept (Recht quotes:write) nimmt das Angebot verbindlich an — nur, wenn Ihre Vereinbarung mit LOGICAR das vorsieht (acceptance.viaApi: true). Eine Annahme über die Schnittstelle ist eine Erklärung Ihres Systems, ohne Unterschrift und ohne Einmalcode; deshalb muss sie vereinbart sein. Sonst antwortet die Schnittstelle 403 QUOTE_ACCEPTANCE_NOT_AGREED, und ein Mensch nimmt über den Link in der Angebotsmail an — der Auftrag entsteht dann genauso, und acceptance.channel sagt LINK.

Nennen Sie die Fassung, die Ihr System gelesen hat. Angenommen wird genau diese:

http
POST /api/v1/extern/quotes/3f2a9c1e-7b4d-4e8a-9c2f-1a2b3c4d5e6f/accept
Authorization: Bearer <Token>
Idempotency-Key: 0b8e6f1c-4b1d-4a36-9d0e-2f1a7c5b9e11
Content-Type: application/json

{ "version": 1 }

Mit der Annahme gilt dieser Wortlaut:

Das System des Auftraggebers nimmt das Angebot in der genannten Fassung über die Schnittstelle verbindlich an und beauftragt die darin beschriebene Leistung zum genannten Preis. Die Annahme gilt als Erklärung des Auftraggebers, so wie es seine Vereinbarung mit LOGICAR vorsieht; mit ihr kommt ein kostenpflichtiger Vertrag zustande. Es gelten die Angebotsbedingungen und die Allgemeinen Geschäftsbedingungen.

Fassung annahme-api-v1

Der Auftrag entsteht sofort: Die Antwort steht auf ORDERED und nennt ihn in order, Ihr Webhook-Endpunkt bekommt order.created. Ab jetzt fragen Sie mit GET /orders/{id} nach. Als Nachweis hält LOGICAR fest, welcher Zugang angenommen hat, in welchem Aufruf (requestId), von welcher Adresse und wann — dazu die Fassung und die Prüfsumme ihres Dokuments. Eine E-Mail an Sie geht dabei nicht hinaus: Ihr System hält die Antwort in der Hand.

AntwortBedeutung
403 QUOTE_ACCEPTANCE_NOT_AGREEDNicht vereinbart — über den Link annehmen.
409 QUOTE_VERSION_MISMATCHAngeboten ist eine andere Fassung; details.currentVersion nennt sie.
409 QUOTE_EXPIREDDas Angebot ist abgelaufen.
409 QUOTE_NOT_OFFEREDEs liegt noch kein Angebot vor.
409 QUOTE_ALREADY_DECIDEDSchon angenommen oder abgelehnt; details.status nennt den Stand.

Schicken Sie einen Idempotency-Key mit: Bricht die Verbindung ab, liefert derselbe Aufruf mit demselben Schlüssel die erste Antwort noch einmal — statt 409 QUOTE_ALREADY_DECIDED.

#Ablehnen

POST /quotes/{id}/decline (Recht quotes:write) lehnt das vorliegende Angebot ab, auch ein abgelaufenes. Einen Grund dürfen Sie mitschicken:

json
{ "reason": "Termin passt nicht" }

Die Anfrage endet (DECLINED), Ihr Webhook-Endpunkt bekommt order.rejected. Eine Vereinbarung braucht es dafür nicht: Eine Ablehnung bindet nichts. Solange noch kein Angebot vorliegt, ziehen Sie die Anfrage stattdessen zurück: POST /orders/{id}/cancel (Aufträge verwalten).

#In der Sandbox

POST /quotes mit einem Testzugang startet das Szenario QUOTE_REQUIRED:

Nach 20 Sekunden — im Handbetrieb beim ersten Weiterschalten — schickt die Simulation das Angebot: Preis nach der Preismatrix für die Strecke (ohne Strecke rechnet sie mit 300 km), gültig 14 Tage, Fassung 1.

Danach wartet die Simulation auf Ihre Entscheidung: Annehmen oder ablehnen Sie über dieselben Endpunkte. In der Sandbox darf Ihr System immer annehmen (acceptance.viaApi: true) — dort entsteht nichts Verbindliches. Ein PDF gibt es in der Sandbox nicht.

Im Handbetrieb (X-Sandbox-Mode: manual) schalten Sie mit POST /sandbox/orders/{id}/advance weiter (Szenarien).