AI translation
This page was translated from German with AI. If in doubt, the German original applies.
Field rules¶
This page collects the rules that DIWASS enforces on the server side but that are not evident
from the schema: number formats, context-dependent notations, requirements beyond
minOccurs, cross-references between document parts, and the facility chain. The formats for BMU consignment
notes and acceptance notes are in the BMU section; they follow from
the BMU schema or the protos.
It is aimed at you if you are building client-side pre-validation or looking for the cause of a rejection.
Not covered here, but on the neighboring pages:
- Value lists (waste codes,
listID, R/D codes, packaging type,typeID) — Code lists - Meaning, notation and evaluation of the error codes — Error codes
Why the schema is not a sound basis for validation¶
The DIWASS XSD and the protos derived from it describe the structure of a document. They do not describe the rule DIWASS validates against. The discrepancy goes both ways:
| Direction | Example | What the schema says | What DIWASS does |
|---|---|---|---|
| Server stricter | CertificateOfWasteReceiptType.RejectedQuantity (movement receipt) |
minOccurs=0 |
rejects without the field (REJECTED-QUANTITY-EMPTY) |
| Server stricter | CertificateOfWasteReceiptType.RejectionDescription |
minOccurs=0, annotation: “Only filled in case of partial rejection” |
rejects without the field (REJECTION-DESCRIPTION-EMPTY) |
| Schema stricter / misleading | WasteCodeType.@listID |
Schema annotation names EWL, BASEL, YCODE as example values |
no longer accepts these old values — the valid tokens are different (Code lists) |
| Schema stricter / misleading | AttachmentBinaryObject.@mimeCode |
Token64, use="required", documentation example "image/png" |
no MIME allowlist; the controlled list is typeID |
The counterexample is in the same schema: RejectedQuantity has the same name in the Annex VII
branch, but there it sits on Annex7CertificateOfWasteReceiptType and is minOccurs=1. So
the difference between the two document types is intentional — it just isn’t reflected in the
movement schema.
Consequence for client-side validation
A pre-validation that evaluates only minOccurs/maxOccurs lets through documents that
DIWASS rejects. The hard rules are in the error codes, not in the schema — and the
specification’s validation list is not complete in this respect. See
Error codes.
There is no intermediate draft step via the API¶
That is why so many checks hit you on the very first call. The EU process descriptions are unambiguous on this point:
| Path | State after creation |
|---|---|
| User interface | Notification DRAFT, movement DRAFT — may be saved incomplete |
| API | Notification SUBMITTED, movement ANNOUNCED |
Everything the user interface checks only on submission, DIWASS checks immediately for an API caller. “Create it now and complete it later” does not exist in the API.
Notation of the error codes
On this page, the codes are consistently written in hyphenated form, as DIWASS reports them at runtime. The EU validation list lists the same codes with underscores. Details and normalization: Error codes → Notation.
Identifiers and number formats¶
Notification number¶
Structure: <CA code><YY><serial number>i.
| Part | Example from the specification sample | Example from existing data |
|---|---|---|
| CA code | BE01 |
DE01 |
| Year, two digits | 25 |
26 |
| Serial number | 000538 |
013237 |
| Suffix | i |
i |
| Result | BE0125000538i |
DE0126013237i |
The schema enforces none of this: model:NotificationIdentifierType is a token with
maxLength=100 and no pattern. The schema annotation merely mentions a convention — the
number starts “by convention” with the ISO 3166-1 alpha-2 code of the country of dispatch. The check
is made against the full authority code.
Generating and validating is handled by the DIWASS operation validateAndGenerateNotification. Its
request has exactly one mandatory field — caCode — plus, optionally, the NotificationID to be validated.
If the prefix does not match the code, DIWASS responds with statusCode=NOTOK and
INVALID-NOTIFICATION-CA-CODE-PREFIX (“Invalid CA code in notification number”).
The specification does not say which authority provides the code. It only speaks of “a valid
number based on the provided CA code”. What counts is the competent authority at the place of dispatch —
in the document Submission.ExportState.CompetentAuthority.CompetentAuthorityID, in the
notification document in box 15(b), column for the country of export/dispatch. As long as the notifier is registered with its
competent authority of dispatch, the difference from the registration authority goes unnoticed;
in the edge case it does not.
Authority codes come in two lengths
DIWASS keeps authority codes with four characters (DE01) and with five characters (DE014) — both occur
in the same dataset; the notification document typically shows the five-character form,
while the assigned number carries the four-character one. A naive StartsWith cannot tell the two lengths
apart and assigns a number to the wrong authority. Don’t just compare by
prefix; take the longest of all matching candidates.
MovementId and ZEDAL transport paper number¶
There are two formats for the same business sequence. They are not interchangeable.
| Number | Format | Example | Assigned by |
|---|---|---|---|
| DIWASS MovementId | <NotificationId>.<sequence>MOV |
DE0126005197i.000001MOV |
DIWASS when the movement template is created |
| ZEDAL transport paper number | <NotificationId>.<sequence> — five digits, without MOV |
DE0126013235i.00002 |
ZEDAL |
The stable handle within ZEDAL is the ZEDAL DocumentId, not the MovementId: a
DIWASS movement lives in exactly one ZEDAL document, in which all lifecycle phases
(Announcement, Carrier Transport, Consignee Reception, Facility Reception, Facility Completion)
are stored as blocks. The MovementId only exists after the first push and is merely an
index attribute on it. Hold on to the DocumentId across multi-step flows.
SequenceNumber¶
MovementDocumentType.SequenceNumber is mandatory (minOccurs=1) and of type
model:PositiveInteger8 — a positive integer with at most eight digits. It counts the
shipments within a notification, starting at 1.
The field’s XSD annotation is unambiguous: “A sequence number typically must not be reused. This also applies when shipments of waste are cancelled. The number of the cancelled shipment must not be reused for a new shipment.”
There is no reservation mechanism for movement sequences
For notification numbers, there is a server-side assignment path. For movement sequences there is not — the client determines the number. If you hard-wire it, you collide on the second run against the same notification.
In the .NET SDK, MovementDocumentHandler.GetNextSequenceNumber(notificationId) determines the
next free number from the transport paper index (filter on doc.notification_id, highest
numeric suffix + 1; 1 if none exists yet). With truly parallel creation on
the same notification, a race condition therefore cannot be ruled out.
Note the different number of digits: the DIWASS document allows up to eight digits, the ZEDAL transport paper number carries the sequence with five digits.
Operator identifiers¶
Every party in the document is a WasteOperatorType and carries two mandatory items:
| Field | Type | Meaning |
|---|---|---|
PartyUUID |
model:UuidType (pattern-checked), minOccurs=1 |
technical identifier of the party |
OperatorInternalID |
xs:long, minOccurs=1 |
identifier of the party in the DIWASS operator directory |
A name is not enough. You have to resolve the OperatorInternalID in the directory beforehand. The
.NET SDK provides IOperatorApi for this: FindOperatorForEori(eori),
FindOperatorByIdentifier(id, type), FindOperatorByName(name, countryId),
FindOperatorByQuery(query, countryId) and GetOperatorById(operatorId) for the details. The
search space is centrally restricted to the waste domain (Activity.Section = "WSR").
Permitted identifier types for the search:
| Type | Wire value | Origin |
|---|---|---|
| EORI | eori |
model:TracesPartyIdentificationSchemeIdentifierType |
| VAT (VAT identification number) | vat |
model:PartyIdentificationSchemeIdentifierType |
| NTR (trade register) | ntr |
model:PartyIdentificationSchemeIdentifierType |
| GLN (GS1) | gln |
model:PartyIdentificationSchemeIdentifierType |
In the XSD, the @type attribute is a free xs:token without restriction. In the spec samples,
the values are consistently lowercase; in practice, only eori and vat have been confirmed so far.
Error patterns around operator identifiers: OPERATOR-ID-NOT-FOUND, DUPLICATE-OPERATOR-ID and
the role-specific CARRIER-OPERATOR-DUPLICATE, WASTE-PRODUCER-OPERATOR-DUPLICATE,
TREATMENT-FACILITY-OPERATOR-DUPLICATE. So using the same identifier more than once in the same role
leads to rejection.
Attachment identifiers¶
A central DIWASS attachment ID has the form <digits>ATT, for example 26000015965ATT.
ZEDAL_TMP_ATT_ID_… is not a DIWASS identifier
If the returned identifier looks like ZEDAL_TMP_ATT_ID_<n>_<m>, it is a temporary
ZEDAL staging identifier. It is only valid for a retrieval via the same path. Used as
attachmentIdentifier on a DIWASS document, DIWASS responds to it with
ATTACHMENT-NOT-FOUND. A central identifier is returned by the raw SOAP path (ISoapProxyApi) to
the DIWASS operation submitAttach.
Two further observed edge cases: retrieving your own attachment that is not yet attached to
any document fails on the server side with HTTP 500; retrieving someone else’s
attachment responds cleanly with USER-AUTHORISATION-PERMISSION-AUTHORITY-DENIED — so the ID
alone is not enough, the permission must match the operator.
Context-dependent formats¶
Country code — two formats, two error patterns¶
The same business value has a different format depending on where it is used. This is the most common pitfall of all, because both error patterns lead to the same wrong diagnosis: “the authority doesn’t exist”.
| Context | Format | Example Belgium | If the form is wrong |
|---|---|---|---|
CountryID in the document (model:CountryCodeType, pattern \d\d\d) |
ISO 3166-1 numeric, three digits with leading zero | 056 |
Rejected at the schema already: SOAP fault, cvc-pattern-valid: Value '56' is not facet-valid with respect to pattern '\d\d\d'. The business logic is never reached. |
Directory lookup (FindActivities, ListAuthorities) |
ISO 3166-1 alpha-2 | BE |
0 hits, no error, no exception. |
Verified in the same test run: FindActivities("BE", code: "BE01") returns one hit (OVAM,
Afdeling Afvalstoffenbeheer, status VALID), FindActivities("056", code: "BE01") and
FindActivities("56", …) none.
The SDK validator does not protect you here
CountryIdValidator.Validate(...) lets both forms through — alpha-2 and three-digit
numeric. It only checks that one of the two is present at all. It cannot detect a mix-up
between the contexts. A value like "56" is neither and fails.
Value table and further notation pitfalls: Code lists → Country code.
Waste code¶
The code value itself is completely unchecked in the schema: WasteCodeType extends
model:Token64OrEmpty — a free token, at most 64 characters, no pattern, no enumeration.
The listID attribute is now also an empty restriction on xs:token. DIWASS validates both
only on the server side against the repository.
The most important rule in practice: EU waste codes go into the field with group spaces —
01 03 06, not 010306; hazardous ones additionally with an asterisk (01 04 07*). Everything else about
values, list tokens and upper/lower case is in the
Code lists.
Quantities¶
| Aspect | Rule |
|---|---|
| Structure | model:MassVolumeMeasureType has two children: MassMeasure and VolumeMeasure — both minOccurs=0. A structurally empty quantity is schema-valid. |
| Units | There is no unit field. Mass is always in metric tons, volume always in cubic meters. |
| Number format | model:Decimal25Fraction5Type — at most 25 digits in total, at most 5 decimal places. |
For missing quantities, the specification list includes MASS-VOLUME-NOT-FOUND.
Free text is multilingual¶
Every description field is a DescriptionType — a list of Description entries, each
with a languageID attribute. Two details that are loose in the schema and strict on the server:
| Aspect | Schema | Practice |
|---|---|---|
languageID |
optional attribute, pattern [a-z][a-z] — i.e. lowercase, de not DE |
DIWASS has MISSING-LANGUAGE-DESCRIPTION and INVALID-LANGUAGE-DESCRIPTION |
| Text length | model:String1024 — at most 1024 characters, at least 1 |
longer texts already fail at the schema |
Date and time fields¶
Date fields are xs:date without a time component — StartDate, ReceiptDate, CompletionDate,
RecoveryDisposalApproximateDate, DecisionDate. Only the signature time
(SignatureType.timestamp) is an xs:dateTime.
‘Working day’ means Monday to Friday
If you precompute deadlines from the Waste Shipment Regulation in the client: the term “Werktag” or “working day” there means Monday to Friday, not the German legal concept from § 193 of the German Civil Code (Bürgerliches Gesetzbuch, BGB), which includes Saturday. The Regulation does not define it; the German version translates the same English phrase “working days” sometimes as “Werktage”, sometimes as “Arbeitstage”. What counts is Regulation (EEC, Euratom) No 1182/71, Article 2(2) (“all days other than public holidays, Sundays and Saturdays”), confirmed by German enforcement practice (LAGA M25). Counting Monday to Saturday makes the deadline too short.
It remains open whose public holidays apply — with authorities in the countries of dispatch, transit and destination this is not clear-cut, and within Germany they differ by federal state. No verified source answers this.
Attachments: which field is really controlled¶
An attachment (AttachmentBinaryObject) carries four mandatory attributes. Only one of them is a
controlled list — and it is not the one you would expect:
| Attribute | Type | Controlled? |
|---|---|---|
typeID |
BinaryAttachmentClassificationCodeType |
yes — a real XSD enumeration with 27 values (FacilityPermit, LiabilityInsurance, FinancialGuarantee, WasteAnalysis, OtherAnnex, …). Business classification of the document, not a file format. Full list: Code lists |
mimeCode |
Token64, use="required" |
no — free string, max. 64 characters, no enumeration, no pattern. The "image/png" in the schema documentation is an example, not a restriction. There is no MIME allowlist. |
filename |
NameType, max. 256 characters, use="required" |
no |
containsPersonalData |
xs:boolean, use="required" |
— |
The catch-all category among the typeID values requires an additional explanation: the
specification list includes ATTACHMENT-TYPE-OTHER with the key
waste.error.attachment.type.other.no.comment. The specification does not say in which field the
explanation is expected.
Mandatory fields beyond the schema¶
The following fields are optional in the XSD but required by DIWASS. The Evidence column distinguishes where the rule comes from:
- measured — actually occurred in the integration
- specification list — entry in the EU validation list; the exact trigger is not described there
| Field | XSD cardinality | Server rule | Error code | Evidence |
|---|---|---|---|---|
Submission.Notifier |
minOccurs=0 |
mandatory | NOTIFIER-OPERATOR-IS-REQUIRED |
specification list |
Submission.Consignee |
minOccurs=0 |
mandatory | CONSIGNEE-OPERATOR-IS-REQUIRED |
specification list |
Submission.Carrier |
minOccurs=0, maxOccurs=unbounded |
at least one | CARRIER-OPERATOR-IS-REQUIRED |
specification list |
Submission.WasteProducer |
minOccurs=0, maxOccurs=unbounded |
at least one | WASTE-PRODUCER-OPERATOR-IS-REQUIRED |
specification list |
Submission.ExportState |
minOccurs=0 |
mandatory | DISPATCH-IS-REQUIRED |
specification list |
Submission.ImportState |
minOccurs=0 |
mandatory | DESTINATION-IS-REQUIRED |
specification list |
PartyType.Contact per party |
minOccurs=0 |
mandatory, checked per role | NOTIFIER-CONTACT-IS-REQUIRED, CONSIGNEE-CONTACT-IS-REQUIRED, PRODUCER-CONTACT-IS-REQUIRED, CARRIER-CONTACT-IS-REQUIRED, FACILITY-CONTACT-IS-REQUIRED |
specification list |
Submission.ShipmentOriginAddress |
The element is mandatory, but the type is a choice of two optional elements — an empty structure is schema-valid |
mandatory in substance | SHIPMENT-ORIGIN-ADDRESS-REQUIRED, alongside SHIPMENT-ORIGIN-ADDRESS-BAD and SHIPMENT-ORIGIN-ADDRESS-PARTY |
specification list |
Submission.PhysicalCharacteristicDescription |
minOccurs=0 |
conditionally mandatory | PHYSICAL-CHARACTERISTICS-DESCRIPTION-REQUIRED |
specification list |
LanguageDescriptionType.@languageID |
optional attribute | mandatory | MISSING-LANGUAGE-DESCRIPTION |
specification list |
CertificateOfWasteReceiptType.RejectedQuantity (movement receipt) |
minOccurs=0 |
mandatory | REJECTED-QUANTITY-EMPTY |
measured |
CertificateOfWasteReceiptType.RejectionDescription (movement receipt) |
minOccurs=0, annotation “only in case of partial rejection” |
mandatory | REJECTION-DESCRIPTION-EMPTY |
measured |
The last two rows are not in any version of the specification list
REJECTED-QUANTITY-EMPTY and REJECTION-DESCRIPTION-EMPTY occurred in the integration
and are not contained in the EU validation list — a full-text search across the
list returns zero hits for REJECT and zero for QUANTITY. Expect further
codes to be missing, and treat every unknown code as a valid rejection.
Fields you are better off omitting¶
ShipmentOriginAddress in the movement¶
Same field, two document types, two cardinalities:
| Document | Cardinality |
|---|---|
Notification (SubmissionType.ShipmentOriginAddress) |
mandatory |
Movement (MovementDocumentType.ShipmentOriginAddress) |
minOccurs=0, maxOccurs=1 |
If the field is set in the movement, DIWASS compares it against the origin address of the consented
notification and rejects any deviation with
MOVEMENT-SHIPMENT-ORIGIN-ADDRESS-MISMATCH-NOTIFICATION. If it is omitted, DIWASS takes the
address from the notification and the push goes through.
Measured: with a hard-wired address, CreateMovementTemplate failed with exactly this code;
without the field, the same push went through.
Default: don’t set it
An origin address hard-wired in the client couples the entire movement path to exactly one notification and breaks silently as soon as its address differs or you switch to a different notification. The error text does say “mismatch”, but it usually points to outdated master data in the client, not to a broken movement.
movementIdentifier on creation¶
MovementTemplateType.movementIdentifier is minOccurs=0. On create, leave it empty —
DIWASS assigns the MovementId and returns it in the response
(MovementTemplateOperationResponse.movementId). On update, it must be set.
Fields that don’t exist¶
Waste designation on movement receipt¶
The DIWASS user interface requires a mandatory field “Designation and composition of the waste received” on movement receipt. In the API, this field does not exist there.
| Type | Field present? |
|---|---|
Annex7CertificateOfWasteReceiptType (Annex VII) |
yes — WasteDesignationCompositionDescription, minOccurs=1 |
Annex7CertificateOfCompletionType (Annex VII) |
yes — wasteDesignationCompositionDescription |
CertificateOfWasteReceiptType (movement receipt) |
no |
CertificateOfWasteReceiptBaseType (consignee receipt) |
no — only carries RecipientParty, ReceiptDate, AdditionalInformation |
TransportAnnouncementType (movement announcement) |
no |
The related field in the movement/notification branch is called
SubmissionType.WasteDesignationDescription — without “Composition” — and sits on the
notification (mandatory, box 12 of Annex IA), not on the receipt certificate. The XSD annotation
on the movement’s WasteClassification explicitly refers there for additional information.
Not a single DIWASS type carries both fields. So it is not a type mix-up but a divergence between user interface and API on the EU side. On movement receipt, this information cannot be transmitted.
Cross-references the server checks¶
DIWASS validates not only individual fields but also relationships between document parts and between documents. The schema expresses none of them.
Intended number of shipments¶
Submission.ShipmentQuantity (model:PositiveInteger8, mandatory) is, according to the XSD annotation, “the
total intended number of shipments under this notification” — box 4 of Annex IA. The number of
movement documents created must not exceed this value.
A properly canceled movement document does not count, but one left lying around does (Implementing Regulation (EU) 2025/1290, Article 17(7) and (8)). Combined with the rule that sequence numbers must not be reused, this means: cancel cleanly instead of leaving drafts lying around.
Error code from the specification list: MOVEMENT-TEMPLATE-INVALID-TOTAL-NUMBER.
Competence of the authority of transit¶
AUTHORITY-ID-NOT-FOUND is a statement about competence, not existence
Not every WSR authority may act as competent authority of transit — and the authority directory does not say
which. If you name an authority without transit competence in Submission.TransitState,
DIWASS rejects the notification with AUTHORITY-ID-NOT-FOUND: Authority <code> not found,
even though the authority exists and has Status=VALID.
Verified by a contrasting pair in the same test run: BE004 and BE002 are accepted as transit CA,
BE01 (OVAM) and BE003 are rejected. Most clearly with DE014 — the same authority is accepted in the
same document as export and import CA and rejected as transit CA.
The directory does not help here: all eleven Belgian authorities return identical activity data in
FindActivities("BE"). Authorities with and without transit competence cannot be
distinguished in it. An authority picker in the client therefore cannot check suitability in advance
today — the error only surfaces on submission. Plan for the rejection as a normal
flow, not as an exception.
A second, independent route to the same message: the numeric country code in the directory lookup (see above). With such a symptom, first determine which of the two paths produced it.
R/D identifier in four places¶
The distinction between recovery and disposal appears several times in one process:
| Place | Field | Range of values |
|---|---|---|
| Notification, overall statement | Submission.DestinedForRecoveryDisposal |
R / D |
| Notification, per facility | RecoveryDisposalFacilityType.FacilityTypeCode |
R / D |
| Notification, planned operations | DisposalRecoveryOperations.RecoveryDisposalTypeCode (mandatory, unbounded) |
R1–R13, D1–D15 |
| Movement, receipt certificate | CertificateOfWasteReceiptType.FacilityTypeCode and .RecoveryDisposalTypeCode |
R/D or R1–R13, D1–D15 |
The schema does not couple these places — each one is valid on its own. The specification list includes
DISPOSAL-RECOVERY-DOES-NOT-MATCH; which of the places DIWASS checks against each other is not
stated there. Keep them consistent.
Code list of the R/D operations: Code lists.
Pre-consented facility¶
Submission.PreConsentIndicator is a mandatory Boolean. The specification list includes two
dedicated error codes for it — DESTINED-PRE-CONSENT-REQUIRED and FACILITY-NOT-PRE-CONSENTED. So don’t set the
flag to true across the board; the list does not describe under which conditions the two codes
are triggered.
Receipt and completion belong to the same facility¶
The movement specification is unambiguous: “Completion must be done by/for the SAME facility which received.” The schema does not enforce this. Receipt and completion certificates have separate document IDs and no foreign key to each other.
You have to establish the pairing yourself — via RecipientParty ↔ RecoveryDisposalParty or
ActualSiteOfDisposalOrRecovery, not via list positions. Both lists are
unbounded in retrieval; their order carries no meaning.
Immutable information¶
After a notification has been created, the countries concerned, the authorities concerned and the
notifier can no longer be changed — according to the EU process description. Error codes:
OPERATORS-CANNOT-CHANGE, AUTHORITIES-CANNOT-CHANGE.
For everything else: a submitted notification can only be changed while at least one
request for additional information is open. The corresponding code is HAS-REQUEST-INFORMATION-OPEN. Details on the
change window: Lifecycle.
Not verified¶
Whether DIWASS checks a movement’s carrier against the notification’s carrier list is neither
described in the specification nor measured by us. All that is known is that
TransportAnnouncement.Carrier is mandatory and unbounded in the movement, while
Submission.Carrier in the notification is schema-optional, and that the specification list
includes MULTIPLE-DOC-FOR-CARRIER (waste.error.multiple.documents.same.carrier).
Facility chain¶
A DIWASS notification does not describe a single receiving facility but a chain.
Submission.RecoveryDisposalFacility is minOccurs=1, maxOccurs=unbounded (box 10) — the
notification lists 1 + n facilities. The reason is Article 15 of Regulation (EU) 2024/1157: if a shipment goes
to interim recovery or disposal, all subsequent facilities must be stated in the document in addition to the
first one.
Three Booleans per facility¶
Every facility carries FacilityType.OperationalIndicators
(FacilityOperationalIndicatorsType). All three fields are mandatory:
| Indicator | Meaning | Consequence |
|---|---|---|
InterimFacility |
The facility carries out an interim operation | Article 15(1): all facilities where the subsequent treatment is planned must be listed in the notification document in addition to the first interim facility |
NextSubsequentInterimOrNonInterimFacilityInSameCountry |
Passing on to a facility in the country of destination | Article 15(5): no new notification, no new movement. The proof comes back as an Article 15 certificate on the notification. |
NextSubsequentInterimOrNonInterimFacilityInAnotherCountry |
Passing on to the country of dispatch, another Member State or a third country | Article 15(7)/(8): new notification with its own movements |
The cross-border case is a new process, not a follow-up step
Within the country of destination, the chain is only extended on paper — no new movements are created. If, on the other hand, the delivery crosses the border, you need a completely new notification with its own number range, its own set of authorities and its own movements.
Plan for this in the data model: the transition is not a status change on an existing
process but the start of a second one. A field that explicitly links the new notification
to its predecessor is not described in the specification —
according to the schema annotation, referenceNotificationId is the number of the notification itself, assigned by the competent authority of dispatch,
not a reference to a predecessor. You have to maintain the link
yourself.
Exactly one facility closes the chain¶
The specification list includes two dedicated error codes for this:
| Code | Key |
|---|---|
NON-SUBSEQUENT-FACILITY-IS-REQUIRED |
waste.notification.non.subsequent.facility.must.exist |
NON-SUBSEQUENT-FACILITY-MANY |
waste.notification.non.subsequent.facility.many |
At least one facility without a subsequent facility must be present, and more than one is too many. Following the
logic of the indicators, a facility closes the chain when both NextSubsequent… fields
are false — the specification does not spell this out explicitly.
Article 15 certificate is attached to the notification¶
Not to the movement. FacilityCompletionUnderArticle15Type carries:
| Field | Cardinality |
|---|---|
notificationId |
minOccurs=1 |
movementIdentifier |
minOccurs=1, maxOccurs=unbounded |
recoveryDisposalParty, wasteClassification, completionDate, acceptedQuantity |
minOccurs=1 each |
That movementIdentifier is unbounded is no accident: a subsequent facility processes material
from several shipments, the relationship is n:m, and the certificate names the shipments
it covers.
In the .NET SDK:
NotificationDocumentHandler.SetFacilityCompletionUnderArticle15(FacilityCompletionUnderArticle15Type).
The movement status aggregates across the chain¶
facilityReception and facilityCompletion are both unbounded in retrieval, while
consigneeReception is set to maxOccurs="1". According to the EU specification, the status transitions
each hinge on the first event:
ANNOUNCED→MOVING: on the first carrier transfer certificateANNOUNCED/MOVING→RECEIVED: on the first receipt certificateRECEIVED→COMPLETED: on the completion certificate
RECEIVED means ‘at least one facility has acknowledged’
Not “the receiving facility has” and certainly not “all of them have”. With an interim facility,
it is the first station. Likewise, COMPLETED does not mean that the recovery chain
is complete — the interim operation is a completion; the proof of the
subsequent operation still follows afterwards, namely on the notification as an
Article 15 certificate. A user interface that shows “done” on COMPLETED claims more
than the status supports.
Details on the status values and where to find them in the document: Lifecycle.
BMU (consignment note and acceptance note)¶
The rules apply to BGSDokument and UNSDokument. How strictly the service validates is set by
XmlOptions.validation, see BMU guide → Validation and draft.
| Field | Rule |
|---|---|
bgs_nr |
14 characters: “1” followed by 13 digits |
uns_nr, uns_nrn |
14 characters: “2” followed by 13 digits |
nachweis_nr |
12 characters: “EN” or “SN”, one letter from ABCDEFGHIKLMNPRS, then 9 characters |
abfallschluessel |
6 digits according to the German List of Waste ordinance (Abfallverzeichnis-Verordnung, AVV), without spaces |
menge |
in metric tons; up to 8 digits, of which 3 decimal places |
volumen |
in cubic meters; up to 8 digits, of which 3 decimal places |
abfallbezeichnung |
at most 255 characters |
vermerke |
at most 64000 characters |
You do not enter the unit; it is fixed in the schema. Unlike DIWASS, the waste code goes into the
field here without group spaces. bgs_nr, uns_nr and nachweis_nr carry a check digit
(pruefziffer) next to the number (nr); the service checks it by default and calculates it with
XmlOptions.pruefziffer = PRUEFZIFFER_CALCULATE.
Further reading¶
- Code lists — value lists and notations
- Error codes — complete catalog, evaluation, normalization
- DIWASS guides — flow of notification and movement
- BMU guide — consignment note and acceptance note