AI translation
This page was translated from German with AI. If in doubt, the German original applies.
Lifecycle¶
A DIWASS shipment passes through two consecutive document lifecycles: first the notification (registration and approval), then, once consent has been given, the movement (operational execution). Both have their own states and their own stage sequences, but they are causally linked — a movement can only exist for a consented notification.
This chapter describes the states, the choreography and the sending procedure. You’ll find the calling code in Notification (Company) and Movement (Company).
Legal basis¶
Two EU legal acts are decisive, and the second is often overlooked:
| Legal act | Governs |
|---|---|
| Regulation (EU) 2024/1157 (Waste Shipment Regulation) | The procedure: who notifies, who consents, which documentation is due when |
| Implementing Regulation (EU) 2025/1290 (implementing act) | The technical implementation: data model, operation types and above all the authentication obligations in Article 14 |
For an integration, the Implementing Regulation is the more concrete source. It specifies which party has to authenticate which operation — that is the requirement your application has to implement technically.
Stage vocabulary¶
A stage is a self-contained step in the document lifecycle. In the SDK, each stage corresponds to one method on the document handler (SetCarrierTransport, SetFacilityReception, …), and each follows the same two-phase flow — see Sending procedure.
The status comes back to you, you don’t send it
DIWASS documents carry no status in the mutation data model. A movement you create yourself carries the request type (MovementTemplateType) — and that type has no status field. The same applies to notification and Annex VII: mutation types carry payload data; only the retrieval view carries the status.
There, however, it is a real, schema-restricted field — not a convention:
| Field | Permitted values |
|---|---|
notificationStatus |
DRAFT, SUBMITTED, SATISFIED, CONSENT, INVALID, WITHDRAWN, OBJECTED, CANCELLED |
movementStatus |
DRAFT, ANNOUNCED, SUBMITTED, MOVING, RECEIVED, ACCEPTED, REJECTED, COMPLETED, CANCELLED, TAKE_BACK |
Use these values in your code, not names of your own choosing. What this chapter describes as an intermediate situation — “request for additional information open”, “request for change pending” — is not a status value of its own, but is derived from the presence of blocks and from the follow-up intents. See Determining the state.
Sending procedure¶
A document’s path from the SDK into the EU system runs in two separate phases plus an asynchronous feedback loop.
Phase 1 — SaveToZedal()¶
The document (internally ZeWaSS XML) is persisted in ZEDAL. In this state, it
- exists as an addressable version and can be reloaded at any time,
- is not transmitted to the EU system — there is no external communication,
- can be edited further, validated or discarded without DIWASS taking any notice.
SaveToZedal() is the persistence anchor. Only a persisted document can proceed to the second step.
Phase 2 — SendToDiwass()¶
Triggers the actual sending. The call returns as soon as the sending has been accepted on the server side and placed in the transmission pipeline — not only once the EU system has responded. The transfer log ID is then available in handler.LastTransferLogId.
There is no draft status via the API
What would be a draft in the GUI is already submitted via the API: a notification created via the interface goes straight to status Submitted, a movement straight to Announced. There is no preliminary stage for trying things out — all validation applies on the first call, and a document submitted with errors is submitted.
So build your own pre-validation before SendToDiwass(), not afterwards. The field rules describe what DIWASS insists on beyond the schema.
Phase 2b — WaitForDiwassTransfer() (optional)¶
Waits for the confirmation of receipt by polling the transfer log status:
- Success (
RECEIVED_RECEIPT_POSITIVEorDELIVERED_TO_RECIPIENT_INBOX): returns normally. - Rejection (
RECEIVED_RECEIPT_NEGATIVEorCANCELLED): throwsDiwassTransferFailedExceptionwith the error details. - Timeout: throws
TimeoutException.
The waiting is a local loop in the SDK, not a wire status on the document. It does not replace the business response from phase 3.
Choose a realistic time budget
These calls take considerably longer than a network timeout would suggest:
| Case | Measured | Budget |
|---|---|---|
| Push without attachment | around 50 s | 90 s is enough |
| Push with attachment | over 90 s | at least 180 s |
| Movement chain, per stage | 2:39 to 4:53 | 180 s is not enough |
The SDK’s client default is 30 seconds — too tight for DIWASS paths. Set the deadline per call via the ZedalCallContext. A budget that is too tight produces errors that look like server problems but are purely a matter of runtime.
Phase 3 — Asynchronous response¶
The business response of the EU system (acknowledgment, validation result, follow-up intents, new status) arrives asynchronously and is stored in ZEDAL as a new version of the same document. The DIWASS output is therefore not a return value of SendToDiwass(), but a later version.
It follows that:
- a successful
SendToDiwass()means “accepted for transmission”, not “confirmed by DIWASS”; - a successful
WaitForDiwassTransfer()means “accepted by DIWASS”, but says nothing about the business outcome; - the business outcome only appears in a later version;
- each stage has its own sending and response cycle.
Changes made by others take time — and need the inbox import
An update from outside (a request for additional information from an authority, a decision, a reply to a request for change) does not reach the ZEDAL document store synchronously. 100 to 150 seconds were measured between the authority’s push to DIWASS and its appearance in ZEDAL. Until then, reloading returns the original document with an empty intent list — the authority block is simply missing.
The inbox import is the delivery path, not merely a cleanup step: without it, the new version does not appear in the document store. How to set this up properly is described under Calls and synchronization.
Determining the state¶
Because the document carries no status, you need a different approach. There is exactly one right one:
Evaluate the follow-up intents. After each stage call, handler.FollowupIntents lists the actions that are permitted next. It is a property, not a method. The list comes from the server and reflects the rules that apply there — you don’t have to rebuild them.
From it, you derive buttons, locks and status displays. Two common mistakes:
Don’t derive the state from list lengths
The retrieval schema separates two lists: requestInformation for requests for additional information from the authority and replyRequestInformation for the notifier’s replies. DIWASS only fills the first one. Both messages — request and reply — appear as requestInformation entries; you can recognize the reply by the fact that it carries its own replyRequestInformationId and the same requestInformationId as the request it refers to.
If you determine “open versus answered” via list membership or by comparing the lengths of the two lists, you will get systematically wrong results.
RECEIVED does not mean “arrived”
The movement status is an aggregation across the entire facility chain, not the state of a single facility. The specification explicitly ties the transitions to one event:
ANNOUNCED/MOVING→RECEIVEDon the first confirmation of receiptRECEIVED→COMPLETEDon the certificate of completed recovery or disposal
Since a notification can list several facilities (see Facility chain), RECEIVED therefore means “at least one facility has acknowledged receipt” — not “the receiving facility has” and certainly not “all have”. If you read the status as “where is the waste right now”, you will be wrong for Article 15 chains.
Facility chain¶
A notification does not describe a single receiving facility but a chain. That is why there can be several confirmations of receipt and several certificates of completed recovery or disposal per movement.
If a shipment goes to interim recovery or disposal, Article 15(1) of Regulation (EU) 2024/1157 requires all downstream facilities to be specified in the notification form in addition to the first one. The notification therefore lists 1 + n facilities.
Which path a facility takes is given by three indicators on the facility itself (FacilityType.OperationalIndicators):
| Indicator | Meaning | Consequence |
|---|---|---|
InterimFacility |
This facility carries out an interim operation | The chain continues |
NextSubsequent…InSameCountry |
Passed on within the country of destination | Article 15(5): no new notification, no new movement. The evidence comes back as an Article 15 certificate |
NextSubsequent…InAnotherCountry |
Passed on to another country | Article 15(7)/(8): new notification with its own movements required |
The last row has the most far-reaching consequences for integrators: in the cross-border case, the procedure does not end with another certificate; instead, a completely new notification procedure begins.
No chaining in the data model
For the new notification under Article 15(7)/(8), there is no field that refers to its predecessor. Despite its name, referenceNotificationId is not such a reference — it carries the number of the document itself, as assigned by the competent authority of dispatch.
If you want to keep the chain traceable across national borders, you have to maintain the link outside DIWASS.
The chain determines the cardinalities in retrieval: facilityReception and facilityCompletion are repeatable without limit, consigneeReception has exactly one entry. Each confirmation of receipt itself states which facility issued it — the movement announcement does not yet name the facility.
The Article 15 certificate is attached to the notification, not to the movement, and references several shipments via movementIdentifier: a subsequent facility processes material from several transports, so the relationship is n:m. In the SDK, this is SetFacilityCompletionUnderArticle15 on the NotificationDocumentHandler.
Notification: states¶
stateDiagram-v2
[*] --> SUBMITTED: CreateSubmission
SUBMITTED --> SUBMITTED: request for additional information, reply, update
SUBMITTED --> CONSENT: all CAs give consent
SUBMITTED --> OBJECTED: one CA objects
CONSENT --> CONSENT: request for change and replies
SUBMITTED --> CANCELLED: cancellation
CONSENT --> CANCELLED: cancellation
CONSENT --> WITHDRAWN: transit CA withdraws
SUBMITTED --> INVALID: CA declares invalid
CANCELLED --> [*]
OBJECTED --> [*]
WITHDRAWN --> [*]
Before consent, the competent authority of dispatch sets the signal ProperlyCarriedOut and the competent authority of destination sets ProperlyCompleted. These signals are a precondition — they ensure that all parties form their decision on the same basis.
Notification: stage order¶
The stage names are the SDK methods. Company side: NotificationDocumentHandler. Authority side: AuthorityNotificationDocumentHandler (see Authority). Signals all go through the same method SubmitNotificationSignal with a typed signal body.
| # | Stage | Actor | Article (Reg. 2024/1157) | Precondition | Effect |
|---|---|---|---|---|---|
| 1 | CreateSubmission |
notifier | Article 4 | — | submission created, NotificationId assigned |
| 2 | SetRequestInformation |
one authority | Article 4(4) | status SUBMITTED |
request for additional information open |
| 3a | SetSubmission |
notifier | Article 4(4) | open request for additional information | submission updated |
| 3b | SetReplyToRequestInformation |
notifier | Article 4(4) | open request for additional information | reply recorded |
| 4a | SubmitNotificationSignal (ProperlyCarriedOut) |
competent authority of dispatch | Article 10 | all requests for additional information closed | readiness signaled |
| 4b | SubmitNotificationSignal (ProperlyCompleted) |
competent authority of destination | Article 10 | as for 4a | readiness signaled |
| 5 | SetDecision |
each authority concerned individually | Article 5 | 4a and 4b are present | consented as soon as all have consented |
| 6 | SetRequestForChangeAfterConsent |
notifier | Article 7 | status CONSENT |
request for change open |
| 7 | ReplyToRequestForChangeAfterConsent |
each authority individually | Article 7 | open request for change | consent or rejection |
| 8 | SubmitNotificationSignal (cancellation) |
notifier | Article 6(2) | status ≠ CANCELLED |
notification canceled |
| — | SetFacilityCompletionUnderArticle15 |
facility in the chain | Article 15(5) | interim operation completed | certificate from the subsequent facility, refers to several movements |
The decision is made N times, not once
A shipment involves at least the competent authorities of dispatch and of destination, plus one more for each country of transit. Each of them issues its decision separately. Only once all have consented is the notification consented — a missing consent blocks the transition.
Which authority is permissible as a competent authority of transit at all is not stated in the directory. See Field rules.
The change window¶
A submitted notification can only be changed as long as at least one request for additional information is open. Without an open request, there is no way to correct the notification in status SUBMITTED.
Three consequences an application has to handle:
- The window depends on “none open anymore”, not on “one answered”. If two authorities request additional information in parallel, the notification remains changeable after the reply to the first one. The window closes with the last reply — and reopens when a new request for additional information arrives.
- The order is a one-way street. If you send your reply first and only then realize that you also need to adjust the notification, you have closed the window yourself. Before the last open reply is sent, the user interface should therefore ask for confirmation — and as long as nothing has been sent, it must be possible to discard a draft reply.
- “Locked” is not a stored state, but always derived. Derive it from the follow-up intents, not from a flag of your own.
Movement: states¶
stateDiagram-v2
[*] --> ANNOUNCED: CreateMovementTemplate
ANNOUNCED --> MOVING: SetCarrierTransport
MOVING --> RECEIVED: first confirmation of receipt
RECEIVED --> RECEIVED: further facilities in the chain
RECEIVED --> COMPLETED: certificate of completed recovery or disposal
ANNOUNCED --> TAKE_BACK: take-back ordered
MOVING --> TAKE_BACK: take-back ordered
RECEIVED --> TAKE_BACK: take-back ordered
ANNOUNCED --> CANCELLED: cancellation by the notifier
COMPLETED --> [*]
TAKE_BACK --> [*]
CANCELLED --> [*]
Movement: stage order¶
| # | Stage | Actor | Article (Reg. 2024/1157) | Precondition | Effect |
|---|---|---|---|---|---|
| 1 | CreateMovementTemplate |
notifier | Article 16 | consented notification | movement created, MovementId assigned |
| 2 | SetCarrierTransport |
carrier | Article 16 | status ANNOUNCED |
vehicle, departure, takeover recorded |
| 3 | SetConsigneeReception |
consignee | Article 16 | status MOVING |
receipt of the waste confirmed, quantity balance |
| 4 | SetFacilityReception |
facility | Article 16 | receipt by the consignee recorded | acceptance at the facility confirmed |
| 5 | SetFacilityCompletion |
facility | Article 15 | status RECEIVED |
treatment completed, with R/D code |
| 6 | SetMovementTakeBack |
each authority concerned | Article 22 | status ANNOUNCED, MOVING or RECEIVED |
take-back ordered; exactly one per movement, can be updated by the submitting authority |
| 7 | SubmitMovementSignal (cancellation) |
notifier | Article 16 | status DRAFT or ANNOUNCED |
movement canceled |
The standard path is sequential: stage n requires that n−1 has been pushed successfully. Interventions by authorities can end it at any time.
Stage 3 is omitted if consignee and facility are identical
If Consignee and RecoveryDisposalFacility are the same operator, the consignee confirmation is omitted; acceptance is confirmed in a single call in stage 4. The status then goes from MOVING directly to RECEIVED, without a consignee certificate.
Several facilities, several strands
If the notification lists several facilities, each of them carries out its own reception and completion stages. Completion and acceptance belong together: the completion message must come from the same facility that confirmed acceptance.
Time limits¶
The regulation sets time limits for the confirmation of receipt and for the certificate of completed recovery or disposal. They are checked on the server side; the SDK passes violations up as validation errors.
Take the specific lengths of the time limits from the applicable text of the regulation — they differ between the notification procedure and the procedure under Annex VII, and depend on the respective triggering event.
“Working day” means Monday to Friday
The regulation’s term does not follow § 193 of the German Civil Code (Bürgerliches Gesetzbuch, BGB), which includes Saturday. If you calculate time limits according to the German legal understanding, your time limits come out too short. It is a one-liner in code — and a missed time limit if it is missing.
What’s next¶
- Notification (Company) — stage by stage with code
- Movement (Company) — stage by stage with code
- Roles — who may trigger which stage
- Calls and synchronization — call frequency, error handling, synchronization
- Error codes — what a rejection means