#Angebote
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 mit202undkind: "REQUEST"(Auftrag anlegen).POST /quotes(Rechtquotes:write) — Sie fordern ausdrücklich ein Angebot an, auch wo Ihre Vereinbarung den Fall sonst direkt bepreisen würde. Der Rumpf ist derselbe wie beiPOST /orders; die Antwort ist das Angebot mit StatusREQUESTED(HTTP 202). Wie beim Auftrag gilt derIdempotency-Key, ohne ihn dieexternalOrderId(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
| Status | Bedeutung | Ereignis |
|---|---|---|
REQUESTED | Angefragt — LOGICAR erstellt das Angebot. | — |
OFFERED | Das Angebot liegt vor und kann angenommen oder abgelehnt werden. | — |
ACCEPTED | Angenommen; der Auftrag entsteht. | — |
ORDERED | Aus dem Angebot ist ein Auftrag geworden (order). | order.created |
DECLINED | Vom Auftraggeber abgelehnt. | order.rejected |
EXPIRED | Abgelaufen, ohne angenommen zu werden. | — |
REJECTED | Von 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:
{
"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 aufREQUESTED, ohne Beträge.amountunditems— wie im Angebotsdokument,vatRatein 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 aufEXPIRED.document— das Angebot als PDF:GET /quotes/{id}/document. Prüfen Sie nach dem Herunterladen diesha256.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:
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.
| Antwort | Bedeutung |
|---|---|
403 QUOTE_ACCEPTANCE_NOT_AGREED | Nicht vereinbart — über den Link annehmen. |
409 QUOTE_VERSION_MISMATCH | Angeboten ist eine andere Fassung; details.currentVersion nennt sie. |
409 QUOTE_EXPIRED | Das Angebot ist abgelaufen. |
409 QUOTE_NOT_OFFERED | Es liegt noch kein Angebot vor. |
409 QUOTE_ALREADY_DECIDED | Schon 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:
{ "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).