# HybridmailDpagSpecification.md ## 1. Document Status **Document:** HybridmailDpagSpecification.md **Project:** hybridmail-connect **Provider Flavor:** Deutsche Post / E-POSTBUSINESS API **Parent Specification:** HybridmailAdapterSpecification.md **Target Integration:** coordination-engine **Adapter Contract:** AdapterInterfaceSpecification.md v1.0 **Status:** Draft v1.0 **Primary Scope:** Deutsche Post / E-POSTBUSINESS hybrid-mail provider flavor for PDF mail-shipment submission, one-by-one and bulk upload, validation, address-window positioning, cover-sheet handling, scheduled dispatch, production status, shipment tracking, registered-mail products, and delivery/return evidence mapping. ## 2. Purpose This document specifies the Deutsche Post / E-POSTBUSINESS API provider flavor for `hybridmail-connect`. The DPAG flavor implements the generic hybrid-mail adapter model for the Deutsche Post E-POSTBUSINESS API / Deutsche Post Hybrid Mail Shipments E-POST API family. It maps Deutsche Post’s hybrid-mail API concepts into the provider-neutral hybrid-mail model used by `coordination-engine`. The purpose of this document is to capture: * DPAG/E-POSTBUSINESS-specific provider capabilities. * DPAG-specific workflow stages. * PDF mail-shipment submission. * Single and bulk upload handling. * Production and shipment-status mapping. * Address-window positioning and automatic positioning semantics. * Individual cover-sheet support where available. * Scheduled dispatch semantics. * Registered-mail and delivery-tracking semantics. * PDF/PDF-A requirements and validation. * DPAG-specific evidence event mapping. * DPAG-specific limitations and assumptions. * DPAG-specific MVP boundaries. The DPAG flavor MUST remain compatible with `HybridmailAdapterSpecification.md` and MUST NOT leak DPAG-specific terminology into the core coordination model except through mapped provider metadata. ## 3. Grounding Summary The public Deutsche Post / DHL developer and product material indicates the following relevant features: * The Deutsche Post Hybrid Mail Shipments E-POST API is intended for business customers sending PDF documents as mail shipments with Deutsche Post. * The API expects single PDF documents for mail shipments. * It supports one-by-one and bulk upload. * It provides detailed shipment processing information. * It supports bulk status requests. * It provides focused information for suppliers. * It supports varied mail shipments of Deutsche Post with E-POST. * It supports tracking the shipment from uploading through delivery. * The broader E-POSTBUSINESS API is described as a REST API with Swagger documentation. * It offers detailed shipment-level status information, including production data and shipment tracking. * It supports individual submission through mass submission. * It includes address-window positioning aids, automatic positioning, individual cover sheets, and scheduled dispatch. * It includes hybrid dispatch services where digital documents are printed, enveloped, franked, and delivered as physical letters. * Registered-letter use cases are part of the public API/product description. * PDF/A-1b knowledge is explicitly relevant in public API notes. * Activation, business-software partner setup, API access data, and technical login/access handling are part of the adoption model. These facts define the baseline for this provider flavor. ## 4. Provider Flavor Identity ```yaml id="7qj3nr" HybridmailProviderFlavorDescriptor: provider_name: dpag_epost provider_label: Deutsche Post E-POSTBUSINESS API / Hybrid Mail Shipments E-POST provider_family: hybridmail adapter_contract_version: "1.0" parent_specification: HybridmailAdapterSpecification.md deployment_mode: external ``` ## 5. DPAG Capability Descriptor The DPAG flavor MUST expose a capability descriptor. ```yaml id="bs763g" HybridmailProviderFlavorDescriptor: provider_name: dpag_epost provider_version: provider_specific supported_file_types: - pdf - pdfa supported_attachment_file_types: - provider_specific supports_single_letter: true supports_bulk: true supports_serial_letters: true supports_attachments: provider_specific supports_preview: provider_specific supports_webhooks: provider_specific supports_polling: true supports_bulk_status_requests: true supports_supplier_focused_status: true supports_registered_mail: true supports_delivery_confirmation: product_dependent supports_return_mail: provider_specific supports_address_correction: provider_specific supports_international_mail: true supports_cancellation: provider_specific supports_staging: true supports_idempotency: adapter_managed_or_provider_specific supports_rate_limits: true supports_scheduled_dispatch: true supports_address_window_positioning: true supports_automatic_positioning: true supports_cover_sheet: true supports_pdfa_validation: true supports_production_status: true supports_shipment_tracking: true supports_gogreen_plus: true supported_print_options: color_mode: provider_specific simplex_duplex: provider_specific envelope_selection: provider_specific address_position: true automatic_positioning: true cover_sheet: true supported_postal_products: - standard - registered - registered_return_receipt - delivery_confirmation - international - provider_specific limitations: - Public documentation confirms upload-to-delivery tracking, but exact native status names and semantics must be implemented against the active API documentation and account configuration. - Registered-mail and delivery-confirmation evidence are product-dependent. - Ordinary letters may provide strong production and postal-chain evidence without proving human awareness. - PDF/PDF-A and address-window constraints must be treated as provider-specific validation concerns. - Idempotency should be adapter-managed unless the active API endpoint provides native idempotency semantics. - Cancellation semantics are provider-specific and likely time-sensitive. ``` ## 6. DPAG-Specific Conceptual Workflow The DPAG flavor uses a PDF mail-shipment workflow. ```text id="reoa08" authenticate / obtain access → prepare PDF or PDF/A document → submit single or bulk mail shipment → validate PDF, address, product, and layout constraints → optionally apply address-window positioning / automatic positioning / cover sheet → optionally schedule dispatch → provider accepts shipment → production processing → print / envelope / frank → postal handover → shipment tracking / registered-mail tracking where supported → delivery, return, or unknown final status depending on product and evidence ``` The adapter MUST preserve this distinction: ```text id="ypwf4z" PDF upload is not validation success. Validation success is not sending. Sending/production is not postal handover. Postal handover is not necessarily final delivery confirmation. Delivery tracking is product- and status-dependent. ``` ## 7. DPAG Object Mapping ## 7.1 Generic to DPAG Mapping | Generic hybrid-mail concept | DPAG flavor concept | | --------------------------- | ------------------------------------------------------------------------------------------------------ | | `HybridmailLetter` | DPAG mail shipment / E-POST shipment | | `HybridmailDocumentRef` | PDF/PDF-A document submitted for mail shipment | | `HybridmailAttempt` | DPAG upload/submission/status operation | | `HybridmailBatch` | Bulk upload / mass submission | | `PostalRecipient` | Address extracted from PDF, positioned in address window, or provided through metadata where supported | | `HybridmailOptions` | DPAG shipment, product, print, positioning, scheduling, and cover-sheet options | | `HybridmailPreview` | Provider-specific preview or validation representation if supported | | `HybridmailTimeline` | DPAG upload, production, shipment, tracking, and return timeline | ## 7.2 DpagShipment ```yaml id="5wcgbn" DpagShipment: dpag_shipment_id: string hybridmail_letter_id: string? coordination_case_id: string? participant_id: string? provider_status: string? normalized_status: string document_ref: DpagDocumentRef recipient: PostalRecipient? sender: PostalSender? options: DpagShipmentOptions? production_data_ref: string? tracking_ref: string? registered_mail_ref: string? created_at: timestamp updated_at: timestamp? metadata: object? ``` ## 7.3 DpagDocumentRef ```yaml id="c50301" DpagDocumentRef: dpag_document_id: string? hybridmail_document_id: string original_file_ref: ResourceRef document_type: pdf | pdfa | unknown pdfa_profile: pdfa_1b | provider_specific | none | unknown file_size_bytes: integer? page_count: integer? sheet_count: integer? integrity_hash: string? validation_result: DpagValidationResult? created_at: timestamp metadata: object? ``` ## 7.4 DpagSubmissionAttempt ```yaml id="ps6n1n" DpagSubmissionAttempt: dpag_attempt_id: string hybridmail_letter_id: string? hybridmail_batch_id: string? provider_operation_id: string? idempotency_key: string operation_type: upload_single | upload_bulk | validate | submit | status_poll | bulk_status_poll | cancel | tracking_poll state: pending | accepted | rejected | failed | completed | duplicate | unknown created_at: timestamp updated_at: timestamp? raw_provider_response_ref: string? ``` ## 7.5 DpagBatch ```yaml id="k7g0d2" DpagBatch: dpag_batch_id: string? hybridmail_batch_id: string coordination_case_id: string? batch_type: bulk | mass_submission | serial | mixed | unknown shipments: - dpag_shipment_id state: pending | partial | completed | failed | unknown created_at: timestamp updated_at: timestamp? bulk_status_ref: string? ``` Batch-level status MUST NOT be treated as success for every child shipment unless DPAG status data provides per-shipment evidence or scenario policy explicitly accepts batch-level evidence. ## 8. DPAG Address and Positioning Model Public material explicitly mentions address-window positioning aids and automatic positioning. The DPAG flavor MUST model address positioning as a first-class provider concern. ```yaml id="aob25f" DpagAddressPositioning: mode: fixed_window | automatic_positioning | cover_sheet | metadata | provider_default | unknown window_position: left | right | provider_specific | unknown page_number: integer? bounding_box: object? provider_positioning_result: string? confidence: low | medium | high ``` Generic postal recipient mapping: ```yaml id="ew9cwa" PostalRecipient: recipient_id: string? name_lines: - string organization: string? street: string? house_number: string? address_addition: string? postal_code: string? city: string? region: string? country_code: string? country_name: string? address_source: extracted_from_document | provided_metadata | provider_detected | cover_sheet | manual | unknown address_quality: PostalAddressQuality? ``` If automatic positioning or cover-sheet generation changes where the address appears in the physical output, the adapter MUST preserve that fact in metadata. ## 9. DPAG Cover Sheet Model Public material references individual cover sheets. The adapter SHOULD model cover-sheet use explicitly. ```yaml id="c5w0y6" DpagCoverSheet: enabled: boolean cover_sheet_type: individual | provider_default | provider_specific | unknown recipient_source: metadata | extracted | provided | unknown sender_source: metadata | provided | provider_default | unknown template_ref: string? generated_document_ref: ResourceRef? metadata: object? ``` Cover-sheet generation is a production preparation step. It does not prove physical dispatch. ## 10. DPAG Scheduled Dispatch Model Public material references scheduled dispatch. The adapter SHOULD model dispatch timing. ```yaml id="zr33sn" DpagScheduledDispatch: dispatch_mode: immediate | scheduled | provider_default | unknown desired_dispatch_date: date? desired_dispatch_time_window: string? schedule_status: not_scheduled | scheduled | missed | cancelled | completed | unknown metadata: object? ``` Scheduled dispatch affects policy interpretation: ```text id="8bh4mo" A letter scheduled for future dispatch should remain pending until the scheduled production/dispatch window begins. ``` ## 11. DPAG Shipment Options The DPAG flavor MUST map DPAG options into generic `HybridmailOptions`. ```yaml id="2lo1jt" DpagShipmentOptions: color_mode: color | grayscale | provider_default | unknown print_sides: simplex | duplex | provider_default | unknown envelope_type: c5 | c4 | window_left | window_right | provider_default | unknown address_positioning: DpagAddressPositioning? cover_sheet: DpagCoverSheet? postage_product: standard | registered | registered_return_receipt | delivery_confirmation | international | provider_specific country_scope: domestic | international | unknown scheduled_dispatch: DpagScheduledDispatch? return_mail_handling: none | provider_processed | physical_return | digital_return_info | unknown gogreen_plus: boolean? metadata: object? ``` Provider-native option names MUST be preserved in metadata. The adapter MUST NOT assume support for a product unless the DPAG capability descriptor confirms it for the active account/API context. ## 12. DPAG Validation Model DPAG validation results MUST be mapped into generic `HybridmailValidationResult`. ```yaml id="y66riu" DpagValidationResult: dpag_shipment_id: string? dpag_document_id: string? provider_validation_state: string? validation_state: pending | passed | action_required | failed | unknown issues: - DpagValidationIssue validated_at: timestamp? raw_provider_response_ref: string? ``` ```yaml id="ucmvxb" DpagValidationIssue: provider_issue_code: string? issue_code: string severity: info | warning | action_required | fatal category: format | pdf | pdfa | page_size | address | address_position | restricted_area | cover_sheet | margins | file_size | page_count | postage | country | scheduled_dispatch | provider_policy | unknown message: string page_number: integer? bounding_box: object? fixable: boolean? ``` ## 13. DPAG Validation Issue Mapping | DPAG validation concern | Generic validation category | Normalized issue code | | ----------------------------------- | ----------------------------- | ---------------------------------- | | Invalid PDF | `pdf` / `format` | `invalid_pdf` | | PDF/A-1b issue | `pdfa` | `invalid_pdfa_1b` | | Unsupported file type | `format` | `unsupported_file_type` | | Page or file constraint violated | `page_count` / `file_size` | `document_constraint_violation` | | Address not detected | `address` | `address_not_detected` | | Address-window problem | `address_position` | `address_position_invalid` | | Automatic positioning failed | `address_position` | `automatic_positioning_failed` | | Cover sheet generation failed | `cover_sheet` | `cover_sheet_failed` | | Restricted-area or margin violation | `restricted_area` / `margins` | `layout_restricted_area_violation` | | Unsupported destination country | `country` | `unsupported_country` | | Postal product invalid | `postage` | `unsupported_product` | | Scheduled dispatch invalid | `scheduled_dispatch` | `scheduled_dispatch_invalid` | | Provider policy rejection | `provider_policy` | `provider_policy_rejected` | | Unknown validation issue | `unknown` | `unknown_validation_issue` | Validation failure MUST emit: ```text id="wrwvgy" payload.validation_failed ``` Validation success MUST emit: ```text id="ybc5gu" payload.validation_passed ``` Warnings MAY allow processing to continue, but the warning MUST be preserved in metadata. ## 14. DPAG Status Model The DPAG flavor MUST preserve raw provider status and map it to normalized status. ```yaml id="5o3jui" DpagStatusRecord: status_record_id: string dpag_shipment_id: string? dpag_batch_id: string? provider_status: string normalized_status: string status_scope: upload | validation | production | shipment | tracking | registered_mail | bulk | supplier | unknown observed_at: timestamp raw_provider_response_ref: string? ``` ## 15. Normalized DPAG Status Categories The DPAG flavor SHOULD map native statuses into these normalized categories: ```text id="k3jagx" shipment.created shipment.uploaded shipment.validation_pending shipment.validation_passed shipment.validation_failed shipment.action_required shipment.ready_for_sending shipment.scheduled shipment.submitted_for_sending shipment.processing shipment.production_started shipment.production_completed shipment.handed_to_postal_service shipment.in_transit shipment.delivery_confirmed shipment.registered_event shipment.undeliverable shipment.return_received shipment.cancelled shipment.failed shipment.status_unknown ``` Where DPAG status granularity is insufficient, the adapter MUST use the nearest weaker event and preserve raw status in metadata. ## 16. DPAG Production Data Model Public documentation references production data. The adapter SHOULD model production-stage evidence separately from postal-stage evidence. ```yaml id="oia4p4" DpagProductionData: dpag_shipment_id: string production_status: pending | started | completed | failed | unknown print_status: pending | printed | failed | unknown enveloping_status: pending | enveloped | failed | unknown franking_status: pending | franked | failed | unknown production_site_ref: string? production_started_at: timestamp? production_completed_at: timestamp? raw_provider_response_ref: string? ``` Production completion does not prove postal handover unless the provider status explicitly supports that interpretation. ## 17. DPAG Tracking Model Public documentation references shipment tracking from upload through delivery. The adapter SHOULD model tracking as a separate status stream. ```yaml id="ry1ic0" DpagTrackingEvent: tracking_event_id: string dpag_shipment_id: string provider_tracking_id: string? tracking_type: production | postal | registered_mail | delivery_confirmation | return | unknown provider_status: string normalized_status: string occurred_at: timestamp? observed_at: timestamp raw_provider_response_ref: string? metadata: object? ``` Tracking events MUST be mapped according to their actual semantics. For ordinary mail, a tracking stage may indicate process progress without proving delivery. For registered mail or delivery-confirmation products, tracking events may provide stronger physical-delivery evidence. ## 18. DPAG Registered Mail Model The public API material references registered-letter use cases and varied mail shipments. ```yaml id="7r9xqo" DpagRegisteredMail: dpag_shipment_id: string registered_product_type: registered | registered_return_receipt | delivery_confirmation | provider_specific registered_tracking_id: string? status: created | in_transit | delivery_attempted | delivered | refused | returned | undeliverable | unknown delivery_confirmation_ref: ResourceRef? recipient_signature_ref: ResourceRef? occurred_at: timestamp? observed_at: timestamp? raw_provider_response_ref: string? ``` The adapter MUST only emit: ```text id="3sgj7j" delivery.postal.delivery_confirmed ``` when the DPAG status and selected postal product semantically support delivery confirmation. Ordinary letter dispatch MUST NOT be mapped to `delivery.postal.delivery_confirmed`. ## 19. DPAG Bulk Status Model The API supports bulk upload and bulk status requests. The adapter MUST support per-shipment state under a batch. ```yaml id="43ernq" DpagBulkStatus: dpag_batch_id: string status_observed_at: timestamp batch_status: pending | partial | completed | failed | unknown child_statuses: - DpagChildShipmentStatus raw_provider_response_ref: string? ``` ```yaml id="62finx" DpagChildShipmentStatus: dpag_batch_id: string dpag_shipment_id: string hybridmail_letter_id: string? participant_id: string? provider_status: string normalized_status: string evidence_event_refs: - string updated_at: timestamp? metadata: object? ``` Batch-level acceptance MUST NOT be treated as per-recipient success without child-shipment evidence. ## 20. DPAG-to-Generic Event Mapping | DPAG workflow event | Generic event | Evidence interpretation | | ----------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------- | | PDF upload accepted | `delivery.payload.accepted` | Digital submission accepted | | PDF upload rejected | `delivery.payload.rejected` | Attempt failed | | Validation passed | `payload.validation_passed` | Document is provider-processable | | Validation failed | `payload.validation_failed` | Document/action must be corrected | | Automatic positioning applied | `delivery.payload.available` with positioning metadata | Operational readiness, not dispatch | | Cover sheet generated | `delivery.payload.available` with cover-sheet metadata | Operational readiness | | Scheduled dispatch accepted | `delivery.payload.available` with schedule metadata | Future dispatch pending | | Submitted for sending | `delivery.payload.submitted` | Provider instructed to send | | Production started | `delivery.production.started` | Provider production began | | Production completed | `delivery.production.completed` | Physical production completed | | Handed to postal service | `delivery.postal.handed_over` | Strong dispatch evidence | | Tracking in transit | `delivery.postal.in_transit` | Postal tracking evidence | | Registered tracking event | `delivery.postal.in_transit` or `delivery.postal.delivery_confirmed` depending status | Product-dependent | | Delivery confirmed | `delivery.postal.delivery_confirmed` | Strong physical-delivery evidence | | Undeliverable | `delivery.postal.undeliverable` | Strong negative delivery evidence | | Return received | `delivery.postal.return_received` | Strong negative evidence | | Bulk status child failed | child-level event | Per-recipient failure | | Bulk status child completed | child-level mapped event | Per-recipient progress | ## 21. Evidence Grading Rules ### 21.1 DPAG PDF Upload Accepted ```yaml id="ms003r" event_type: delivery.payload.accepted evidence_grade: strength: weak actor_certainty: none authority_certainty: none payload_certainty: medium interaction_certainty: none timing_certainty: medium channel_certainty: medium non_repudiation_strength: low notes: - DPAG accepted the digital PDF upload into the API workflow. - This does not prove validation, production, postal handover, or delivery. ``` ### 21.2 DPAG Validation Passed ```yaml id="3qhzvf" event_type: payload.validation_passed evidence_grade: strength: medium actor_certainty: none authority_certainty: none payload_certainty: high interaction_certainty: none timing_certainty: high channel_certainty: high non_repudiation_strength: low notes: - DPAG validation passed or the shipment is processable according to provider status. - This does not prove sending or postal handover. ``` ### 21.3 DPAG Validation Failed ```yaml id="jt0dxl" event_type: payload.validation_failed evidence_grade: strength: negative actor_certainty: none authority_certainty: none payload_certainty: high interaction_certainty: none timing_certainty: high channel_certainty: high non_repudiation_strength: low notes: - DPAG reported a document, address, layout, PDF/PDF-A, product, or policy issue. - The issue should be categorized and preserved. ``` ### 21.4 DPAG Production Started ```yaml id="24mb0j" event_type: delivery.production.started evidence_grade: strength: medium actor_certainty: none authority_certainty: none payload_certainty: high interaction_certainty: none timing_certainty: medium channel_certainty: high non_repudiation_strength: low notes: - DPAG status indicates production processing started. - The exact native status should be preserved in metadata. ``` ### 21.5 DPAG Production Completed ```yaml id="5qyv09" event_type: delivery.production.completed evidence_grade: strength: medium actor_certainty: none authority_certainty: none payload_certainty: high interaction_certainty: none timing_certainty: high channel_certainty: high non_repudiation_strength: low notes: - DPAG production status indicates physical production completed. - This does not prove postal handover unless the provider status explicitly says so. ``` ### 21.6 DPAG Postal Handover ```yaml id="xqenak" event_type: delivery.postal.handed_over evidence_grade: strength: strong actor_certainty: none authority_certainty: none payload_certainty: high interaction_certainty: none timing_certainty: high channel_certainty: high non_repudiation_strength: medium notes: - DPAG status indicates handover into the physical postal delivery chain. - This is strong dispatch evidence. - It does not prove recipient receipt or reading. ``` ### 21.7 DPAG Delivery Confirmed / Registered Event ```yaml id="aqs8rv" event_type: delivery.postal.delivery_confirmed evidence_grade: strength: strong actor_certainty: low authority_certainty: none payload_certainty: high interaction_certainty: low timing_certainty: high channel_certainty: high non_repudiation_strength: medium notes: - DPAG registered-mail or delivery-confirmation evidence indicates physical delivery. - Product and native status semantics must support this mapping. - This may still not prove that the intended human personally read the payload. ``` ### 21.8 DPAG Undeliverable / Return ```yaml id="8d68n9" event_type: delivery.postal.return_received evidence_grade: strength: negative actor_certainty: none authority_certainty: none payload_certainty: high interaction_certainty: none timing_certainty: high channel_certainty: high non_repudiation_strength: medium notes: - DPAG or postal-chain status indicates undeliverable or returned mail. - This is strong negative evidence for the physical delivery attempt. ``` ## 22. DPAG Evidence Assessment The DPAG flavor SHOULD provide a DPAG-native evidence assessment. ```yaml id="hsl1jn" DpagEvidenceAssessment: hybridmail_letter_id: string dpag_shipment_id: string? dpag_batch_id: string? participant_id: string? category: success | fail | undef subclass: string confidence: low | medium | high strongest_signal: string? evidence_summary: - string recommended_coordination_interpretation: string? ``` ### 22.1 DPAG Adapter Success Subclasses ```text id="mqc4vu" success.pdf_uploaded success.validation_passed success.positioning_applied success.cover_sheet_generated success.scheduled_dispatch_accepted success.submitted_for_sending success.production_started success.production_completed success.handed_to_postal_service success.registered_tracking_event success.delivery_confirmed success.return_info_processed ``` ### 22.2 DPAG Adapter Fail Subclasses ```text id="vopxjx" fail.upload_rejected fail.validation_failed fail.invalid_pdf fail.invalid_pdfa fail.address_position_invalid fail.automatic_positioning_failed fail.cover_sheet_failed fail.address_invalid fail.unsupported_country fail.unsupported_product fail.scheduled_dispatch_invalid fail.provider_rejected fail.production_failed fail.cancelled fail.undeliverable fail.return_received ``` ### 22.3 DPAG Adapter Undef Subclasses ```text id="1wfu6k" undef.pending undef.uploaded_only undef.validation_pending undef.action_required undef.ready_but_not_sent undef.scheduled_for_future_dispatch undef.submitted_for_sending undef.processing undef.production_status_unknown undef.production_completed_but_handover_unproven undef.handed_to_postal_service_but_delivery_unproven undef.tracking_pending undef.registered_tracking_pending undef.no_final_status_expected undef.bulk_status_partial undef.conflicting_evidence undef.channel_degraded ``` ## 23. DPAG Workflow States The DPAG flavor SHOULD support these normalized workflow states: ```text id="6ob99h" created upload_requested uploaded upload_failed validation_pending validation_passed validation_failed action_required positioning_pending positioning_applied positioning_failed cover_sheet_pending cover_sheet_generated cover_sheet_failed ready_for_sending scheduled send_requested submitted_for_sending processing production_started production_completed handed_to_postal_service in_transit registered_event delivery_confirmed undeliverable return_received cancelled failed unknown ``` These are DPAG-flavor states, not coordination result states. ## 24. DPAG Idempotency and Duplicate Send Prevention Duplicate physical send prevention is mandatory. If the DPAG endpoint used does not provide native idempotency, `hybridmail-connect` MUST implement adapter-managed idempotency. Idempotency scope SHOULD include: ```text id="5xy9o4" coordination_case_id participant_id delivery_id payload_id payload_integrity_hash provider_flavor postal recipient shipment options scheduled dispatch date postal product ``` A repeated `delivery.submit_letter` request with the same idempotency key MUST NOT create a second physical shipment. If the repeated request refers to a changed payload, changed address, changed schedule, or changed product, the adapter MUST reject it as an idempotency conflict unless a new idempotency key is provided. ## 25. DPAG Authentication and Access Handling The DPAG flavor SHOULD model authentication separately from business events. Public material indicates activation/API access and technical login/access handling are relevant. ```yaml id="0b07q8" DpagAuthContext: api_account_ref: string technical_login_ref: string? token_ref: string? authentication_mode: oauth2 | technical_login | api_key | provider_specific | unknown token_expires_at: timestamp? activation_state: not_activated | activated | suspended | unknown ``` Authentication failures SHOULD map to: ```text id="3884ws" system.provider.unavailable notification/delivery action error with category: authentication ``` unless the provider returns a business-level rejection for the submitted shipment. ## 26. DPAG Status Polling and Webhooks The DPAG flavor MUST support polling if the API exposes status retrieval. The DPAG flavor MAY support webhooks if available in the active provider setup. ```yaml id="dyea5l" DpagStatusPollingConfig: enabled: boolean initial_delay_seconds: integer interval_seconds: integer max_duration_seconds: integer supports_bulk_status: boolean supports_tracking_status: boolean terminal_statuses: - delivery_confirmed - handed_to_postal_service - undeliverable - returned - failed - cancelled ``` Polling MUST preserve status history and MUST NOT overwrite raw evidence. ## 27. DPAG Raw Event Preservation The DPAG flavor SHOULD preserve raw provider responses or references to them. ```yaml id="b3p9qg" RawDpagEventRef: raw_event_id: string source: api_response | status_poll | bulk_status_poll | tracking_poll | webhook | validation | production_data | operator endpoint: string? storage_ref: string? received_at: timestamp redacted: boolean ``` Normalized events SHOULD reference raw DPAG event data where available. ## 28. DPAG Channel Health ```yaml id="mcyrjl" DpagChannelHealth: provider_name: dpag_epost provider_account_ref: string? status: healthy | degraded | failing | unknown activation_status: activated | not_activated | suspended | unknown authentication_status: valid | expired | missing | insufficient | unknown upload_status: healthy | degraded | unavailable | unknown validation_status: healthy | degraded | unavailable | unknown production_status: healthy | delayed | unavailable | unknown status_api_status: healthy | degraded | unavailable | unknown tracking_status: healthy | degraded | unavailable | product_dependent | unknown bulk_status_api_status: healthy | degraded | unavailable | unknown cutoff_status: before_cutoff | after_cutoff | no_production_day | unknown known_degradations: - string ``` Health events SHOULD map to: ```text id="l2svm8" system.provider.degraded system.provider.unavailable system.adapter.health_changed ``` ## 29. Security Requirements The DPAG flavor MUST: * protect DPAG API credentials and technical login data. * use secure transport. * avoid logging document contents. * protect postal recipient data. * preserve idempotency. * prevent duplicate physical shipments. * separate test/sandbox and production configuration. * protect tracking and status data. * validate file type and size before upload where possible. * protect generated cover sheets and derived print artifacts. * apply tenant/account separation where applicable. ## 30. Privacy Requirements The DPAG flavor SHOULD: * store payload references instead of payload content where possible. * support metadata-only mode after provider submission. * mask postal address data in logs. * support configurable retention of raw provider responses. * support configurable retention of generated cover sheets and artifacts. * separate operational diagnostics from coordination evidence. * document provider-side retention limitations. * support deletion or anonymization workflows where legally possible. ## 31. Reliability Requirements The DPAG flavor MUST support: * idempotent upload and send requests. * duplicate status event detection. * out-of-order status handling. * polling-based status recovery. * bulk status retrieval and partial-state handling. * late tracking events. * late return/undeliverable events. * retryable upload failures. * non-retryable validation failures. * provider timeout handling. * validation issue preservation. * tracking history preservation. * correlation preservation. * dead-letter handling for unprocessable provider responses. ## 32. Minimal API Surface The DPAG flavor SHOULD implement or expose these conceptual operations through `hybridmail-connect`. ### 32.1 Adapter Contract Operations ```text id="03530g" GET /adapter/descriptor GET /adapter/health POST /adapter/actions POST /adapter/events/provider GET /adapter/events GET /adapter/letters/{id}/timeline GET /adapter/letters/{id}/assessment ``` ### 32.2 DPAG Flavor Operations ```text id="8csqtm" POST /dpag/shipments POST /dpag/shipments/bulk POST /dpag/shipments/{id}/validate POST /dpag/shipments/{id}/send POST /dpag/shipments/{id}/cancel GET /dpag/shipments/{id} GET /dpag/shipments/{id}/status GET /dpag/shipments/{id}/tracking GET /dpag/shipments/bulk/{batch_id}/status GET /dpag/shipments/{id}/timeline GET /dpag/shipments/{id}/assessment GET /dpag/channel-health ``` The exact provider endpoint names MUST be implemented according to the live DPAG/E-POSTBUSINESS API documentation. The conceptual operations above define the adapter-facing semantic model. ## 33. Example End-to-End Flow ### 33.1 Single DPAG Hybrid-Mail Shipment 1. `coordination-engine` creates a coordination case. 2. A PDF or PDF/A payload is registered. 3. Policy selects `hybridmail-connect` with provider flavor `dpag_epost`. 4. `coordination-engine` sends `delivery.submit_letter`. 5. `hybridmail-connect` submits the PDF to DPAG. 6. DPAG accepts the submission. 7. The adapter emits `delivery.payload.accepted`. 8. DPAG validation/status indicates the shipment is processable. 9. The adapter emits `payload.validation_passed`. 10. If address-window positioning, automatic positioning, or cover-sheet generation is used, the adapter records the result as operational metadata. 11. The shipment is submitted or scheduled for sending. 12. The adapter emits `delivery.payload.submitted`. 13. Production data indicates processing/production. 14. The adapter emits `delivery.production.started` and later `delivery.production.completed` if semantically supported. 15. DPAG status indicates handover to the postal chain. 16. The adapter emits `delivery.postal.handed_over`. 17. `coordination-engine` evaluates whether postal handover is sufficient for the case policy. ### 33.2 Validation Failure 1. DPAG rejects or flags the PDF due to PDF/PDF-A, address-window, cover-sheet, product, or layout issue. 2. The adapter emits `payload.validation_failed`. 3. The validation issue is preserved with category and severity. 4. `coordination-engine` marks the participant delivery as action-required or failed for this attempt. 5. Policy requests document correction, alternate generation, or fallback channel. ### 33.3 Scheduled Dispatch 1. `coordination-engine` submits a shipment with a desired dispatch date. 2. DPAG accepts the schedule. 3. The adapter records `scheduled_dispatch`. 4. Participant remains `undef.scheduled_for_future_dispatch`. 5. When the dispatch window begins and DPAG status progresses, the adapter emits production and postal events. 6. `coordination-engine` derives updated participant state. ### 33.4 Registered Letter 1. A shipment is submitted with a registered-mail product. 2. DPAG accepts and processes the shipment. 3. Registered tracking events are received. 4. The adapter emits `delivery.postal.in_transit` for intermediate tracking events. 5. If a delivery-confirming status is received, the adapter emits `delivery.postal.delivery_confirmed`. 6. `coordination-engine` evaluates whether this satisfies the intended result. ### 33.5 Bulk Shipment 1. `coordination-engine` creates a batch delivery case. 2. `hybridmail-connect` submits a bulk upload to DPAG. 3. DPAG returns batch and per-shipment status data. 4. The adapter records `DpagBulkStatus` and `DpagChildShipmentStatus`. 5. The adapter emits per-child evidence events. 6. `coordination-engine` aggregates participant-level states and does not treat batch acceptance as universal success. ## 34. DPAG MVP Scope The first DPAG flavor implementation should include: 1. DPAG provider flavor descriptor. 2. Adapter descriptor integration. 3. DPAG credential/config handling. 4. Single PDF/PDF-A shipment submission. 5. Bulk shipment submission model, at least simulated or structurally supported. 6. Validation result mapping. 7. Address-window / positioning metadata handling. 8. Scheduled dispatch metadata handling. 9. Sending submission. 10. Status polling. 11. Bulk status polling where available. 12. Production status mapping. 13. Shipment tracking mapping. 14. Registered-mail status mapping where product-supported. 15. Evidence event generation. 16. Shipment timeline. 17. DPAG evidence assessment. 18. Adapter-managed idempotency unless provider endpoint support is verified. ### MVP Required DPAG Events ```text id="5kdrfo" delivery.payload.accepted delivery.payload.rejected payload.validation_passed payload.validation_failed delivery.payload.available delivery.payload.submitted delivery.production.started delivery.production.completed delivery.postal.handed_over delivery.postal.in_transit delivery.postal.delivery_confirmed delivery.postal.undeliverable delivery.postal.return_received delivery.postal.status_unknown system.provider.degraded system.provider.unavailable ``` Where a provider status is unavailable or semantically unclear, the adapter MUST emit the weakest safe event and preserve the raw status. ## 35. DPAG MVP Acceptance Criteria The DPAG flavor MVP is acceptable when it can: 1. Accept a coordination-compatible `delivery.submit_letter` request. 2. Upload or simulate upload of a PDF/PDF-A DPAG shipment. 3. Preserve correlation and idempotency. 4. Prevent duplicate physical shipments for duplicate idempotency keys. 5. Map upload acceptance to `delivery.payload.accepted`. 6. Map validation success to `payload.validation_passed`. 7. Map PDF/PDF-A, address-window, or layout validation failure to `payload.validation_failed`. 8. Map send submission to `delivery.payload.submitted`. 9. Map production status to `delivery.production.started` or `delivery.production.completed` only when supported by native status semantics. 10. Map postal handover only when semantically supported by provider status. 11. Map delivery confirmation only when the selected product/status supports it. 12. Map bulk child statuses per shipment where available. 13. Provide a DPAG shipment timeline. 14. Provide a DPAG evidence assessment. 15. Integrate with `coordination-engine` without overclaiming physical delivery or human awareness. ## 36. Open Questions 1. Which exact DPAG native statuses map to `delivery.production.started`, `delivery.production.completed`, `delivery.postal.handed_over`, and `delivery.postal.delivery_confirmed`? 2. Which endpoint names and payload fields are present in the active E-POSTBUSINESS API version used by the target account? 3. Does the target DPAG account/API configuration expose webhooks, or is polling the required baseline? 4. Which registered-mail and delivery-confirmation products are available in the target account? 5. Which PDF/A constraints are enforced automatically and which are documented as implementer responsibility? 6. Which address-window positioning modes are available in the active API? 7. How are individual cover sheets represented in the API? 8. How is scheduled dispatch represented and how are missed schedules surfaced? 9. Which bulk status fields provide child-shipment identity and per-recipient status? 10. Should DPAG validation issues update a shared postal address quality registry? 11. Does the active API provide native idempotency, or must idempotency remain fully adapter-managed? 12. Which GoGreen Plus or sustainability metadata should be captured for reporting? ## 37. Non-Goals The DPAG flavor is not: * a document authoring system. * a PDF renderer by default. * a legal notice system by itself. * a postal carrier abstraction for all DPAG products. * a general E-POST UI replacement. * the owner of coordination case success. * the owner of contract, payment, or signature result semantics. It integrates DPAG/E-POSTBUSINESS hybrid-mail capabilities into the coordination framework. ## 38. Summary `HybridmailDpagSpecification.md` defines the DPAG/E-POSTBUSINESS provider flavor for `hybridmail-connect`. The DPAG flavor models Deutsche Post hybrid-mail shipment as a PDF-centered physical-mail dispatch channel with: * PDF/PDF-A shipment submission * one-by-one and bulk upload * validation * address-window positioning aids * automatic positioning * individual cover sheets * scheduled dispatch * production data * shipment tracking * registered-mail / delivery-confirmation products where supported * bulk and per-shipment status * postal handover and return/undeliverable evidence The key rule is: > DPAG/E-POSTBUSINESS events are provider, production, postal-chain, shipment-tracking, and registered-mail evidence. They are not automatic coordination result satisfaction. hybridmail-connect reports DPAG-channel facts and uncertainty. coordination-engine evaluates intended results.