Reimann Logistics API guide
A small, complete transport integration: pull inputs, attach original documents, link a Logistica case, and return exchange results.
Connection details
Base URL: https://reimann-logistics.pages.dev API root: /api/v1 Header: x-api-key: demo_reimann_logistics_2026
The key and login are fake demonstration credentials. The ten selected cases were reviewed; each current collection matches its sole extraction snapshot exactly, with no recorded data correction. Human review is expected. The website has its own demo database; it never writes to Pape. Sample inputs preserve the source collection values and exclude only exchange_details. Original source PDFs are supplied locally, one PDF per collection, and are not published as static assets.
1. Load and pull cases
The Add Demo Data button loads the configured sample inputs. Loading again preserves existing cases and any results already pushed. Clear Demo Data removes only this demo’s records and uploaded attachments.
curl -X POST 'https://reimann-logistics.pages.dev/api/demo/seed' \ -H 'x-api-key: demo_reimann_logistics_2026' curl 'https://reimann-logistics.pages.dev/api/v1/cases?status=Created' \ -H 'x-api-key: demo_reimann_logistics_2026'
Match the actual document reference
Poll every minute from Logistica. Match using input.document_number, never the RL-xxxx selector. For Tevex use the Fahrt-Nr.; for DPL credit notes issued by Kaufland use the complete OPG Gutschrift-Nr. Preserve the source input.customer = DPL and input.issuer = Kaufland Neckarsulm; the TMS customerGroup is DPL. Kaufland is the issuer, distinct from the source collection/customer DPL; this does not select a Logistica booking partner.
curl 'https://reimann-logistics.pages.dev/api/v1/cases?documentNumber=OPG-39790-LG-109352&customerGroup=DPL' \ -H 'x-api-key: demo_reimann_logistics_2026'
This performs an exact, case-sensitive match and returns cases of any status. URL-encode the full reference. Zero matches means no TMS data; multiple matches require explicit resolution rather than selecting the first record.
Case response
{
"cases": [{
"id": "RL-0001",
"customerGroup": "Tevex",
"status": "Created",
"input": { "document_number": "15443533", "date": "27.09.2026", "customer": "Tevex", "kennzeichen": "DU EA 572", "...": "remaining exact source fields" },
"exchangeData": null,
"logisticaCaseId": null,
"logisticaCaseUrl": null,
"sampleDocument": null,
"createdAt": "ISO timestamp",
"updatedAt": "ISO timestamp"
}],
"total": 10
}Read one case with GET /api/v1/cases/{id}. Its response adds a documents array with ID, filename, MIME type, size, timestamp, and download URL. The returned input values are the source values; the response above abbreviates additional fields for readability.
2. Attach a PDF or image
Upload the corresponding original case PDF, or a returned image, as a multipart field named file. Supported formats: PDF, PNG, JPEG, WebP. Demo upload limit: 20 MB per file. MIME type must agree with the file’s signature. Uploading a document preserves the case’s current status.
curl -X POST 'https://reimann-logistics.pages.dev/api/v1/cases/RL-0001/documents' \ -H 'x-api-key: demo_reimann_logistics_2026' \ -F 'file=@RL-0001-Tevex-15443533.pdf;type=application/pdf'
{
"id": "document UUID",
"filename": "RL-0001-Tevex-15443533.pdf",
"mimeType": "application/pdf",
"size": 123456,
"url": "/api/v1/cases/RL-0001/documents/document-UUID"
}The supplied file is stored unchanged. Repeating an upload with the same case, sanitized filename, and SHA-256 file contents returns the existing document ID. Changed bytes produce a new ID, even when the filename is unchanged. The upload response and case document list include a sha256 field. Download it using the returned relative URL and the API-key header, or open it from a signed-in case detail panel. A document can only be retrieved through its owning case.
3. Link a Logistica OS case
curl -X PATCH 'https://reimann-logistics.pages.dev/api/v1/cases/RL-0001/logistica-case' \
-H 'x-api-key: demo_reimann_logistics_2026' \
-H 'Content-Type: application/json' \
-d '{"logisticaCaseId":"external-case-id","logisticaCaseUrl":"https://your-demo-platform.example/cases/external-case-id"}'Both fields are optional individually. URLs must use HTTPS. Saving a case link does not change status. The URL appears as a clickable link in the table and case detail panel. This example URL is a placeholder; use the actual URL returned by your Logistica demo.
4. Push the exchange result
Send an object keyed by load carrier type. Each value must contain non-negative integer in and out counts. IN = carriers received; OUT = carriers delivered. Use the actual results returned by document processing.
curl -X PUT 'https://reimann-logistics.pages.dev/api/v1/cases/RL-0001/exchange-data' \
-H 'x-api-key: demo_reimann_logistics_2026' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: your-stable-result-id' \
-d '{"exchangeData":{"euro":{"in":21,"out":21},"h1":{"in":0,"out":0}},"logisticaCaseId":"external-case-id","logisticaCaseUrl":"https://your-demo-platform.example/cases/external-case-id"}'{
"id": "RL-0001",
"status": "Reviewed",
"exchangeData": { "euro": { "in": 21, "out": 21 }, "h1": { "in": 0, "out": 0 } },
"updatedAt": "ISO timestamp"
}The result and Reviewed status are persisted together. Each subsequent valid push replaces the full exchange object. Optional link fields update only when supplied. Repeating a push with the same Idempotency-Key and same payload returns the original receipt without adding a second result event; reusing the key with a different payload or case returns 409. Use a new key for a new result.
Click Refresh in the portal, or pull the case again, to see the persisted update. The case detail panel also offers a manual JSON push for demonstrating this behavior.
5. Synchronize the complete reviewed extraction
Use this endpoint on human review and every later input or file edit. Supply the full current non-exchange input, the complete current exchange object or explicit null, and the exact current set of uploaded document IDs. Upload current originals first, then synchronize their returned IDs.
PUT /api/v1/cases/{id}/reviewed-data
Content-Type: application/json
x-api-key: demo_reimann_logistics_2026
{
"customerGroup": "DPL",
"input": {
"document_number": "OPG-39790-LG-109352",
"customer": "DPL",
"issuer": "Kaufland Neckarsulm",
"date": "01.10.2026",
"kennzeichen": "DU-ME 480",
"quantity": 17
},
"exchangeData": null,
"documentIds": ["document-id-returned-by-upload"],
"logisticaCaseId": "current-logistica-collection-id",
"logisticaCaseUrl": "https://your-demo-platform.example/cases/current-logistica-collection-id"
}The input above illustrates the shape; send all current source fields, including any matching metadata. Split only exchange_details into exchangeData. Neither PATCH nor PUT merges the input object. Fields missing from the new input are removed. exchangeData: null explicitly clears an old exchange result while preserving Reviewed status.
documentIds is required. Every ID must belong to this case. The listed documents become the complete current set: documents omitted from it are removed from this demo's metadata and storage. An empty array removes all attachments. Up to 50 current document IDs are accepted. The response is the full current case, with status Reviewed and its document list.
The input, exchange, current document set, links, and Reviewed state commit together in D1. Removed file bytes are cleaned up afterward from a durable cleanup queue; if cleanup fails, retrieve the case and retry the current snapshot to retry queued removal. The response can be 500 after the database snapshot committed; a retry preserves the current content. Uploading changed files preserves originals until the following snapshot selects the replacement set. Repeating a snapshot preserves the same content and may add a new receipt activity event.
Correct only non-exchange input
PATCH /api/v1/cases/{id}
{ "input": { "document_number": "full-current-reference", "...": "all current non-exchange fields" }, "customerGroup": "Tevex" }This replaces the entire input and optionally its customer group, while preserving status, exchange data, and documents. For a review or file edit, prefer the complete reviewed-data snapshot. Push snapshots sequentially per case: the latest arriving valid snapshot wins; there is no historical revision-ordering protocol.
Missing TMS data: wait for human review
- Logistica polls the TMS every minute and separately classifies incoming emails as Tevex or DPL, extracts the original files, and matches the actual document number.
- With no existing TMS match, Logistica creates its extracted collection and the action No TMS data detected. It waits for human review before creating any TMS case.
- After human review, create the TMS case using POST, preserving the current exact non-exchange input. Use a stable
Idempotency-Key, for examplecreate:<Logistica-collection-id>. Retry the same creation with the same key and body to receive the same case ID; changed content under that key returns 409. - Upload current original files, save the external case link, and PUT the full reviewed snapshot using the returned TMS ID as an API selector.
- On each later review or input/file edit, upload the current files and send the exact current snapshot again with Reviewed status.
The human-review wait and intake locks belong to Logistica. This demo TMS accepts authenticated valid API requests and does not assert that a human approval happened. Minute polling, email intake, classification, extraction, and Logistica action creation are performed by the separate intake integration.
Endpoint reference
| METHOD | PATH | BEHAVIOR |
|---|---|---|
| GET | /api/v1/cases | All cases; optional status, exact documentNumber, customerGroup filters |
| POST | /api/v1/cases | Create case: {customerGroup, input}; document_number required, exchange fields forbidden; Idempotency-Key supported |
| GET | /api/v1/cases/{id} | Full case including documents |
| PATCH | /api/v1/cases/{id} | Replace complete non-exchange input |
| PUT | /api/v1/cases/{id}/reviewed-data | Save current input, exchange or null, exact documents, and Reviewed |
| PATCH | /api/v1/cases/{id}/logistica-case | Save external ID and/or HTTPS URL |
| PUT | /api/v1/cases/{id}/exchange-data | Save results and mark Reviewed |
| POST | /api/v1/cases/{id}/documents | Multipart document upload |
| GET | /api/v1/cases/{id}/documents/{documentId} | Original file bytes |
| GET | /api/v1/activity | Last 100 demo activity entries |
| POST | /api/demo/seed | Load configured sample cases |
| DELETE | /api/demo/clear | Clear this demo’s cases, results, links, attachment records, and stored files |
Clearing cases and stored files
DELETE /api/demo/clear removes all demo cases, document records, and their stored PDF/image files. File deletion uses a durable cleanup queue. If file storage temporarily fails, records may already be cleared; retry the same DELETE to finish deleting the queued files. The per-case reviewed-data snapshot also deletes stored files omitted from its exact documentIds set. The portal has no separate individual-document delete control.
Errors
{ "error": { "code": "VALIDATION_ERROR", "message": "Request did not match the contract", "issues": [] } }400 invalid request; 401 missing/incorrect credentials; 404 missing resource; 409 idempotency conflict or snapshot changed during synchronization; 413 oversized input or file. Case inputs are limited to 50 KB. Carrier type keys allow letters, digits, underscores, and hyphens. Counts are integers between 0 and 1,000,000.
Demo boundary
The TMS, login, and API key are demonstrations. Source-case input values and uploaded originals are not invented. All mutations affect this demo’s D1 database and R2 bucket only. This portal does not start Logistica intake, run extraction, create production cases, or send emails. The external integration supplies processed results through the documented APIs.