AI translation
This page was translated from German with AI. If in doubt, the German original applies.
Platform architecture¶
The ZEDAL platform exposes its functionality as a family of gRPC services. Integrators reach them in three ways: SDK, REST/JSON and gRPC directly. All three lead to the same functionality, because the .proto definitions are the single source of truth from which the SDK, the REST facade and the OpenAPI document are derived.
Overview¶
flowchart TB
subgraph integ["Integrator side"]
APP["Application<br/>Backend / Mobile / Web"]
end
subgraph edge["ZEDAL edge"]
SDK[".NET SDK<br/>Zedal.Sdk"]
REST["REST / JSON + gRPC-Web<br/>openapi.*.zedal.de"]
GRPC[("gRPC endpoint<br/>api.*.zedal.de")]
end
subgraph backend["Backend services"]
CORE["Core<br/>Auth, documents, files"]
BXA["BxA documents<br/>Company / Authority"]
DIWASS["DIWASS connection<br/>Retrieval, Attachment,<br/>Operator, Authority"]
SIGNER["Signer<br/>VerifyApi"]
DISC["DiscoveryApi"]
TRANS["TransformApi"]
end
subgraph ext["External systems"]
EU["EU DIWASS<br/>central system"]
end
APP --> SDK
APP --> REST
APP --> GRPC
SDK --> GRPC
REST --> GRPC
GRPC --> CORE
GRPC --> BXA
GRPC --> SIGNER
GRPC --> DIWASS
GRPC --> DISC
GRPC --> TRANS
DIWASS -.->|brokered server-side| EU
Three access paths¶
Which path fits depends on your language, your integration style and whether you need streaming.
1. Official SDK¶
When: if your application is built in a language for which an SDK is available.
Currently: .NET / C# — NuGet package Zedal.Sdk, versioned according to Semantic Versioning.
The SDK encapsulates gRPC, handles authentication including token renewal and provides dedicated document handlers for the DIWASS documents instead of raw request messages. Recommended for most integrations.
Beyond pure protocol encapsulation, it offers building blocks that do not exist on the gRPC or REST path and that you would otherwise have to build yourself:
| Building block | What it does |
|---|---|
Document handler (client.DocumentHandler) |
Notification, movement, Annex VII and the authority view as objects with stage methods and follow-up intents |
Inbox importer (CreateInboxImporter()) |
Takes incoming document versions over into the local store — see Calls and synchronization |
| Token renewal | The bundled DefaultTokenRefresher renews the access token as soon as less than 5 minutes of remaining lifetime are left. It checks only the expiry time — it does not handle revoked or blocked access; for production use, a custom IJwtTokenRefresh implementation is intended |
client.MyAccount |
The logged-in user’s own DIWASS operator IDs and BMU ZKS numbers |
2. REST / JSON¶
When: if you work in a language without an official SDK or prefer REST tooling. Status: in production. Details, call format and code generation: API reference → REST.
A brief note on its origin, because it explains the behavior: the REST facade is not generated gateway code. It is a separate .NET service that reflects the FileDescriptors of the gRPC definitions at runtime and derives the REST routes from them. This has direct consequences:
- No codegen step, no version skew. The OpenAPI document describes exactly what the running service can do. That is why the reference is always up to date.
- The paths are RPC-shaped, not resource-oriented:
<VERB> /<service.FullName>/<method>. - The verb comes from the
google.api.httpannotation. It is not always POST; GET, PATCH, DELETE and PUT occur as well. - A method without an HTTP annotation has no REST route. There are gRPC methods that cannot be reached via REST — see the “REST” column in the table below.
- The reference UI is Scalar, the document is OpenAPI 3.0.3.
REST/JSON is unary — no server streaming
One request, one response. Server streaming is not available via REST, not even as server-sent events. If you need streaming, use native gRPC or gRPC-Web via the same openapi.* host; there, streaming responses are delivered incrementally.
3. gRPC directly¶
When: if you need streaming, want low latency or would like to generate code from the protos yourself in your language.
The native gRPC endpoint is on the api.* host and offers the complete surface — including the methods without a REST route. See API reference → gRPC.
Environments¶
The two hosts per environment are separate: native gRPC on api.*, REST/JSON and gRPC-Web on openapi.*.
| Environment | native gRPC | REST/JSON + gRPC-Web |
|---|---|---|
| Production | api.live.zedal.de |
openapi.live.zedal.de |
| Preview | api.preview.zedal.de |
openapi.preview.zedal.de |
| Test | api.test.zedal.de |
openapi.test.zedal.de |
| Development | api.dev.zedal.de |
openapi.dev.zedal.de |
Provider IDs are environment-specific
A provider ID from production is not valid on test and vice versa. On the REST path, the provider_id header is mandatory on every call — including the login. A wrong or missing ID returns the same misleading 501 response. Details in REST / JSON and Getting started.
Services¶
Behind the gRPC endpoint there are several thematic services. The SDK bundles them under the IZedalClient facade; via REST and gRPC you address them by their fully qualified name.
The REST column states how many methods of the service can be reached via REST/JSON. The numerator comes from the OpenAPI document of the running system, the denominator from the proto definitions.
| SDK path | gRPC service | REST | Responsibility |
|---|---|---|---|
CoreApi.Auth |
core.v1.api.AuthApi |
8 / 8 | Refresh/access tokens, sessions, client IDs, password change |
CoreApi.Documents |
core.v1.api.DocumentApi |
20 / 32 | Reading documents and parameters, inbox, import from the inbox, sending and acknowledgment |
CoreApi.File |
core.v1.api.FileApi |
13 / 23 | Files and submissions in the file area (Nachweis-Bereich) |
CoreApi.Templates |
core.v1.api.DocumentTemplateApi |
4 / 6 | Templates for transport papers and files |
CoreApi.MasterData |
core.v1.api.MasterdataApi |
1 / 2 | Address master data |
CoreApi.Common |
core.v1.api.CommonApi |
2 / 3 | Global parameters |
CoreApi.Query |
core.preview.api.PreviewApi |
2 / 8 | Overview lists of documents, files and templates. Experimental — names and scope may change |
| — | core.v1.api.QueryApi |
3 / 5 | Overview lists of transport documents, inbox, file area documents, files and templates. Without a REST route: ListFileAreaDocuments, ListFiles |
BxaApi.CompanyDocumentApi |
bxa.diwass.v1.api.CompanyDocumentApi |
23 / 23 | Company side of the DIWASS documents: creating notification, movement, Annex VII and setting stages |
BxaApi.AuthorityDocumentApi |
bxa.diwass.v1.api.AuthorityDocumentApi |
9 / 9 | Authority side: decision, request for additional information, signals, take-back |
BxaApi.BmuDocumentApi |
bxa.bmu.v1.api.BmuDocumentApi |
6 / 6 | BMU consignment notes and acceptance notes: create, append layers, set fields, signature positions; see BMU guide |
DiwassApi.RetrievalApi |
diwass.v1.api.RetrievalApi |
4 / 4 | Event list and synchronization — see Calls and synchronization |
DiwassApi.AttachmentApi |
diwass.v1.api.AttachmentApi |
2 / 2 | Submitting and retrieving attachments |
DiwassApi.OperatorApi |
diwass.v1.api.OperatorApi |
2 / 2 | Operator directory: search and single retrieval |
DiwassApi.AuthorityDirectoryApi |
diwass.v1.api.AuthorityApi |
4 / 4 | Authority directory: search by activity, single retrieval, change status |
DiwassApi.SoapProxyApi |
— | none | Passing a raw SOAP body through to DIWASS |
DiscoveryApi |
provider_discovery.v1.api.DiscoveryApi |
1 / 1 | Provider directory. ListProvider is the only operation without a token and without provider_id — and therefore step 0 of every integration |
TransformApi |
— | none | Generates a graphical representation from the native document representation, in particular PDF (ToPdf) |
SignerApi.VerifyApi |
signer.v2.api.VerifyApi |
4 / 4 | Verification of certificates and signatures (VerifyCert, VerifyP7, VerifyPdf, VerifyXml) |
Where REST falls behind gRPC
A gRPC method without a google.api.http annotation gets no REST route. This does not only affect edge cases:
| Missing via REST | Why it hurts |
|---|---|
DocumentApi.ImportTransportDocumentFromInbox, ImportDocumentToFileAreaFromInbox |
Exactly the step that brings incoming document versions into the local store — see Calls and synchronization |
DocumentApi.SendDocument, DeliverDocument |
Sending via the ZEDAL distribution path |
FileApi.CreateNewFile, GrantAccessToFile, MergeFiles, MoveDocumentToFile |
File management in the file area |
PreviewApi.ListTransportDocuments, ListFiles, ListFileAreaDocuments, ListInboxDocuments; QueryApi.ListFiles, ListFileAreaDocuments |
Files and the file area cannot be listed via REST. Inventory, inbox and templates are listed via REST by the QueryApi (ListTransportDocuments, ListInboxDocuments, ListTransportTemplates) |
If you are planning a pure REST integration, check early whether your workflow can do without these operations — this is an architecture decision, not a detail. The binding reference is always the OpenAPI document of the running system: what is listed there can be reached via REST; what is missing cannot.
External connections¶
The DIWASS services broker server-side to the EU DIWASS central system and encapsulate transport and format conversion in the process. From the integrator’s point of view, this brokering is an implementation detail — you work against the ZEDAL API.
What is not encapsulated: operating rules and latency
Two things leak through the encapsulation, and your application has to handle both:
- The European Commission requires sequential calls against DIWASS and reserves the right to block API access in the event of continued violations.
- Responses arrive asynchronously and slowly. External updates only appear in the ZEDAL store after 100–150 seconds; the SDK’s default client timeout of 30 seconds is not sufficient for DIWASS paths.
Both are described in detail under Calls and synchronization.
Single source of truth¶
The .proto definitions are the starting point for everything: changes to the API are made at the proto level. For integrators this means:
- gRPC is the complete surface. REST is a projection of it and covers it almost, but not completely.
- The OpenAPI document is generated, but not in advance. It is created at runtime from the
FileDescriptors. There is therefore no version that lags behind the deployment. - Versioning of the .NET SDK follows Semantic Versioning (
Zedal.Sdk).
Deprecations do not carry through to every access path
Deprecated operations are marked as deprecated in the protos and visible as [Obsolete] in the SDK. In the running OpenAPI document, no operation is currently marked as deprecated — so do not rely on the REST reference alone for deprecation notices. The SDK release notes and the proto definitions are authoritative.
Where to go next¶
- Getting started — authentication, configuration, first call
- Calls and synchronization — call frequency, error handling, synchronization, time budgets
- Storage areas — inbox, file area, transport paper area (Versandpapier-Bereich); the vocabulary behind most core calls
- DIWASS guides — current focus: transboundary shipment of waste
- Glossary — terms and abbreviations
- .NET SDK — quickstart for the C# world