{"openapi":"3.0.3","info":{"title":"Dativery Pepposh API","version":"1.0.0","description":"Multi-tenant Peppol document exchange service. Most endpoints require authentication via OAuth 2.0 Client Credentials (obtain a token from POST /api/auth/token).\n\nLocalization:\n- Frontend clients should send the selected UI language in the `Accept-Language` header.\n- The server uses this header to localize user-facing responses and falls back to the default locale when the requested language is not supported.\n\nDomain model:\n- A tenant is the top-level customer workspace or organization account. Users, billing, API keys, logs, reports, and configuration are scoped to a tenant.\n- A participant is a concrete business entity managed inside a tenant. Participants represent the legal or operational sender/receiver on the Peppol network and hold business identity, verification state, and Peppol registration.\n- One tenant can manage multiple participants. Most document exchange happens for a specific participant, while tenant endpoints manage the shared container around them.\n\nPermissions model (practical):\n- User roles are hierarchical: owner > admin > member > sender > reader.\n- owner/admin: full tenant administration and operational actions.\n- member: operational write access without tenant administration.\n- sender: send-focused operational access.\n- reader: read-only access.\n- API keys use scope + permissions. `scope=tenant` applies across tenant resources, `scope=participant` limits access to one participant.\n- Standard API key permissions map to guards: read -> requireRead, write/member/sender -> requireMember, admin -> requireAdmin.\n- Developer API key permissions are document-capability based (`send_documents`, `receive_documents`, `receive_all_documents`, `read_all_documents`, `read_participant_info`, `admin`) and can be constrained by outbound ownership."},"servers":[{"url":"https://sandbox.peppos.cz","description":"Sandbox"},{"url":"https://app.peppos.cz","description":"Production"}],"components":{"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth 2.0 Client Credentials flow. Obtain an access token by posting your client_id and client_secret to /api/auth/token, then include it as a Bearer token in the Authorization header.","flows":{"clientCredentials":{"tokenUrl":"/api/auth/token","scopes":{}}}}},"parameters":{"PaginationLimit":{"name":"limit","in":"query","description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},"PaginationOffset":{"name":"offset","in":"query","description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},"PaginationPageToken":{"name":"pageToken","in":"query","description":"Alias of `offset`. It has the same meaning as `offset`.","schema":{"type":"string","example":"0"}},"PeppolParticipantIdHeader":{"name":"X-Peppol-Participant-Id","in":"header","required":false,"description":"Alternative participant selector in the form `ICD:value` (for example `0245:1234567890`). When the endpoint also accepts `participantId`, both values must resolve to the same participant.","schema":{"type":"string","example":"0245:1234567890"}},"AcceptLanguageHeader":{"name":"Accept-Language","in":"header","required":false,"description":"Preferred response language. Supported values are `en`, `cs`, `de`, `sk`, `pl`, `hu`, `fr`, `it`, `es`, `ro`, `hr`, `sl`, `ua`, `pt`, `dk`, `fi`, `gr`, `lu`, `no`, `se`, and `nl`. Unsupported values fall back to the default locale.","schema":{"type":"string","example":"en"}},"ReceiverParticipantIdQuery":{"name":"receiverParticipantId","in":"query","required":false,"description":"Optional receiver Peppol ID override in `ICD:value` format. When omitted, receiver is auto-detected from document content.","schema":{"type":"string","example":"0245:9876543210"}},"DocumentTypeIdQuery":{"name":"documentTypeId","in":"query","required":false,"description":"Optional document type identifier override. When omitted, type is auto-detected from document content.","schema":{"type":"string","example":"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1"}},"DocumentNumberQuery":{"name":"documentNumber","in":"query","required":false,"description":"Optional document number override. When omitted, number is auto-detected from document content when possible.","schema":{"type":"string","example":"INV-2026-001"}},"SenderParticipantIdQuery":{"name":"senderParticipantId","in":"query","required":false,"description":"Optional sender Peppol ID override. Must belong to the authenticated participant.","schema":{"type":"string","example":"0245:1234567890"}},"ProcessIdQuery":{"name":"processId","in":"query","required":false,"description":"Optional process/profile override. When omitted, process is inferred from payload and/or document type.","schema":{"type":"string","example":"urn:fdc:peppol.eu:2017:poacc:billing:01:1.0"}},"WaitForResultQuery":{"name":"wait-for-result","in":"query","required":false,"description":"When set, response returns current SQL-backed document status payload (same shape as /api/documents/{documentId}/status). If a duplicate invoice number already exists, returns status of the existing document instead of creating a new one.","schema":{"type":"boolean","default":false}},"OverwriteQuery":{"name":"overwrite","in":"query","required":false,"description":"When true, allows creating a new outbound document even if another outbound document with the same detected/overridden document number already exists for the same sender.","schema":{"type":"boolean","default":false}}},"schemas":{"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"SAPIError":{"type":"object","required":["category","code","message","retryable","correlation_id"],"properties":{"category":{"type":"string","enum":["AUTH","VALIDATION","PROCESSING","TEMPORARY","PERMANENT"]},"code":{"type":"string","example":"SAPI-AUTH-001"},"message":{"type":"string"},"retryable":{"type":"boolean","example":false},"correlation_id":{"type":"string","format":"uuid"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"issue":{"type":"string"},"value":{"type":"string"}}}}}},"ErrorResponseEnvelope":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/SAPIError"}}},"TokenResponse":{"type":"object","required":["access_token","token_type","expires_in"],"properties":{"access_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"],"example":"Bearer"},"expires_in":{"type":"integer","example":900},"scope":{"type":"string","example":"document:send document:receive"}}},"TokenStatus":{"type":"object","properties":{"valid":{"type":"boolean","example":true},"token_type":{"type":"string","enum":["access"],"example":"access"},"client_id":{"type":"string"},"issued_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"expires_in_seconds":{"type":"integer","example":542},"should_refresh":{"type":"boolean","example":false},"refresh_recommended_at":{"type":"string","format":"date-time"}}},"UserProfile":{"type":"object","properties":{"id":{"type":"string"},"extId":{"type":"string","nullable":true,"description":"Optional external identifier. Can be used in API references as ext:{extId}."},"email":{"type":"string","format":"email"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"language":{"type":"string","enum":["en","cs","sk","de"]},"phone":{"type":"string","nullable":true,"description":"Phone number in E.164 format"},"jobTitle":{"type":"string","nullable":true},"company":{"type":"string","nullable":true},"avatar":{"type":"string","nullable":true,"description":"Avatar image as a base64 data URL"},"createdAt":{"type":"string","format":"date-time"},"otpEnabled":{"type":"boolean"},"participants":{"type":"array","items":{"$ref":"#/components/schemas/UserProfileParticipant"}}},"required":["id","email","firstName","lastName","language","phone","jobTitle","company","avatar","createdAt","otpEnabled","participants"]},"UpdateUserProfileRequest":{"type":"object","properties":{"firstName":{"type":"string","maxLength":100,"description":"First name"},"lastName":{"type":"string","maxLength":100,"description":"Last name"},"language":{"type":"string","enum":["en","cs","sk","de"],"description":"Preferred application language"},"phone":{"type":"string","nullable":true,"description":"Phone number in E.164 format; send null or an empty string to clear it"},"jobTitle":{"type":"string","nullable":true,"maxLength":150,"description":"Job title; send null or an empty string to clear it"},"company":{"type":"string","nullable":true,"maxLength":200,"description":"Company name; send null or an empty string to clear it"},"avatar":{"type":"string","nullable":true,"description":"Avatar image as a base64 data URL or raw base64 image string; send null or an empty string to clear it"}}},"Tenant":{"type":"object","description":"Top-level customer workspace or organization account. A tenant groups users, participants, API keys, reports, logs, and shared configuration. One tenant can own multiple participants.","properties":{"id":{"type":"string"},"extId":{"type":"string","nullable":true,"description":"Optional external identifier. Can be used in API references as ext:{extId}."},"name":{"type":"string"},"slug":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"accessPointId":{"type":"string","format":"uuid","nullable":true,"description":"Optional access point assigned to the tenant. Reporting and operator workflows use the linked access point configuration."},"isActive":{"type":"boolean"},"blocked":{"type":"boolean","readOnly":true},"blockedReason":{"type":"string","nullable":true,"readOnly":true},"rateLimit":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time","nullable":true},"deletedAt":{"type":"string","format":"date-time","nullable":true},"role":{"type":"string","nullable":true},"allowToSkipVerification":{"type":"string","enum":["no","valid","all"],"readOnly":true,"description":"Controls whether users of this tenant may skip the interactive verification steps via the mark-as-verified endpoint. Read-only – set by the operator, not editable via API. `no` – skip not permitted (default). `valid` – skip allowed but ARES + ADISSPR business-identity validation is still enforced. `all` – full bypass including business-identity checks."},"allowToSkipVerificationReason":{"type":"string","enum":["tenant_config","sandbox_default"],"nullable":true,"readOnly":true,"description":"Indicates why the skip-verification mode is active. Read-only – computed field. `tenant_config` – set explicitly on this tenant by the operator. `sandbox_default` – inherited from the sandbox/test environment default (`TEST_DEFAULT_ALLOW_SKIP_VERIFICATION_FOR_NEW_TENANTS=true`); behaves identically to `all` mode. `null` when skip is not permitted."}},"required":["id","name","isActive","createdAt"]},"AccessPoint":{"type":"object","description":"Access point configuration used for transport, reporting, and tenant routing.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"termsLink":{"type":"string","nullable":true},"privacyLink":{"type":"string","nullable":true},"apDomainName":{"type":"string","nullable":true},"smpDomainName":{"type":"string","nullable":true},"peppolApSeatId":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"blocked":{"type":"boolean","readOnly":true},"blockedReason":{"type":"string","nullable":true,"readOnly":true},"primaryTenantId":{"type":"string","format":"uuid","nullable":true},"primaryParticipantId":{"type":"string","format":"uuid","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true}},"required":["id","name","isActive","blocked","createdAt","updatedAt"]},"Participant":{"type":"object","description":"Concrete business entity managed inside a tenant. A participant is the sender or receiver on the Peppol network and carries company identity, verification state, and Peppol registration data.","properties":{"id":{"type":"string"},"extId":{"type":"string","nullable":true,"description":"Optional external identifier. Can be used in API references as ext:{extId}."},"tenantId":{"type":"string","description":"Owning tenant. The tenant is the parent workspace or organization account that manages this participant."},"name":{"type":"string"},"code":{"type":"string","nullable":true},"registrationNumber":{"type":"string","nullable":true},"bankAccount":{"type":"string","nullable":true},"registrationInfo":{"type":"string","nullable":true},"taxId":{"type":"string","nullable":true},"vatId":{"type":"string","nullable":true},"streetWithNo":{"type":"string","nullable":true},"address2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"region":{"type":"string","nullable":true},"postCode":{"type":"string","nullable":true},"countryCode":{"type":"string","nullable":true},"telephone":{"type":"string","nullable":true},"contactPhone":{"type":"string","nullable":true},"contactEmail":{"type":"string","format":"email","nullable":true},"website":{"type":"string","nullable":true},"logoUrl":{"type":"string","nullable":true},"language":{"type":"string"},"isVerified":{"type":"boolean","readOnly":true},"blocked":{"type":"boolean","readOnly":true},"blockedReason":{"type":"string","nullable":true,"readOnly":true},"rateLimit":{"type":"string","nullable":true},"verifiedRegistrationNumber":{"type":"string","nullable":true},"verifiedTaxId":{"type":"string","nullable":true},"verifiedVatId":{"type":"string","nullable":true},"emailVerified":{"type":"boolean"},"emailVerifiedAt":{"type":"string","format":"date-time","nullable":true},"registrationVerified":{"type":"boolean"},"registrationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"bankAccountVerified":{"type":"boolean"},"bankAccountVerifiedAt":{"type":"string","format":"date-time","nullable":true},"authorizedPersonVerified":{"type":"boolean"},"authorizedPersonVerifiedAt":{"type":"string","format":"date-time","nullable":true},"phoneVerified":{"type":"boolean"},"phoneVerifiedAt":{"type":"string","format":"date-time","nullable":true},"peppolRegistration":{"type":"string","enum":["none","sending-only","all"],"readOnly":true,"description":"Current Peppol registration scope for the participant. `none` means not registered, `sending-only` means outbound only, and `all` means send and receive."},"isCorporation":{"type":"boolean","nullable":true},"isVatPayer":{"type":"boolean","nullable":true,"description":"Whether this participant is a registered VAT payer according to the most recent ADISSPR check."},"adissrBankAccounts":{"type":"array","items":{"type":"object"},"nullable":true},"rejectInvalidRegistrations":{"type":"boolean","description":"When true, inbound documents are rejected if the sender's registration number cannot be confirmed in the national business registry (CZ: ARES, SK: ORSR). Only enforced for CZ/SK senders."},"rejectInvalidBankAccounts":{"type":"boolean","description":"When true, inbound documents are rejected if the sender's VAT ID is no longer an active VAT payer (checked via EU VIES). Only enforced when the sender's Peppol ID exposes a VAT number."},"acceptInvoices":{"type":"boolean","description":"Whether inbound invoice-like documents are accepted for this participant."},"acceptSelfBilling":{"type":"boolean","description":"Whether inbound self-billing invoice and credit note documents are accepted for this participant."},"acceptOrders":{"type":"boolean","description":"Whether inbound orders are accepted for this participant."},"acceptDespatchAdvices":{"type":"boolean","description":"Whether inbound despatch advice documents (BIS 30 shipping notices) are accepted for this participant."},"acceptOrderConfirmations":{"type":"boolean","description":"Whether inbound order confirmation documents are accepted for this participant."},"acceptReceiptAdvices":{"type":"boolean","description":"Whether inbound receipt advice documents are accepted for this participant."},"acceptOrderModifications":{"type":"boolean","description":"Whether inbound OrderChange and OrderCancellation documents are accepted for this participant."},"acceptCatalogues":{"type":"boolean","description":"Whether inbound catalogue documents are accepted for this participant."},"extraPeppolIds":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Additional Peppol identifiers accepted for this participant (read-only via participant update API)."},"extraDocumentTypes":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Additional inbound document types accepted for this participant."},"peppol":{"$ref":"#/components/schemas/ParticipantPeppolSettings","description":"Grouped Peppol-specific acceptance and validation settings."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true},"deletedAt":{"type":"string","format":"date-time","nullable":true}},"required":["id","tenantId","name","language","isVerified","blocked","emailVerified","registrationVerified","bankAccountVerified","authorizedPersonVerified","phoneVerified","peppolRegistration","rejectInvalidRegistrations","rejectInvalidBankAccounts","acceptInvoices","acceptSelfBilling","acceptOrders","acceptDespatchAdvices","acceptOrderConfirmations","acceptReceiptAdvices","acceptOrderModifications","acceptCatalogues","peppol","createdAt","updatedAt"]},"ParticipantPeppolSettings":{"type":"object","properties":{"rejectInvalidRegistrations":{"type":"boolean"},"rejectInvalidBankAccounts":{"type":"boolean"},"autoAcknowledge":{"type":"boolean"},"acceptInvoices":{"type":"boolean","description":"Whether inbound invoice-like documents are accepted for this participant."},"acceptSelfBilling":{"type":"boolean","description":"Whether inbound self-billing invoice and credit note documents are accepted for this participant."},"acceptOrders":{"type":"boolean","description":"Whether inbound orders are accepted for this participant."},"acceptDespatchAdvices":{"type":"boolean","description":"Whether inbound despatch advice documents (BIS 30 shipping notices) are accepted for this participant."},"acceptOrderConfirmations":{"type":"boolean","description":"Whether inbound order confirmation (OrderResponse) documents are accepted for this participant."},"acceptReceiptAdvices":{"type":"boolean","description":"Whether inbound receipt advice documents are accepted for this participant."},"acceptOrderModifications":{"type":"boolean","description":"Whether inbound OrderChange and OrderCancellation documents are accepted for this participant."},"acceptCatalogues":{"type":"boolean","description":"Whether inbound catalogue documents are accepted for this participant."},"extraPeppolIds":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Read-only additional Peppol IDs accepted for the participant."},"extraDocumentTypes":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Additional inbound document types accepted for this participant."}}},"ParticipantPeppolSettingsInput":{"type":"object","properties":{"acceptInvoices":{"type":"boolean","description":"Update invoice acceptance flag."},"acceptSelfBilling":{"type":"boolean","description":"Update self-billing document acceptance flag."},"acceptOrders":{"type":"boolean","description":"Update order acceptance flag."},"acceptDespatchAdvices":{"type":"boolean","description":"Update despatch advice (BIS 30 shipping notice) acceptance flag."},"acceptOrderConfirmations":{"type":"boolean","description":"Update order confirmation acceptance flag."},"acceptReceiptAdvices":{"type":"boolean","description":"Update receipt advice acceptance flag."},"acceptOrderModifications":{"type":"boolean","description":"Update OrderChange and OrderCancellation acceptance flag."},"acceptCatalogues":{"type":"boolean","description":"Update catalogue acceptance flag."},"extraDocumentTypes":{"type":"array","items":{"type":"string"},"description":"Replace list of extra accepted document types."}}},"Document":{"type":"object","properties":{"id":{"type":"string"},"extId":{"type":"string","nullable":true,"description":"Optional external identifier. Can be used in API references as ext:{extId}."},"tenantId":{"type":"string","nullable":true},"senderId":{"type":"string","nullable":true},"receiverId":{"type":"string","nullable":true},"senderPeppolId":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true},"documentTypeIdentifier":{"type":"string","nullable":true},"documentType":{"type":"string","description":"Detected document type. Possible values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","enum":["invoice","creditnote","order","order-response","order-change","order-cancellation","despatch-advice","receipt-advice","catalogue","mlr","invoice-response","other"]},"documentNumber":{"type":"string","nullable":true},"originalFormat":{"type":"string","nullable":true,"enum":["UBL","ISDOC","ISDOCX","POHODA","MRP","CII","FACTUR_X","ORDER_X","ZUGFERD","MONEY_S3"]},"status":{"type":"string"},"validationStatus":{"type":"string","enum":["need-validation","valid","invalid"]},"direction":{"type":"string","enum":["inbound","outbound"]},"isRead":{"type":"boolean"},"metadata":{"type":"object","nullable":true,"additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true},"readAt":{"type":"string","format":"date-time","nullable":true},"messageId":{"type":"string","nullable":true,"description":"Peppol SBDH message identifier (UUID). Populated for both inbound and outbound messages. Can be used to correlate response documents (MLR, ILR, Order Response) with the original document they reference."}},"required":["id","documentType","status","validationStatus","direction","isRead","createdAt","updatedAt"]},"ParticipantVerificationStatus":{"type":"object","properties":{"status":{"type":"string"},"verification":{"anyOf":[{"$ref":"#/components/schemas/ParticipantVerificationRecord"},{"type":"null"}]},"participant":{"anyOf":[{"$ref":"#/components/schemas/ParticipantVerificationParticipant"},{"type":"null"}]}},"required":["status","verification","participant"]},"ParticipantVerificationParticipant":{"type":"object","description":"Verification-related participant identity fields.","properties":{"extId":{"type":"string","nullable":true},"registrationNumber":{"type":"string","nullable":true},"taxId":{"type":"string","nullable":true},"vatId":{"type":"string","nullable":true}},"required":["extId","registrationNumber","taxId","vatId"]},"EventLog":{"type":"object","properties":{"id":{"type":"string"},"tenantId":{"type":"string","nullable":true},"participantId":{"type":"string","nullable":true},"userId":{"type":"string","nullable":true},"user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"email":{"type":"string"}},"required":["id","email"]},{"type":"null"}]},"eventType":{"type":"string"},"severity":{"type":"string","enum":["info","peppol","document","security","warning","error"]},"message":{"type":"string"},"metadata":{"type":"object","nullable":true,"additionalProperties":true},"createdAt":{"type":"string","format":"date-time"}},"required":["id","eventType","severity","message","createdAt"]},"PeppolReport":{"type":"object","properties":{"id":{"type":"string"},"tenantId":{"type":"string"},"reportType":{"type":"string","enum":["eusr","tsr"]},"reporterId":{"type":"string"},"periodStart":{"type":"string","format":"date"},"periodEnd":{"type":"string","format":"date"},"reportXml":{"type":"string","nullable":true},"status":{"type":"string","enum":["generated","submitted","failed"]},"transmissionId":{"type":"string","nullable":true},"submittedAt":{"type":"string","format":"date-time","nullable":true},"errorMessage":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","reportType","reporterId","periodStart","periodEnd","status","createdAt","updatedAt"]},"PeppolLog":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid","nullable":true},"participantId":{"type":"string","format":"uuid","nullable":true},"messageId":{"type":"string","nullable":true},"transmissionId":{"type":"string","nullable":true},"senderPeppolId":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true},"documentTypeIdentifier":{"type":"string","nullable":true},"protocol":{"type":"string","nullable":true},"status":{"type":"string"},"errorMessage":{"type":"string","nullable":true},"documentId":{"type":"string","format":"uuid","nullable":true},"relatedDocumentId":{"type":"string","format":"uuid","nullable":true,"description":"For response documents (IMR, MLR, OrderResponse): the ID of the original document this response refers to."},"kind":{"type":"string","nullable":true,"description":"Human-readable document kind, e.g. invoice, creditnote, mlr-accept, mlr-reject, imr-accept, or-reject, …"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","status","createdAt"]},"PeppolLogListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/PeppolLog"}}},"required":["success","data"]},"DocumentReporting":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"direction":{"type":"string","enum":["inbound","outbound"]},"accessPointId":{"type":"string","format":"uuid","nullable":true},"reportingType":{"type":"string"},"status":{"type":"string","enum":["pending","retrying","failed","sent"]},"attemptCount":{"type":"integer"},"maxAttempts":{"type":"integer"},"nextAttemptAt":{"type":"string","format":"date-time"},"lastAttemptAt":{"type":"string","format":"date-time","nullable":true},"lastError":{"type":"string","nullable":true},"confirmationStatus":{"type":"object","nullable":true,"additionalProperties":true},"xmlBody":{"type":"string","nullable":true,"description":"Raw reporting XML payload (from queue or reporting log payload when available)."},"sentAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","participantId","documentId","direction","reportingType","status","attemptCount","maxAttempts","nextAttemptAt","createdAt","updatedAt"]},"DocumentReportingListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentReporting"}}},"required":["success","data"]},"Invitation":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"token":{"type":"string"},"tenantId":{"type":"string","nullable":true},"participantId":{"type":"string","nullable":true},"invitedBy":{"type":"string"},"role":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true},"expiresAt":{"type":"string","format":"date-time"},"acceptedAt":{"type":"string","format":"date-time","nullable":true}},"required":["id","email","token","invitedBy","role","status","createdAt","updatedAt","expiresAt"]},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"clientId":{"type":"string"},"name":{"type":"string"},"tenantId":{"type":"string","nullable":true},"participantId":{"type":"string","nullable":true},"scope":{"type":"string","description":"Access scope of the API key. `tenant` means tenant-wide context; `participant` means access restricted to the assigned participant."},"permissions":{"type":"string","description":"Effective permission set. For standard keys: `read` = read-only, `write/member/sender` = operational write, `admin` = admin-level operations. For developer keys this represents capability scopes like `send_documents`, `receive_documents`, `receive_all_documents`, `read_all_documents`, `read_participant_info`, `admin`."},"rateLimit":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"blocked":{"type":"boolean","readOnly":true},"blockedReason":{"type":"string","nullable":true,"readOnly":true},"expiresAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true},"lastUsedAt":{"type":"string","format":"date-time","nullable":true}},"required":["id","clientId","name","scope","permissions","isActive","blocked"]},"AffiliateToken":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"name":{"type":"string"},"validTo":{"type":"string","format":"date-time","nullable":true},"isActive":{"type":"boolean"},"token":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","format":"uuid","nullable":true},"updatedAt":{"type":"string","format":"date-time"},"updatedBy":{"type":"string","format":"uuid","nullable":true}},"required":["id","tenantId","participantId","name","isActive","token","createdAt","updatedAt"]},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"extId":{"type":"string","nullable":true,"description":"Optional external identifier. Can be used in API references as ext:{extId}."},"tenantId":{"type":"string"},"participantId":{"type":"string","nullable":true},"developerApplicationId":{"type":"string","format":"uuid","nullable":true,"description":"Developer application scope for developer-grant-created webhooks. When present, document event delivery is restricted to documents owned by this application and allowed by grant permissions."},"url":{"type":"string","nullable":true},"events":{"type":"array","items":{"type":"string","enum":["document.received","document.sent","document.delivered","document.failed","mlr","invoice.response","order.response","account.verified"]}},"documentTypes":{"type":"array","items":{"type":"string","enum":["*","invoice","creditnote","order","order-response","order-change","order-cancellation","despatch-advice","receipt-advice","catalogue","mlr","invoice-response","other"]},"nullable":true,"description":"Optional list of document type categories to filter document events. Use [\"*\"] to explicitly receive all types. When set, only events for matching document types are delivered. Has no effect on account.verified and certificate.expiring events."},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time","nullable":true},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true}},"required":["id","tenantId","participantId","events","isActive","createdAt"]},"WebhookWithSecret":{"type":"object","properties":{"id":{"type":"string"},"tenantId":{"type":"string"},"participantId":{"type":"string","nullable":true},"developerApplicationId":{"type":"string","format":"uuid","nullable":true,"description":"Developer application scope for developer-grant-created webhooks. When present, document event delivery is restricted to documents owned by this application and allowed by grant permissions."},"url":{"type":"string","nullable":true},"events":{"type":"array","items":{"type":"string","enum":["document.received","mlr","invoice.response","order.response","document.sent","document.delivered","document.failed","account.verified","certificate.expiring"]}},"documentTypes":{"type":"array","items":{"type":"string","enum":["*","invoice","creditnote","order","order-response","order-change","order-cancellation","despatch-advice","receipt-advice","catalogue","mlr","invoice-response","other"]},"nullable":true,"description":"Optional list of document type categories to filter document events. Use [\"*\"] to explicitly receive all types. When set, only events for matching document types are delivered. Has no effect on account.verified and certificate.expiring events."},"secret":{"type":"string"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time","nullable":true},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true}},"required":["id","tenantId","participantId","events","secret","isActive","createdAt"]},"UpdateParticipantRequest":{"type":"object","properties":{"extId":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"},"registrationNumber":{"type":"string"},"bankAccount":{"type":"string"},"registrationInfo":{"type":"string"},"taxId":{"type":"string"},"vatId":{"type":"string"},"streetWithNo":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"region":{"type":"string"},"postCode":{"type":"string"},"countryCode":{"type":"string"},"telephone":{"type":"string"},"contactPhone":{"type":"string"},"contactEmail":{"type":"string","format":"email"},"website":{"type":"string"},"logoUrl":{"type":"string"},"language":{"type":"string","minLength":2,"maxLength":2},"rateLimit":{"type":"string"},"rejectInvalidRegistrations":{"type":"boolean","description":"When true, inbound documents are rejected if the sender's registration number cannot be confirmed in the national business registry. Only enforced for CZ/SK senders."},"rejectInvalidBankAccounts":{"type":"boolean","description":"When true, inbound documents are rejected if the sender's VAT ID is no longer an active VAT payer (checked via EU VIES)."},"peppol":{"$ref":"#/components/schemas/ParticipantPeppolSettingsInput","description":"Optional Peppol-specific settings applied during participant update."}}},"CreateWebhookRequest":{"type":"object","properties":{"extId":{"type":"string"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["document.received","mlr","invoice.response","order.response","document.sent","document.delivered","document.failed","account.verified","certificate.expiring"]},"minItems":1,"example":["document.received","mlr"]},"documentTypes":{"type":"array","items":{"type":"string","enum":["*","invoice","creditnote","order","order-response","order-change","order-cancellation","despatch-advice","receipt-advice","catalogue","mlr","invoice-response","other"]},"description":"Optional list of document type categories to filter document events. Use [\"*\"] to explicitly receive all types. When empty or omitted, all document types are delivered. Has no effect on account.verified and certificate.expiring events.","example":["invoice","creditnote"]}},"required":["events"]},"UpdateWebhookRequest":{"type":"object","properties":{"extId":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["document.received","mlr","invoice.response","order.response","document.sent","document.delivered","document.failed","account.verified","certificate.expiring"]},"minItems":1},"documentTypes":{"type":"array","items":{"type":"string","enum":["*","invoice","creditnote","order","order-response","order-change","order-cancellation","despatch-advice","receipt-advice","catalogue","mlr","invoice-response","other"]},"nullable":true,"description":"Optional list of document type categories to filter document events. Use [\"*\"] to explicitly receive all types. Set to null or empty array to remove the filter."},"isActive":{"type":"boolean"}}},"AllowedEmail":{"description":"An allowed sender email address for a participant. Incoming emails from this address containing ISDOC (or PDF.ISDOC) attachments will be delivered to the Peppol network on behalf of the participant.","type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email","nullable":true},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","participantId","isActive","createdAt","updatedAt"]},"CreateAllowedEmailRequest":{"description":"Request body for creating a new allowed email entry.","type":"object","properties":{"email":{"type":"string","format":"email","maxLength":255}},"required":["email"]},"UpdateAllowedEmailRequest":{"description":"Request body for updating an allowed email entry.","type":"object","properties":{"isActive":{"type":"boolean"}}},"EmailGateway":{"description":"An inbound email gateway address for a participant. Messages sent to this address can be processed and delivered to the Peppol network on behalf of the participant.","type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email","nullable":true},"isActive":{"type":"boolean"},"blocked":{"type":"boolean","readOnly":true},"blockedReason":{"type":"string","nullable":true,"readOnly":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","participantId","isActive","createdAt","updatedAt"]},"CreateEmailGatewayRequest":{"description":"Request body for creating a new email gateway entry. The email local part is generated on the server.","type":"object","properties":{}},"UpdateEmailGatewayRequest":{"description":"Request body for updating an email gateway entry.","type":"object","properties":{"isActive":{"type":"boolean"}}},"Notification":{"description":"A notification channel configured for a participant. Notifications are sent when relevant events occur (e.g. a document is received). Supported types: email, sms.","type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["email","sms"],"nullable":true},"address":{"type":"string","nullable":true,"description":"Destination address — email address or phone number depending on the type."},"isActive":{"type":"boolean"},"sendReceivedInvoices":{"type":"boolean","description":"Whether received invoices and credit notes should trigger this notification. Defaults to true."},"sendDeliveryStatus":{"type":"boolean","description":"Whether sent/failed delivery status updates should trigger this notification. Defaults to true."},"sendOtherDocumentTypes":{"type":"boolean","description":"Whether other received document types such as orders should trigger this notification. Defaults to true."},"attachmentType":{"type":"string","enum":["none","original","pdf","isdoc","isdocx","cii","factur-x","order-x","zugferd"],"description":"Attachment variant used for email notifications. Ignored for SMS.","default":"original"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","participantId","isActive","sendReceivedInvoices","sendDeliveryStatus","sendOtherDocumentTypes","attachmentType","createdAt","updatedAt"]},"CreateNotificationRequest":{"description":"Request body for creating a notification channel.","type":"object","properties":{"type":{"type":"string","enum":["email","sms"]},"address":{"type":"string","maxLength":255},"sendReceivedInvoices":{"type":"boolean","default":true},"sendDeliveryStatus":{"type":"boolean","default":true},"sendOtherDocumentTypes":{"type":"boolean","default":true},"attachmentType":{"type":"string","enum":["none","original","pdf","isdoc","isdocx","cii","factur-x","order-x","zugferd"],"default":"original","description":"Attachment variant used for email notifications. Ignored for SMS."}},"required":["type"]},"UpdateNotificationRequest":{"description":"Request body for updating a notification channel.","type":"object","properties":{"type":{"type":"string","enum":["email","sms"]},"address":{"type":"string","maxLength":255},"isActive":{"type":"boolean"},"sendReceivedInvoices":{"type":"boolean"},"sendDeliveryStatus":{"type":"boolean"},"sendOtherDocumentTypes":{"type":"boolean"},"attachmentType":{"type":"string","enum":["none","original","pdf","isdoc","isdocx","cii","factur-x","order-x","zugferd"]}}},"NotificationLog":{"description":"A read-only log entry representing a queued or delivered participant notification.","type":"object","properties":{"id":{"type":"string","format":"uuid"},"date":{"type":"string","format":"date-time"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["email","sms"]},"address":{"type":"string"},"subject":{"type":"string"},"body":{"type":"string"},"status":{"type":"string","enum":["to-send","sent","rejected","failed"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","date","tenantId","participantId","documentId","type","address","subject","body","status","createdAt","updatedAt"]},"NotificationLogListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/NotificationLog"}}},"required":["success","data"]},"LookupResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/PeppolLookupResult"}},"required":["success","data"]},"LookupBatchResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PeppolLookupResult"}},"count":{"type":"integer","example":1}},"required":["data","count"]},"CreateTenantRequest":{"type":"object","properties":{"extId":{"type":"string"},"name":{"type":"string"},"accessPointId":{"type":"string","format":"uuid","description":"Optional access point to associate with the tenant."},"language":{"type":"string","minLength":2,"maxLength":2}},"required":["name"]},"UpdateTenantRequest":{"type":"object","properties":{"extId":{"type":"string"},"name":{"type":"string"},"language":{"type":"string","minLength":2,"maxLength":2},"accessPointId":{"type":"string","nullable":true,"format":"uuid","description":"Optional access point to associate with the tenant, or null to clear it."},"isActive":{"type":"boolean"}}},"AddTenantUserRequest":{"type":"object","properties":{"userId":{"type":"string","description":"User UUID or external reference in ext:{extId} format."},"role":{"type":"string","enum":["admin","member","viewer"]}},"required":["userId"]},"UpdateTenantUserRoleRequest":{"type":"object","properties":{"role":{"type":"string","enum":["admin","member","viewer"]}},"required":["role"]},"CreateParticipantRequest":{"type":"object","properties":{"extId":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"},"registrationNumber":{"type":"string"},"bankAccount":{"type":"string"},"registrationInfo":{"type":"string"},"taxId":{"type":"string"},"vatId":{"type":"string"},"streetWithNo":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"region":{"type":"string"},"postCode":{"type":"string"},"countryCode":{"type":"string"},"telephone":{"type":"string"},"contactPhone":{"type":"string"},"contactEmail":{"type":"string"},"website":{"type":"string"},"logoUrl":{"type":"string"},"language":{"type":"string","minLength":2,"maxLength":2},"peppol":{"$ref":"#/components/schemas/ParticipantPeppolSettingsInput","description":"Optional Peppol-specific settings applied during participant creation."}},"required":["name"]},"ApiKeyCreateResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ApiKeyWithSecret"}},"required":["success","data"]},"ParticipantDocumentStatus":{"type":"object","properties":{"documentId":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"format":{"type":"string","nullable":true},"documentTypeIdentifier":{"type":"string","nullable":true},"documentType":{"type":"string","description":"Detected document type. Possible values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","enum":["invoice","creditnote","order","order-response","order-change","order-cancellation","despatch-advice","receipt-advice","catalogue","mlr","invoice-response","other"]},"senderPeppolId":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true},"status":{"type":"string"},"validationStatus":{"type":"string","enum":["need-validation","valid","invalid"]},"isRead":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"messageId":{"type":"string","nullable":true},"transmissionId":{"type":"string","nullable":true,"description":"Transport-layer transmission identifier, if available."},"messageStatus":{"type":"string","nullable":true},"messageSentAt":{"type":"string","format":"date-time","nullable":true},"messageReceivedAt":{"type":"string","format":"date-time","nullable":true},"messageError":{"type":"string","nullable":true},"sendQueueStatus":{"type":"object","nullable":true,"description":"Outbound queue retry and delivery metadata from peppol_send_queue.","properties":{"status":{"type":"string","description":"Current queue state (for example: pending, processing, retrying, sent, permanent_failure)."},"attempts":{"type":"integer","description":"Number of send attempts already performed."},"maxAttempts":{"type":"integer","description":"Maximum number of allowed attempts before permanent failure."},"nextAttemptAt":{"type":"string","format":"date-time","nullable":true,"description":"Scheduled timestamp for the next retry attempt."},"lastAttemptAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of the last send attempt."},"lastError":{"type":"string","nullable":true,"description":"Most recent transmission error text, if any."},"receivingServer":{"type":"string","nullable":true,"description":"Receiving access point/server reported by transport layer."}},"required":["status","attempts","maxAttempts","nextAttemptAt","lastAttemptAt","lastError","receivingServer"]}},"required":["documentId","direction","documentType","status","validationStatus","isRead","createdAt","updatedAt"]},"TenantListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Tenant"}}},"required":["success","data"]},"TenantUserListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/TenantUser"}}},"required":["success","data"]},"ParticipantListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Participant"}},"count":{"type":"integer","example":1}},"required":["data","count"]},"EventLogListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/EventLog"}}},"required":["success","data"]},"PeppolReportListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/PeppolReport"}}},"required":["success","data"]},"PeppolReportResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/PeppolReport"}},"required":["success","data"]},"InvitationListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}},"count":{"type":"integer","example":1}},"required":["data","count"]},"ApiKeyListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["success","data"]},"AffiliateTokenListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/AffiliateToken"}}},"required":["success","data"]},"WebhookListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}},"required":["success","data"]},"DocumentListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}},"required":["success","data"]},"DocumentStatusCount":{"type":"object","properties":{"status":{"type":"string","example":"pending"},"count":{"type":"integer","example":12}},"required":["status","count"]},"DocumentStatisticsResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentStatusCount"}}},"required":["success","data"]},"ParticipantInboxDocumentListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantInboxDocument"}}},"required":["success","data"]},"TenantUser":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"role":{"type":"string","enum":["admin","member","viewer"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","email","firstName","lastName","role","createdAt"]},"ParticipantUser":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"language":{"type":"string","enum":["en","cs","sk","de"]},"phone":{"type":"string","nullable":true},"jobTitle":{"type":"string","nullable":true},"company":{"type":"string","nullable":true},"avatar":{"type":"string","nullable":true,"description":"Avatar image as a base64 data URL"},"otpEnabled":{"type":"boolean"},"isEmailVerified":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"role":{"type":"string","enum":["admin","member","sender","reader","viewer"]}},"required":["id","email","firstName","lastName","language","phone","jobTitle","company","avatar","otpEnabled","isEmailVerified","createdAt","role"]},"ParticipantUserListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantUser"}}},"required":["success","data"]},"UserProfileParticipant":{"type":"object","description":"A participant accessible to the current user, with the user's role for that participant.","properties":{"id":{"type":"string","format":"uuid","description":"Participant ID"},"name":{"type":"string"},"tenantId":{"type":"string","format":"uuid"},"tenantName":{"type":"string"},"role":{"type":"string","enum":["admin","member","viewer"]},"isVerified":{"type":"boolean"}},"required":["id","name","tenantId","tenantName","role","isVerified"]},"ParticipantVerificationRecord":{"type":"object","description":"Current bank verification record for a participant.","properties":{"id":{"type":"string","format":"uuid"},"variableSymbol":{"type":"string"},"status":{"type":"string"},"paymentReceivedAt":{"type":"string","format":"date-time","nullable":true},"verifiedAt":{"type":"string","format":"date-time","nullable":true},"refundSentAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"pendingManualReview":{"type":"boolean"},"reviewNote":{"type":"string","nullable":true}},"required":["id","variableSymbol","status","paymentReceivedAt","verifiedAt","refundSentAt","createdAt","expiresAt","pendingManualReview","reviewNote"]},"PeppolLookupResult":{"type":"object","properties":{"peppolId":{"type":"string"},"scheme":{"type":"string"},"exists":{"type":"boolean"},"participantName":{"type":"string"},"smpServer":{"type":"string"},"businessCard":{"type":"object","description":"Included when `extended` query parameter is enabled.","additionalProperties":true},"capabilities":{"type":"object","nullable":true,"properties":{"canReceiveInvoices":{"type":"boolean"},"canReceiveOrders":{"type":"boolean"},"documentTypes":{"type":"array","items":{"type":"string"}},"endpoint":{"type":"string"}},"required":["canReceiveInvoices","canReceiveOrders"]},"cachedAt":{"type":"string","format":"date-time"},"originalIdentifier":{"type":"string"}},"required":["peppolId","scheme","exists"]},"ApiKeyWithSecret":{"allOf":[{"$ref":"#/components/schemas/ApiKey"},{"type":"object","properties":{"clientSecret":{"type":"string","writeOnly":true,"description":"The API key secret, returned only on creation"}},"required":["clientSecret"]}]},"Developer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"rateLimit":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true}},"required":["id","tenantId","name","isActive","createdAt","updatedAt"]},"DeveloperApplication":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"developerId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"requiredPermissions":{"type":"string","description":"Comma-separated list of required application permissions."},"allowedLogoutUrls":{"type":"string","description":"JSON-encoded array of allowed logout URLs."},"allowedOrigins":{"type":"string","description":"JSON-encoded array of allowed origins."},"allowedCallbackUrls":{"type":"string","nullable":true,"description":"JSON-encoded array of allowed callback URLs."},"isActive":{"type":"boolean"},"blocked":{"type":"boolean","readOnly":true},"blockedReason":{"type":"string","nullable":true,"readOnly":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true}},"required":["id","developerId","name","isActive","blocked","createdAt","updatedAt"]},"DeveloperApiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"developerApplicationId":{"type":"string","format":"uuid"},"clientId":{"type":"string"},"name":{"type":"string"},"rateLimit":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"blocked":{"type":"boolean","readOnly":true},"blockedReason":{"type":"string","nullable":true,"readOnly":true},"expiresAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string","nullable":true},"updatedBy":{"type":"string","nullable":true},"lastUsedAt":{"type":"string","format":"date-time","nullable":true}},"required":["id","developerApplicationId","clientId","name","isActive","blocked","createdAt","updatedAt"]},"DeveloperApiKeyWithSecret":{"allOf":[{"$ref":"#/components/schemas/DeveloperApiKey"},{"type":"object","properties":{"clientSecret":{"type":"string","writeOnly":true,"description":"Returned only on creation."},"message":{"type":"string"}},"required":["clientSecret"]}]},"DeveloperUser":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"role":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true}},"required":["userId","role","email"]},"DeveloperListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Developer"}}},"required":["success","data"]},"DeveloperApplicationListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/DeveloperApplication"}}},"required":["success","data"]},"DeveloperApiKeyListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/DeveloperApiKey"}}},"required":["success","data"]},"DeveloperUserListResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/DeveloperUser"}}},"required":["success","data"]},"DeveloperApiKeyCreateResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/DeveloperApiKeyWithSecret"}},"required":["success","data"]},"ParticipantDocumentStatusMessage":{"type":"object","properties":{"messageId":{"type":"string","nullable":true},"transmissionId":{"type":"string","nullable":true},"status":{"type":"string"},"sentAt":{"type":"string","format":"date-time","nullable":true},"receivedAt":{"type":"string","format":"date-time","nullable":true},"errorMessage":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time","nullable":true}},"required":["status"]},"ParticipantInboxDocument":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"direction":{"type":"string","enum":["inbound","outbound"]},"format":{"type":"string","nullable":true},"documentType":{"type":"string","description":"Detected document type. Possible values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","enum":["invoice","creditnote","order","order-response","order-change","order-cancellation","despatch-advice","receipt-advice","catalogue","mlr","invoice-response","other"]},"documentNumber":{"type":"string","nullable":true},"senderPeppolId":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true},"status":{"type":"string"},"validationStatus":{"type":"string","enum":["need-validation","valid","invalid"]},"isRead":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"latestMessage":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ParticipantDocumentStatusMessage"}]}},"required":["id","direction","documentType","status","validationStatus","isRead","createdAt","updatedAt"]}},"responses":{"Unauthorized":{"description":"Unauthorized – missing or invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Forbidden":{"description":"Forbidden – insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotImplemented":{"description":"Not implemented – feature or service is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadGateway":{"description":"Bad gateway – upstream conversion service returned an error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadRequest":{"description":"Bad request – validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Conflict":{"description":"Conflict – resource already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"SAPIError":{"description":"SAPI-formatted error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}}}},"security":[{"oauth2":[]}],"tags":[{"name":"Auth","description":"Authentication and account management"},{"name":"Users","description":"User profile and user management"},{"name":"Lookup","description":"Peppol network participant lookup"},{"name":"Tenants","description":"Tenant management. A tenant is the top-level customer workspace or organization account that contains users, participants, API keys, logs, reports, and shared settings."},{"name":"Participants","description":"Participant management within a tenant. A participant is a concrete business entity under a tenant that sends or receives Peppol documents and has its own identity, verification state, and Peppol registration."},{"name":"Documents","description":"Document listing, delivery, conversion, and acknowledgement"},{"name":"API Keys","description":"API key management across root, tenant, and participant scopes"},{"name":"Affiliate Tokens","description":"Tenant and participant affiliate token management."},{"name":"Event Logs","description":"Audit and event log access"},{"name":"Reports","description":"Peppol reporting endpoints. This section is required only when using our platform as a white-label Peppol AP."},{"name":"Peppol Logs","description":"Peppol transmission log access"},{"name":"Webhooks","description":"Webhook subscriptions"},{"name":"Allowed Emails","description":"Per-participant allowlist of sender email addresses whose ISDOC/PDF.ISDOC attachments are delivered to the Peppol network."},{"name":"Email Gateways","description":"Per-participant inbound email gateway addresses used to receive incoming documents by email."},{"name":"Notifications","description":"Per-participant notification channels (email, SMS) for delivery events."},{"name":"Notification Logs","description":"Read-only log of queued and delivered participant notifications."},{"name":"Invitations","description":"User invitations"},{"name":"Grant Authorization","description":"OAuth 2.0 Authorization Code flow for third-party applications. Allows a developer application to request delegated access to a participant on behalf of a logged-in user. The flow: (1) GET /auth/grant to fetch consent context, (2) POST /auth/grant/authorize (user-authenticated) to issue a short-lived code and redirect, (3) POST /auth/grant/token to exchange the code for access/refresh tokens, (4) POST /auth/grant/refresh to rotate tokens."},{"name":"SAPI","description":"SAPI-SK v1.0 compatible endpoints for machine-to-machine document exchange. Authentication uses OAuth 2.0 client_credentials flow (`POST /sapi/auth/token`). Document endpoints require a Bearer access token and the `X-Peppol-Participant-Id` header."}],"paths":{"/api/documents/{documentId}/download":{"get":{"tags":["Documents"],"summary":"Download document in its original format","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Original document content","content":{"application/xml":{}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"description":"Returns the stored source document payload. Supported source formats include UBL, ISDOC, ISDOCX, POHODA, MRP, MONEY_S3, CII, FACTUR_X, ORDER_X, and ZUGFERD."}},"/api/documents/{documentId}/download/as/{format}":{"get":{"tags":["Documents"],"summary":"Download document in specified format","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["isdoc","pohoda","mrp","money-s3","datev","cii","factur-x","zugferd","order-x","isdocx","ubl-json"]},"description":"Target download format."},{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document file in the requested format.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Unsupported format or incompatible document."},"404":{"description":"Document not found."}},"description":"Download the document converted to the specified format. Supported formats: `isdoc`, `pohoda`, `mrp`, `money-s3`, `datev`, `cii`, `factur-x`, `zugferd`, `order-x`, `isdocx`, `ubl-json`.","operationId":"downloadDocumentAs"}},"/api/documents/{documentId}/download/pdf":{"get":{"tags":["Documents"],"summary":"Download document converted to PDF","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"PDF document","content":{"application/pdf":{}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"501":{"$ref":"#/components/responses/NotImplemented"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/api/reports/{reportId}/download":{"get":{"tags":["Reports"],"summary":"Download a Peppol report XML by ID","description":"Downloads the stored report XML payload as an attachment.","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Report XML attachment","headers":{"Content-Disposition":{"description":"Attachment filename for the downloaded report.","schema":{"type":"string"}}},"content":{"application/xml":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/send":{"post":{"tags":["Documents"],"summary":"Send a draft document","description":"Sends an outbound draft document via the Peppol network. Validates that the document is in draft status, direction is outbound, the sender participant is verified, senderPeppolId belongs to the participant, the UBL content is valid, and the receiver is reachable on the Peppol network. On success the document status transitions to pending.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document queued for sending","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"documentId":{"type":"string"},"status":{"type":"string","example":"queued"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/send":{"post":{"tags":["Documents"],"summary":"Send a document via PEPPOL","description":"Creates an outbound document and enqueues it for PEPPOL transmission. Payload is uploaded directly in request body. Receiver, document type, invoice/credit note kind, and document number are auto-detected from document content when possible. Query parameters can override detected values. The sender's Peppol ID is resolved from the authenticated participant unless `senderParticipantId` is provided.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"Internal document ID assigned by the system."},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Documents"],"summary":"Send a document via PEPPOL","description":"Creates an outbound document and enqueues it for PEPPOL transmission. Payload is uploaded directly in request body. Receiver, document type, invoice/credit note kind, and document number are auto-detected from document content when possible. Query parameters can override detected values. The sender's Peppol ID is resolved from the authenticated participant unless `senderParticipantId` is provided.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"Internal document ID assigned by the system."},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/documents/send/as/{format}":{"post":{"tags":["Documents"],"summary":"Send document in specified format","description":"Upload and send a document. The `format` path parameter specifies the source format (e.g. `pohoda`, `mrp`, `money-s3`, `cii`, `factur-x`, `zugferd`, `order-x`, `isdocx`, `ubl-json`). Supported formats: `isdoc`, `pohoda`, `mrp`, `money-s3`, `datev`, `cii`, `factur-x`, `zugferd`, `order-x`, `isdocx`, `ubl-json`.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["isdoc","pohoda","mrp","money-s3","datev","cii","factur-x","zugferd","order-x","isdocx","ubl-json"]},"description":"Source format of the uploaded document."},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"sendDocumentAs"},"put":{"tags":["Documents"],"summary":"Send document in specified format","description":"Upload and send a document. The `format` path parameter specifies the source format (e.g. `pohoda`, `mrp`, `money-s3`, `cii`, `factur-x`, `zugferd`, `order-x`, `isdocx`, `ubl-json`).","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["pohoda","mrp","money-s3","cii","factur-x","zugferd","order-x","isdocx","ubl-json"]},"description":"Source format of the uploaded document."},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"sendDocumentAs_flat"}},"/api/documents/send/isdoc":{"post":{"tags":["Documents"],"summary":"Send an ISDOC document via PEPPOL (auto-converted to UBL)","description":"Accepts ISDOC XML content and converts it to UBL before validation and transmission.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Documents"],"summary":"Send an ISDOC document via PEPPOL (auto-converted to UBL)","description":"Accepts ISDOC XML content and converts it to UBL before validation and transmission.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/documents/send":{"post":{"tags":["Documents"],"summary":"Send a document via Peppol","description":"Creates an outbound document and enqueues it for PEPPOL transmission. Payload is uploaded directly in request body. Receiver, document type, invoice/credit note kind, and document number are auto-detected from document content when possible. Query parameters can override detected values. The sender's Peppol ID is resolved from the authenticated participant unless `senderParticipantId` is provided.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"Internal document ID assigned by the system."},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Documents"],"summary":"Send a document via Peppol","description":"Creates an outbound document and enqueues it for PEPPOL transmission. Payload is uploaded directly in request body. Receiver, document type, invoice/credit note kind, and document number are auto-detected from document content when possible. Query parameters can override detected values. The sender's Peppol ID is resolved from the authenticated participant unless `senderParticipantId` is provided.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"Internal document ID assigned by the system."},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/documents/send/as/{format}":{"post":{"tags":["Documents"],"summary":"Send document in specified format","description":"Upload and send a document on behalf of a participant. The `format` path parameter specifies the source format. Supported formats: `isdoc`, `pohoda`, `mrp`, `money-s3`, `datev`, `cii`, `factur-x`, `zugferd`, `order-x`, `isdocx`, `ubl-json`.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["isdoc","pohoda","mrp","money-s3","datev","cii","factur-x","zugferd","order-x","isdocx","ubl-json"]},"description":"Source format of the uploaded document."},{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"sendParticipantDocumentAs"},"put":{"tags":["Documents"],"summary":"Send document in specified format","description":"Upload and send a document on behalf of a participant. The `format` path parameter specifies the source format.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["pohoda","mrp","money-s3","cii","factur-x","zugferd","order-x","isdocx","ubl-json"]},"description":"Source format of the uploaded document."},{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"sendParticipantDocumentAs"}},"/api/reports/{reportId}/send":{"post":{"tags":["Reports"],"summary":"Send a generated Peppol report","description":"Sends the stored report XML to OpenPeppol reporting recipient. For access-point-scoped reports, sender participant is resolved from accessPoint.primaryParticipantId. For legacy tenant-scoped reports, participantId request body field is still accepted.","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"participantId":{"type":"string","format":"uuid","description":"Legacy fallback for tenant-scoped reports. Ignored for access-point-scoped reports."}}}}}},"responses":{"202":{"description":"Report accepted for sending"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/sapi/document/send":{"post":{"tags":["SAPI"],"summary":"Send a document via PEPPOL (SAPI)","description":"Creates an outbound document and enqueues it for PEPPOL transmission. Requires scope `document:send`. The `senderParticipantId` in the metadata must match the Peppol ID resolved from `X-Peppol-Participant-Id`. The sending participant must be fully verified before documents can be submitted.","security":[{"oauth2":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Client-generated unique key for idempotent submission. Requests with the same key and identical payload within 24 hours return the original response.","schema":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["metadata","payload","payloadFormat"],"properties":{"metadata":{"type":"object","required":["documentId","documentTypeId","processId","senderParticipantId","receiverParticipantId"],"properties":{"documentId":{"type":"string","description":"Client-assigned document reference ID.","example":"INV-2026-001"},"documentTypeId":{"type":"string","example":"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1"},"processId":{"type":"string","example":"urn:fdc:peppol.eu:2017:poacc:billing:01:1.0"},"senderParticipantId":{"type":"string","description":"Peppol ID of the sender. Must match `X-Peppol-Participant-Id`.","example":"0245:1234567890"},"receiverParticipantId":{"type":"string","description":"Peppol ID of the receiver.","example":"0245:9876543210"},"creationDateTime":{"type":"string","format":"date-time"}}},"payload":{"type":"string","description":"UBL XML document content (UTF-8)."},"payloadFormat":{"type":"string","enum":["XML"]},"payloadEncoding":{"type":"string"},"checksum":{"type":"string","description":"Optional SHA-256 hex digest of the payload.","example":"e3b0c44298fc1c149afb..."}}}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"providerDocumentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["ACCEPTED","REJECTED"],"example":"ACCEPTED"},"receivedAt":{"type":"string","format":"date-time"},"timestamp":{"type":"string","format":"date-time"}},"required":["providerDocumentId","status","timestamp"]}}}},"400":{"$ref":"#/components/responses/SAPIError"},"401":{"$ref":"#/components/responses/SAPIError"},"403":{"description":"Forbidden. Possible error codes:\n- `SAPI-AUTH-007` (`PARTICIPANT_MISMATCH`) — `senderParticipantId` does not match the authenticated Peppol ID, or the Peppol ID cannot be resolved.\n- `SAPI-AUTH-008` (`PARTICIPANT_NOT_VERIFIED`) — The sending participant has not completed verification and is not allowed to send documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"},"examples":{"participantMismatch":{"summary":"Sender does not match authenticated participant","value":{"error":{"category":"AUTH","code":"SAPI-AUTH-007","message":"senderParticipantId '0245:0000000000' does not match authenticated participant '0245:1234567890'","retryable":false,"correlation_id":"550e8400-e29b-41d4-a716-446655440000"}}},"participantNotVerified":{"summary":"Participant is not verified","value":{"error":{"category":"AUTH","code":"SAPI-AUTH-008","message":"Participant '0245:1234567890' is not verified and cannot send documents","retryable":false,"correlation_id":"550e8400-e29b-41d4-a716-446655440001"}}}}}}},"409":{"$ref":"#/components/responses/SAPIError"},"500":{"$ref":"#/components/responses/SAPIError"}}}},"/api/tenants/{tenantId}/participants/{participantId}/documents/send":{"post":{"tags":["Documents"],"summary":"Send a document via Peppol","description":"Creates an outbound document and enqueues it for PEPPOL transmission. Payload is uploaded directly in request body. Receiver, document type, invoice/credit note kind, and document number are auto-detected from document content when possible. Query parameters can override detected values. The sender's Peppol ID is resolved from the authenticated participant unless `senderParticipantId` is provided.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"Internal document ID assigned by the system."},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"put":{"tags":["Documents"],"summary":"Send a document via Peppol","description":"Creates an outbound document and enqueues it for PEPPOL transmission. Payload is uploaded directly in request body. Receiver, document type, invoice/credit note kind, and document number are auto-detected from document content when possible. Query parameters can override detected values. The sender's Peppol ID is resolved from the authenticated participant unless `senderParticipantId` is provided.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"Internal document ID assigned by the system."},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/tenants/{tenantId}/participants/{participantId}/documents/statistics":{"get":{"tags":["Documents"],"summary":"Get aggregated document counts by status for a participant in tenant scope","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"documentTypes","in":"query","required":false,"description":"Comma-separated list of document types to include. Use `*` for all types. Defaults to all types. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"invoice,creditnote"}},{"name":"excludeDocumentTypes","in":"query","required":false,"description":"Comma-separated list of document types to exclude from statistics. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"mlr"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Grouped participant document statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentStatisticsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"listParticipantDocumentStatisticsByTenant"}},"/api/tenants/{tenantId}/participants/{participantId}/documents/send/as/{format}":{"post":{"tags":["Documents"],"summary":"Send document in specified format","description":"Upload and send a document on behalf of a tenant participant. The `format` path parameter specifies the source format. Supported formats: `isdoc`, `pohoda`, `mrp`, `money-s3`, `datev`, `cii`, `factur-x`, `zugferd`, `order-x`, `isdocx`, `ubl-json`.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["isdoc","pohoda","mrp","money-s3","datev","cii","factur-x","zugferd","order-x","isdocx","ubl-json"]},"description":"Source format of the uploaded document."},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"sendTenantParticipantDocumentAs"},"put":{"tags":["Documents"],"summary":"Send document in specified format","description":"Upload and send a document on behalf of a tenant participant. The `format` path parameter specifies the source format.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["pohoda","mrp","money-s3","cii","factur-x","zugferd","order-x","isdocx","ubl-json"]},"description":"Source format of the uploaded document."},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/ReceiverParticipantIdQuery"},{"$ref":"#/components/parameters/DocumentTypeIdQuery"},{"$ref":"#/components/parameters/DocumentNumberQuery"},{"$ref":"#/components/parameters/SenderParticipantIdQuery"},{"$ref":"#/components/parameters/ProcessIdQuery"},{"$ref":"#/components/parameters/WaitForResultQuery"},{"$ref":"#/components/parameters/OverwriteQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"202":{"description":"Document accepted for transmission","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","example":"accepted"},"senderPeppolId":{"type":"string","example":"0245:1234567890"},"receiverPeppolId":{"type":"string","example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","status","senderPeppolId","receiverPeppolId","documentTypeIdentifier","createdAt"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"sendTenantParticipantDocumentAs"}},"/api/access-points":{"get":{"tags":["Access Points"],"summary":"List accessible access points","parameters":[{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated access-point list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AccessPoint"}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Access Points"],"summary":"Create an access point","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","nullable":true},"termsLink":{"type":"string","nullable":true},"privacyLink":{"type":"string","nullable":true},"apDomainName":{"type":"string","nullable":true},"smpDomainName":{"type":"string","nullable":true},"peppolApSeatId":{"type":"string","nullable":true,"maxLength":255},"isActive":{"type":"boolean"},"primaryTenantId":{"type":"string","format":"uuid","nullable":true},"primaryParticipantId":{"type":"string","format":"uuid","nullable":true}}}}}},"responses":{"201":{"description":"Access point created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessPoint"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/access-points/{apId}":{"get":{"tags":["Access Points"],"summary":"Get access point detail","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Access point detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessPoint"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Access Points"],"summary":"Update an access point","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","nullable":true},"termsLink":{"type":"string","nullable":true},"privacyLink":{"type":"string","nullable":true},"apDomainName":{"type":"string","nullable":true},"smpDomainName":{"type":"string","nullable":true},"peppolApSeatId":{"type":"string","nullable":true,"maxLength":255},"isActive":{"type":"boolean"},"primaryTenantId":{"type":"string","format":"uuid","nullable":true},"primaryParticipantId":{"type":"string","format":"uuid","nullable":true}}}}}},"responses":{"200":{"description":"Access point updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessPoint"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/access-points/{apId}/certificates":{"get":{"tags":["Access Points"],"summary":"List access point certificates","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Access-point certificate list"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Access Points"],"summary":"Create an access point certificate","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255},"validFrom":{"type":"string","format":"date-time","nullable":true},"validTo":{"type":"string","format":"date-time","nullable":true},"apCertificate":{"type":"string","nullable":true},"smpCertificate":{"type":"string","nullable":true},"apPrivateKey":{"type":"string","nullable":true,"description":"Write-only plaintext private key. It is encrypted before storage and never returned by API."},"smpPrivateKey":{"type":"string","nullable":true,"description":"Write-only plaintext private key. It is encrypted before storage and never returned by API."}}}}}},"responses":{"201":{"description":"Access-point certificate created"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/access-points/{apId}/certificates/{certId}":{"get":{"tags":["Access Points"],"summary":"Get access point certificate","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"certId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Access-point certificate detail"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Access Points"],"summary":"Update access point certificate","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"certId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"validFrom":{"type":"string","format":"date-time","nullable":true},"validTo":{"type":"string","format":"date-time","nullable":true},"apCertificate":{"type":"string","nullable":true},"smpCertificate":{"type":"string","nullable":true},"apPrivateKey":{"type":"string","nullable":true,"description":"Write-only plaintext private key. It is encrypted before storage and never returned by API."},"smpPrivateKey":{"type":"string","nullable":true,"description":"Write-only plaintext private key. It is encrypted before storage and never returned by API."}}}}}},"responses":{"200":{"description":"Access-point certificate updated"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Access Points"],"summary":"Delete access point certificate","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"certId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Access-point certificate deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/access-points/{apId}/reports/{reportType}/generate":{"post":{"tags":["Reports"],"summary":"Generate an access-point Peppol report (EUSR or TSR)","description":"Generates a report XML for the selected access point and period. Reporter ID is resolved from accessPoint.peppolApSeatId, then PEPPOL_AP_SEAT_ID as fallback.","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"reportType","in":"path","required":true,"schema":{"type":"string","enum":["eusr","tsr"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"year":{"type":"integer","minimum":2000,"maximum":3000},"month":{"type":"integer","minimum":1,"maximum":12},"overwrite":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Existing report returned (not regenerated)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReportResponse"}}}},"201":{"description":"Report generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReportResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/access-points/{apId}/users":{"get":{"tags":["Access Points"],"summary":"List access point users","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Access-point user list"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Access Points"],"summary":"Add a user to an access point","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId","role"],"properties":{"userId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["owner","admin","member","reader"]}}}}}},"responses":{"201":{"description":"User added to access point"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/access-points/{apId}/users/{userId}":{"patch":{"tags":["Access Points"],"summary":"Update access point user role","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["owner","admin","member","reader"]}}}}}},"responses":{"200":{"description":"Access-point user role updated"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Access Points"],"summary":"Remove a user from an access point","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Access-point user removed"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/access-points/{apId}/peppol-logs":{"get":{"tags":["Access Points"],"summary":"List Peppol transmission logs for an access point","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Access point ID."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"status","in":"query","schema":{"type":"string","enum":["received","sent","delivery_failed","permanent_failure"]},"description":"Filter by transmission status."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated peppol log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/access-points/{apId}/peppol-logs/{logId}":{"get":{"tags":["Access Points"],"summary":"Get a single Peppol transmission log for an access point","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Access point ID."},{"name":"logId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Peppol log entry ID."}],"responses":{"200":{"description":"Peppol log entry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolLog"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/access-points/{apId}/document-reportings":{"get":{"tags":["Access Points"],"summary":"List document reporting queue entries for an access point","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Access point ID."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"result","in":"query","schema":{"type":"string","enum":["success","failed"]},"description":"Filter reportings by result (success = sent, failed = failed + retrying)."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated document reporting queue list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentReportingListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/access-points/{apId}/document-reportings/{reportingId}":{"get":{"tags":["Access Points"],"summary":"Get a single document reporting queue entry for an access point","parameters":[{"name":"apId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Access point ID."},{"name":"reportingId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Document reporting entry ID."}],"responses":{"200":{"description":"Document reporting queue entry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentReporting"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/affiliate-tokens":{"get":{"tags":["Affiliate Tokens"],"summary":"List affiliate tokens across accessible tenants","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier.","parameters":[{"name":"tenantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Affiliate token list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AffiliateTokenListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Affiliate Tokens"],"summary":"Create an affiliate token","description":"Creates an affiliate token for a participant. Requires tenant admin role.","parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["participantId","name"],"properties":{"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"name":{"type":"string"},"validTo":{"type":"string","format":"date-time"},"isActive":{"type":"boolean"},"token":{"type":"string","format":"uuid"}}}}}},"responses":{"201":{"description":"Affiliate token created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AffiliateToken"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/affiliate-tokens/{affiliateTokenId}":{"get":{"tags":["Affiliate Tokens"],"summary":"Get affiliate token detail","parameters":[{"name":"affiliateTokenId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Affiliate token detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AffiliateToken"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Affiliate Tokens"],"summary":"Update an affiliate token","parameters":[{"name":"affiliateTokenId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"participantId":{"type":"string","format":"uuid"},"name":{"type":"string"},"validTo":{"type":"string","format":"date-time","nullable":true},"isActive":{"type":"boolean"},"token":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Affiliate token updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AffiliateToken"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"delete":{"tags":["Affiliate Tokens"],"summary":"Delete an affiliate token","parameters":[{"name":"affiliateTokenId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Affiliate token deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/allowed-emails":{"get":{"tags":["Allowed Emails"],"summary":"List allowed emails across accessible tenants","description":"Returns allowed-email entries. Filter by participantId and optionally tenantId.","security":[{"oauth2":[]}],"parameters":[{"name":"tenantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional participant filter. Required for participant-scoped users."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Allowed email list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/AllowedEmail"}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Allowed Emails"],"summary":"Create an allowed email","description":"Creates an allowed-email entry for a participant accessible to the authenticated tenant user.","security":[{"oauth2":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAllowedEmailRequest"}}}},"responses":{"201":{"description":"Allowed email created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/AllowedEmail"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/allowed-emails/{allowedEmailId}":{"patch":{"tags":["Allowed Emails"],"summary":"Update an allowed email","security":[{"oauth2":[]}],"parameters":[{"name":"allowedEmailId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAllowedEmailRequest"}}}},"responses":{"200":{"description":"Allowed email updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/AllowedEmail"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Allowed Emails"],"summary":"Delete an allowed email","security":[{"oauth2":[]}],"parameters":[{"name":"allowedEmailId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Allowed email deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/api-keys":{"get":{"tags":["API Keys"],"summary":"List API keys across accessible tenants","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier.","parameters":[{"name":"tenantId","in":"query","schema":{"type":"string"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"API key list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["API Keys"],"summary":"Create an API key","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` in the request body. If both are provided, they must identify the same participant.","parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","permissions"],"properties":{"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"name":{"type":"string"},"scope":{"type":"string","enum":["tenant","participant"],"description":"Key context. `tenant` allows tenant-wide access according to permissions. `participant` restricts access to participant-scoped resources."},"permissions":{"type":"array","description":"Developer API key capabilities. `admin` is full access; `send_documents` is outbound sending; `receive_documents` is inbound non-acknowledged visibility; `receive_all_documents` includes acknowledged inbound; `read_all_documents` allows full document read; `read_participant_info` is participant metadata access.","items":{"type":"string","enum":["admin","read_participant_info","send_documents","receive_documents","receive_all_documents","read_all_documents"]}},"rateLimit":{"type":"string"},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/api-keys/{apiKeyId}":{"get":{"tags":["API Keys"],"summary":"Get an API key by ID","parameters":[{"name":"apiKeyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API key detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["API Keys"],"summary":"Update an API key","parameters":[{"name":"apiKeyId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"participantId":{"type":"string","format":"uuid","nullable":true},"scope":{"type":"string","enum":["tenant","participant"],"description":"Key context. `tenant` allows tenant-wide access according to permissions. `participant` restricts access to participant-scoped resources."},"permissions":{"type":"array","description":"Developer API key capabilities. `admin` is full access; `send_documents` is outbound sending; `receive_documents` is inbound non-acknowledged visibility; `receive_all_documents` includes acknowledged inbound; `read_all_documents` allows full document read; `read_participant_info` is participant metadata access.","items":{"type":"string","enum":["admin","read_participant_info","send_documents","receive_documents","receive_all_documents","read_all_documents"]}},"rateLimit":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time","nullable":true}}}}}},"responses":{"200":{"description":"API key updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["API Keys"],"summary":"Delete an API key","parameters":[{"name":"apiKeyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API key deleted"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/auth/grant":{"get":{"tags":["Grant Authorization"],"summary":"Get consent context","description":"Returns the information a consent screen needs to render: application details, required permissions, available participants, and whether the user is already authenticated. An optional Bearer JWT can be included to include participant data.","security":[],"parameters":[{"name":"client_id","in":"query","required":true,"schema":{"type":"string"},"description":"The client ID of the developer application requesting access."},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","format":"uri"},"description":"The callback URL to redirect to after authorization. Must be in the application's allowed callback URLs."},{"name":"response_type","in":"query","required":false,"schema":{"type":"string","enum":["code"]}},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string","example":"CZ"},"description":"Two-letter ISO country code of the company to pre-select (e.g. \"CZ\"). Must be provided together with `rn`. Matched against the participant's country code (case-insensitive). Ignored when `vatId` is provided and matches."},{"name":"rn","in":"query","required":false,"schema":{"type":"string","example":"12345678"},"description":"Company registration number to pre-select. Must be provided together with `countryCode`. Matched (case-insensitive, whitespace-normalized) against the participant's registration number or verified registration number."},{"name":"vatId","in":"query","required":false,"schema":{"type":"string","example":"CZ12345678"},"description":"EU VAT ID to pre-select (e.g. \"CZ12345678\"). Checked first — if a match is found, `countryCode`/`rn` are ignored. Matched (case-insensitive, whitespace-normalized) against the participant's EU VAT ID or verified EU VAT ID."}],"responses":{"200":{"description":"Consent context returned successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"authenticated":{"type":"boolean"},"requiresLogin":{"type":"boolean"},"participantLocked":{"type":"boolean"},"clientType":{"type":"string","enum":["apiKey","developerApiKey"]},"client":{"type":"object","properties":{"clientId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"logoUrl":{"type":"string","nullable":true},"permissions":{"type":"array","items":{"type":"string","enum":["admin","read_participant_info","send_documents","receive_documents","read_all_documents"]}}}},"participants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"name":{"type":"string"},"registrationNumber":{"type":"string","nullable":true},"vatId":{"type":"string","nullable":true},"countryCode":{"type":"string","nullable":true}}}},"preselectedParticipantId":{"type":"string","format":"uuid","nullable":true},"redirectUrlError":{"type":"string","nullable":true,"description":"Present when the redirect_uri is not in the application's allowed callback URLs. The consent screen should display this error and disable the Authorize button. Application name, logo, and description are still returned so the user can see which application made the request."}}}}}},"403":{"description":"Redirect URI or origin not allowed for this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}},"404":{"description":"Client not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}}}}},"/api/auth/grant/authorize":{"post":{"tags":["Grant Authorization"],"summary":"Authorize and issue a grant code","description":"Requires the user to be logged in (Bearer JWT). Creates a short-lived authorization code, then redirects the user-agent to `redirect_uri?code=<code>[&state=<state>]`.","security":[{"oauth2":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["client_id","redirect_uri","participantId"],"properties":{"client_id":{"type":"string","description":"The client ID of the developer application."},"redirect_uri":{"type":"string","format":"uri","description":"Must match the redirect URI registered for the application."},"participantId":{"type":"string","format":"uuid","description":"The participant the user is granting access to."},"state":{"type":"string","description":"Optional opaque value for CSRF protection; echoed back in the redirect."}}}}}},"responses":{"302":{"description":"Redirect to `redirect_uri` with `code` (and `state` if provided) as query parameters."},"400":{"description":"Validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}},"401":{"description":"User is not authenticated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}},"403":{"description":"Redirect URI not allowed, origin not allowed, or participant access denied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}}}}},"/api/auth/grant/refresh":{"post":{"tags":["Grant Authorization"],"summary":"Rotate grant refresh token","description":"Validates and revokes the provided refresh token, then issues a fresh pair of access/refresh tokens with the same scope. Implements refresh token rotation.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string","description":"The refresh token obtained from a previous token issuance."}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string","description":"The refresh token obtained from a previous token issuance."}}}}}},"responses":{"200":{"description":"New tokens issued successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"401":{"description":"Refresh token is invalid, expired, or already revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}}}}},"/api/auth/grant/token":{"post":{"tags":["Grant Authorization"],"summary":"Exchange authorization code for tokens","description":"Exchanges a short-lived authorization code for an access token and a refresh token. The `grant_type` must be `authorization_code`.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["client_id","client_secret","code","redirect_uri","grant_type"],"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"code":{"type":"string","description":"The authorization code received from the redirect."},"redirect_uri":{"type":"string","format":"uri","description":"Must exactly match the redirect_uri used in the authorization step."},"grant_type":{"type":"string","enum":["authorization_code"]}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["client_id","client_secret","code","redirect_uri","grant_type"],"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"code":{"type":"string","description":"The authorization code received from the redirect."},"redirect_uri":{"type":"string","format":"uri","description":"Must exactly match the redirect_uri used in the authorization step."},"grant_type":{"type":"string","enum":["authorization_code"]}}}}}},"responses":{"200":{"description":"Tokens issued successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"Validation error or code already consumed / expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}},"401":{"description":"Invalid client credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}},"403":{"description":"Redirect URI mismatch.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseEnvelope"}}}}}}},"/api/auth/token":{"post":{"tags":["Auth"],"summary":"Issue OAuth token pair","description":"Issues a short-lived access token and long-lived refresh token. Supports both OAuth 2.0 `client_credentials` and `authorization_code` grants. For `authorization_code`, credentials may be supplied either via `Authorization: Basic` or request body fields. Successful responses are returned as raw OAuth token payloads.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"],"example":"client_credentials"},"client_id":{"type":"string","description":"API key `clientId`","example":"key_abc123"},"client_secret":{"type":"string","description":"API key `clientSecret`","example":"secret_xyz"},"scope":{"type":"string","description":"Optional subset of permitted scopes.","example":"document:receive"}}},{"type":"object","required":["grant_type","code","redirect_uri","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["authorization_code"],"example":"authorization_code"},"code":{"type":"string","description":"Authorization code received from the consent redirect."},"redirect_uri":{"type":"string","format":"uri","description":"Must exactly match the redirect URI used during authorization."},"client_id":{"type":"string","description":"Developer application or participant API key client ID."},"client_secret":{"type":"string","description":"Client secret. Can be omitted when supplied via Authorization: Basic, but body credentials are also accepted."}}}]}},"application/x-www-form-urlencoded":{"schema":{"oneOf":[{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"],"example":"client_credentials"},"client_id":{"type":"string","description":"API key `clientId`","example":"key_abc123"},"client_secret":{"type":"string","description":"API key `clientSecret`","example":"secret_xyz"},"scope":{"type":"string","description":"Optional subset of permitted scopes.","example":"document:receive"}}},{"type":"object","required":["grant_type","code","redirect_uri","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["authorization_code"],"example":"authorization_code"},"code":{"type":"string","description":"Authorization code received from the consent redirect."},"redirect_uri":{"type":"string","format":"uri","description":"Must exactly match the redirect URI used during authorization."},"client_id":{"type":"string","description":"Developer application or participant API key client ID."},"client_secret":{"type":"string","description":"Client secret. Can be omitted when supplied via Authorization: Basic, but body credentials are also accepted."}}}]}}}},"responses":{"200":{"description":"Token pair issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"$ref":"#/components/responses/SAPIError"},"401":{"$ref":"#/components/responses/SAPIError"},"403":{"$ref":"#/components/responses/SAPIError"}}}},"/api/developers":{"get":{"tags":["Developers"],"summary":"List developers","responses":{"200":{"description":"Developer list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}},"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}]},"post":{"tags":["Developers"],"summary":"Create a developer","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string","nullable":true},"isActive":{"type":"boolean"}},"required":["name"]}}}},"responses":{"201":{"description":"Developer created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Developer"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/developers/{developerId}":{"get":{"tags":["Developers"],"summary":"Get developer by ID","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Developer detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Developer"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Developers"],"summary":"Update developer","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string","nullable":true},"isActive":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Developer updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Developer"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/developers/{developerId}/applications":{"get":{"tags":["Developers"],"summary":"List developer applications","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Developer applications","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperApplicationListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Developers"],"summary":"Create developer application","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string","nullable":true},"redirectUris":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"}},"required":["name"]}}}},"responses":{"201":{"description":"Developer application created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperApplication"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/developers/{developerId}/applications/{applicationId}":{"patch":{"tags":["Developers"],"summary":"Update developer application","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"applicationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string","nullable":true},"requiredPermissions":{"type":"string","description":"Comma-separated list of required permissions."},"allowedLogoutUrls":{"type":"array","items":{"type":"string"}},"allowedOrigins":{"type":"array","items":{"type":"string"}},"allowedCallbackUrls":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Developer application updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperApplication"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Developers"],"summary":"Delete developer application","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"applicationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Developer application deleted"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/developers/{developerId}/applications/{applicationId}/api-keys":{"get":{"tags":["Developers"],"summary":"List developer application API keys","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"applicationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Developer API keys","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperApiKeyListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Developers"],"summary":"Create developer application API key","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"applicationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"rateLimit":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time","nullable":true}},"required":["name"]}}}},"responses":{"201":{"description":"Developer API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperApiKeyCreateResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/developers/{developerId}/applications/{applicationId}/api-keys/{developerApiKeyId}":{"patch":{"tags":["Developers"],"summary":"Update developer API key","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"applicationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"developerApiKeyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"rateLimit":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time","nullable":true}}}}}},"responses":{"200":{"description":"Developer API key updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperApiKey"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Developers"],"summary":"Delete developer API key","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"applicationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"developerApiKeyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Developer API key deleted"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/developers/{developerId}/users":{"get":{"tags":["Developers"],"summary":"List developer users","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Developer users","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperUserListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Developers"],"summary":"Add user to developer","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["owner","admin","user","viewer"]}},"required":["userId","role"]}}}},"responses":{"201":{"description":"Developer membership created"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/developers/{developerId}/users/{userId}":{"patch":{"tags":["Developers"],"summary":"Update developer user role","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["owner","admin","user","viewer"]}},"required":["role"]}}}},"responses":{"200":{"description":"Developer membership updated"},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["Developers"],"summary":"Remove user from developer","parameters":[{"name":"developerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Developer membership removed"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/documents":{"get":{"tags":["Documents"],"summary":"List documents across accessible tenants and participants","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"tenantId","in":"query","schema":{"type":"string"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"documentTypes","in":"query","description":"Comma-separated list of document types to include. Use `*` for all types. Defaults to `invoice,creditnote`. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"invoice,creditnote"}},{"name":"excludeDocumentTypes","in":"query","required":false,"description":"Comma-separated list of document types to exclude from results. Useful for hiding response document types (e.g. `mlr,order-response`) from inbox views. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"mlr"}},{"name":"documentNumber","in":"query","schema":{"type":"string"}},{"name":"format","in":"query","schema":{"type":"string"}},{"name":"dateTo","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"messageId","in":"query","required":false,"description":"Filter by exact Peppol SBDH message identifier (UUID). Useful for correlating a response document (MLR, ILR, Order Response) with the original document it references.","schema":{"type":"string","format":"uuid"}},{"name":"order","in":"query","schema":{"type":"string"}},{"name":"dateSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp (alias for dateFrom).","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Document list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/documents/statistics":{"get":{"tags":["Documents"],"summary":"Get aggregated document counts by status","description":"Returns grouped document statistics in the form `{ status, count }`, scoped by the authenticated principal and optional filters.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"tenantId","in":"query","schema":{"type":"string"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"documentTypes","in":"query","required":false,"description":"Comma-separated list of document types to include. Use `*` for all types. Defaults to all types. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"invoice,creditnote"}},{"name":"excludeDocumentTypes","in":"query","required":false,"description":"Comma-separated list of document types to exclude from statistics. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"mlr"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Grouped document statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentStatisticsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"listDocumentStatistics"}},"/api/documents/{documentId}":{"get":{"tags":["Documents"],"summary":"Get a document","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Document not found"}}},"patch":{"tags":["Documents"],"summary":"Update a document","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"documentNumber":{"type":"string"},"documentType":{"type":"string"},"status":{"type":"string"},"metadata":{"type":"object"}}}}}},"responses":{"200":{"description":"Updated document"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Document not found"}}},"delete":{"tags":["Documents"],"summary":"Delete a document","description":"Permanently deletes a document. Only documents in draft or failed status can be deleted.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted successfully"},"400":{"description":"Document status does not allow deletion (only draft or failed)"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Document not found"}}}},"/api/documents/{documentId}/mlr/confirm":{"post":{"tags":["Documents"],"summary":"Send MLR confirmation (transmission-level)","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document confirmed"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"description":"Marks an inbound document as confirmed. If the document has PEPPOL IDs, sends a PEPPOL MLR (Message Level Response, BIS 36) with response code AP (Accepted) to the original sender. Idempotent."}},"/api/documents/{documentId}/mlr/reject":{"post":{"tags":["Documents"],"summary":"Send MLR rejection (transmission-level)","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Optional rejection reason"}}}}}},"responses":{"200":{"description":"Document rejected"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"description":"Rejects an inbound document. If the document has PEPPOL IDs, sends a PEPPOL MLR (Message Level Response, BIS 36) with response code RE (Rejected) to the original sender. Idempotent."}},"/api/documents/{documentId}/accept":{"post":{"tags":["Documents"],"summary":"Accept document (business-level)","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"type":"string","description":"Response code to send. Defaults to AP (Accepted). For invoice documents (IMR, BIS 63) valid values are: AB (Acknowledgement of receipt), IP (In process), UQ (Under query), CA (Conditionally accepted), RE (Rejected), AP (Accepted), PD (Payment initiated). For order documents (OrderResponse, BIS 28) valid values are: AP (Accepted), RE (Rejected).","default":"AP","enum":["AB","IP","UQ","CA","RE","AP","PD"],"example":"AP"},"note":{"type":"string","description":"Optional acceptance note"},"effectiveDate":{"type":"string","format":"date","description":"Optional effective date (ISO 8601 date)"}}}}}},"responses":{"200":{"description":"Business response queued for sending","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"documentId":{"type":"string"},"responseCode":{"type":"string","example":"AP"},"status":{"type":"string","example":"queued"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"description":"Sends a business-level acceptance response for an inbound document. For invoice documents (invoice, credit-note, debit-note), sends an Invoice Message Response (IMR, BIS 63) with code AP. For order documents, sends an OrderResponse (BIS 28) with code AP. Requires the document to have PEPPOL IDs."}},"/api/documents/{documentId}/reject":{"post":{"tags":["Documents"],"summary":"Reject a document (business-level)","description":"Sends a business-level rejection response for an inbound document. For invoice documents, sends an Invoice Message Response (IMR, BIS 63) with code RE (Rejected). For order documents, sends an OrderResponse (BIS 28) with code RE. The response code can be overridden via the request body. Requires the document to have PEPPOL IDs.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"type":"string","description":"Response code to send. Defaults to RE (Rejected). For invoice documents (IMR, BIS 63) valid values are: AB (Acknowledgement of receipt), IP (In process), UQ (Under query), CA (Conditionally accepted), RE (Rejected), AP (Accepted), PD (Payment initiated). For order documents (OrderResponse, BIS 28) valid values are: AP (Accepted), RE (Rejected).","default":"RE","enum":["AB","IP","UQ","CA","RE","AP","PD"],"example":"RE"},"note":{"type":"string","description":"Optional note to include in the business response.","example":"Invoice does not match the purchase order."},"effectiveDate":{"type":"string","format":"date","description":"Optional effective date (ISO 8601 date)"}}}}}},"responses":{"200":{"description":"Business response queued for sending","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"documentId":{"type":"string"},"responseCode":{"type":"string","example":"RE"},"status":{"type":"string","example":"queued"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/send-response":{"post":{"tags":["Documents"],"summary":"Send business response (custom)","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["responseCode"],"properties":{"responseCode":{"type":"string","description":"For invoices: AB, IP, UQ, CA, RE, AP, PD. For orders: AP, RE."},"note":{"type":"string","description":"Optional note"},"effectiveDate":{"type":"string","format":"date","description":"Optional effective date (ISO 8601 date)"}}}}}},"responses":{"200":{"description":"Business response queued for sending"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"description":"Sends a custom business-level response for an inbound document. For invoice documents, uses IMR (BIS 63). For order documents, uses OrderResponse (BIS 28). Requires the document to have PEPPOL IDs."}},"/api/documents/{documentId}/acknowledge":{"post":{"tags":["Documents"],"summary":"Mark a document as read (dismiss from inbox)","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document acknowledged"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"description":"Marks an inbound document as read (sets isRead to true, status to confirmed). Once acknowledged, the document is removed from GET /api/documents/inbox with status=pending or status=received, and will appear under status=acknowledged instead. If the document has PEPPOL IDs, an MLR (BIS 36) with response code AP is sent to the original sender as a side-effect. Idempotent — if the document is already read, no change is made but the call succeeds."}},"/api/documents/{documentId}/clone":{"post":{"tags":["Documents"],"summary":"Clone an outbound document as draft","description":"Creates a new outbound draft by cloning an existing outbound document.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Draft clone created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"documentId":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/envelope":{"get":{"tags":["Documents"],"summary":"Download document transport envelope","description":"Downloads the full envelope JSON metadata from the preferred Peppol log entry for this document. The API prefers successful transmission logs; if none exist, it uses the newest log entry.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Envelope JSON","content":{"application/json":{}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/forward":{"post":{"tags":["Documents"],"summary":"Forward a received document as outbound draft","description":"Creates a new outbound draft from an inbound document by swapping sender and receiver metadata for re-sending.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Forward draft created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"documentId":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/peppol-logs":{"get":{"tags":["Documents"],"summary":"List Peppol transmission logs for a document","description":"Returns all Peppol transmission log entries that reference this document.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","schema":{"type":"string","enum":["received","sent","delivery_failed","permanent_failure"]},"description":"Filter by transmission status."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Peppol log list for document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/receipts":{"get":{"tags":["Documents"],"summary":"Download document transport receipt","description":"Downloads the receipt XML from the preferred Peppol log entry for this document. The API prefers successful transmission logs; if none exist, it uses the newest log entry. Receipt selection order is primaryReceipt first, then the first item in receipts.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Receipt XML","content":{"application/xml":{}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/status":{"get":{"tags":["Documents"],"summary":"Get document delivery/transmission status","description":"Returns document status with flattened transmission and outbound queue metadata on the document payload.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"responses":{"200":{"description":"Document status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantDocumentStatus"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/{documentId}/validate":{"post":{"tags":["Documents"],"summary":"Validate a document and persist validation status","description":"Validates stored UBL XML content for the document, updates document.validationStatus to valid/invalid, and returns validation result. When the document is already marked as valid, the endpoint immediately returns a successful validation result without re-running validation.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguageHeader"}],"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["valid","issues"],"properties":{"valid":{"type":"boolean"},"issues":{"type":"array","items":{"type":"object","properties":{"ruleId":{"type":"string"},"severity":{"type":"string","enum":["fatal","warning"]},"message":{"type":"string"},"location":{"type":"string"}}}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/documents/inbox":{"get":{"tags":["Documents"],"summary":"List inbound documents for a participant","description":"Returns inbound documents where the resolved participant is the receiver. The participant must be identified via one of: a participant-scoped API key, the `X-Peppol-Participant-Id` header, or a JWT with participant IDs.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"limit","in":"query","description":"Maximum number of items to return (1–200).","schema":{"type":"integer","default":50,"minimum":1,"maximum":200}},{"name":"pageToken","in":"query","description":"Cursor token returned by a previous request for forward pagination.","schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by document status. Use `acknowledged` to return only acknowledged documents, `pending` or `received` for not-yet-acknowledged documents, or any custom status value.","schema":{"type":"string","example":"acknowledged"}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated list of inbound documents","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}},"nextPageToken":{"type":"string","description":"Cursor for the next page. Absent when there are no more results."},"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":1}},"required":["documents","total","limit"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/email-gateways":{"get":{"tags":["Email Gateways"],"summary":"List email gateways across accessible tenants","description":"Returns email-gateway entries. Filter by participantId and optionally tenantId.","security":[{"oauth2":[]}],"parameters":[{"name":"tenantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional participant filter. Required for participant-scoped users."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Email gateway list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/EmailGateway"}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Email Gateways"],"summary":"Create an email gateway","description":"Creates an email-gateway entry for a participant accessible to the authenticated tenant user.","security":[{"oauth2":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEmailGatewayRequest"}}}},"responses":{"201":{"description":"Email gateway created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/EmailGateway"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/email-gateways/{emailGatewayId}":{"patch":{"tags":["Email Gateways"],"summary":"Update an email gateway","security":[{"oauth2":[]}],"parameters":[{"name":"emailGatewayId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmailGatewayRequest"}}}},"responses":{"200":{"description":"Email gateway updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/EmailGateway"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Email Gateways"],"summary":"Delete an email gateway","security":[{"oauth2":[]}],"parameters":[{"name":"emailGatewayId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Email gateway deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/event-logs":{"get":{"tags":["Event Logs"],"summary":"List tenant-level audit/event logs across accessible tenants","description":"Returns tenant-scoped audit/event logs. For participant-scoped logs, use `/api/participants/{participantId}/event-logs`.","parameters":[{"name":"tenantId","in":"query","schema":{"type":"string"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string"},"description":"Filter by participant ID."},{"name":"userId","in":"query","schema":{"type":"string"},"description":"Filter by user ID."},{"name":"eventType","in":"query","schema":{"type":"string"},"description":"Filter by event type."},{"name":"severity","in":"query","schema":{"type":"string","enum":["info","peppol","document","security","warning","error"]},"description":"Filter by severity level."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Event log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/event-logs/{eventLogId}":{"get":{"tags":["Event Logs"],"summary":"Get an event log by ID","parameters":[{"name":"eventLogId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Event log detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventLog"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/formats/invoice":{"get":{"tags":["Formats"],"summary":"List supported invoice formats","description":"Returns invoice formats supported by send/download endpoints.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"responses":{"200":{"description":"Invoice formats list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","example":"ubl"},"label":{"type":"string","example":"UBL"},"description":{"type":"string","example":"Peppol-native UBL XML invoice format."},"countries":{"type":"array","items":{"type":"string"},"example":["CZ","SK"]}},"required":["key","label","description","countries"]}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"listInvoiceFormats","parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}]}},"/api/invitations":{"post":{"tags":["Invitations"],"summary":"Create an invitation","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` in the request body. If both are provided, they must identify the same participant.","parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["admin","member","viewer"]}}}}}},"responses":{"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"get":{"tags":["Invitations"],"summary":"List invitations across accessible tenants and participants","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier.","security":[{"oauth2":[]}],"parameters":[{"name":"tenantId","in":"query","schema":{"type":"string"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Invitation list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/invitations/{invitationId}":{"get":{"tags":["Invitations"],"summary":"Get an invitation by ID","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invitation detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Invitations"],"summary":"Update an invitation's role","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["admin","member","viewer"]}}}}}},"responses":{"200":{"description":"Invitation updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Invitations"],"summary":"Revoke an invitation","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invitation revoked"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/invitations/{invitationId}/resend":{"post":{"tags":["Invitations"],"summary":"Resend an invitation","description":"Generates a new token and expiry for an expired or pending invitation and re-sends the invitation email. Requires admin role for tenant-scoped invitations.","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invitation resent — returns the updated invitation with a new token and expiry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"400":{"description":"Invitation has already been accepted"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/lookup/{country}/{ico}":{"get":{"tags":["Lookup"],"summary":"Look up Peppol participant by country and ICO","security":[],"parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string"},"description":"Country code (e.g. cz, sk)"},{"name":"ico","in":"path","required":true,"schema":{"type":"string"}},{"name":"extended","in":"query","required":false,"description":"When set, includes additional data such as `businessCard`.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Lookup result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupResponse"}}}},"404":{"description":"Not found"}}}},"/api/lookup/batch":{"post":{"tags":["Lookup"],"summary":"Batch lookup (up to 50 identifiers)","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["identifiers"],"properties":{"identifiers":{"type":"array","items":{"type":"string"},"maxItems":50,"example":["CZ12345678","vat/CZ12345678","cz/12345678","CZ/12345678","0192:87654321"]}}}}}},"parameters":[{"name":"extended","in":"query","required":false,"description":"When set, includes additional data such as `businessCard` in each result.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Batch results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupBatchResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/lookup/peppol/{peppolId}":{"get":{"tags":["Lookup"],"summary":"Lookup by Peppol ID","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"peppolId","in":"path","required":true,"schema":{"type":"string"},"example":"0192:12345678"},{"name":"extended","in":"query","required":false,"description":"When set, includes additional data such as `businessCard`.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Lookup result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/lookup/vat/{vatId}":{"get":{"tags":["Lookup"],"summary":"Lookup by VAT ID","security":[],"parameters":[{"name":"vatId","in":"path","required":true,"schema":{"type":"string"},"example":"CZ12345678"},{"name":"extended","in":"query","required":false,"description":"When set, includes additional data such as `businessCard`.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Lookup result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupResponse"}}}}}}},"/api/notification-logs":{"get":{"tags":["Notification Logs"],"summary":"List notification logs across accessible tenants","description":"Returns notification log entries. Filter by participantId and optionally tenantId.","parameters":[{"name":"tenantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional participant filter. Required for participant-scoped users."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Notification log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/notification-logs/{notificationLogId}":{"get":{"tags":["Notification Logs"],"summary":"Get a notification log by ID","parameters":[{"name":"notificationLogId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Notification log detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationLog"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/notifications":{"get":{"tags":["Notifications"],"summary":"List notifications across accessible tenants","description":"Returns notification channels. Filter by participantId and optionally tenantId.","security":[{"oauth2":[]}],"parameters":[{"name":"tenantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Optional participant filter. Required for participant-scoped users."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Notification channel list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Notifications"],"summary":"Create a notification channel","description":"Creates a notification channel for a participant accessible to the authenticated tenant user.","security":[{"oauth2":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateNotificationRequest"}}}},"responses":{"201":{"description":"Notification channel created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Notification"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/notifications/{notificationId}":{"patch":{"tags":["Notifications"],"summary":"Update a notification channel","security":[{"oauth2":[]}],"parameters":[{"name":"notificationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNotificationRequest"}}}},"responses":{"200":{"description":"Notification channel updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Notification"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Notifications"],"summary":"Delete a notification channel","security":[{"oauth2":[]}],"parameters":[{"name":"notificationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Notification channel deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/notifications/{notificationId}/notification-logs":{"get":{"tags":["Notification Logs"],"summary":"List notification logs for a notification channel","security":[{"oauth2":[]}],"parameters":[{"name":"notificationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Notification log list for the notification channel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/participants":{"post":{"tags":["Participants"],"summary":"Create or update a participant by external ID (API key)","description":"Creates or updates a participant within the tenant bound to the API key (upsert operation). The `extId` field is required and it identifies the participant—if a participant with that external ID already exists in the tenant, it will be updated with the new fields instead of creating a duplicate. Can only be used with an API key that is tied to exactly one tenant. When `mark-as-verified=true` is provided and the tenant's `allowToSkipVerification` mode is not `no`, the server will try to complete the non-interactive verification flow immediately after creation. In `valid` mode it runs the Czech business-identity verification checks before marking the participant as verified; in `all` mode it fully bypasses the remaining verification steps. If the tenant is not allowed to skip verification or the participant country is not supported for the requested flow, the participant is still created and the query flag is ignored.","security":[{"apiKeyAuth":[]}],"parameters":[{"name":"mark-as-verified","in":"query","required":false,"schema":{"type":"boolean"},"description":"When `true`, attempts to mark the newly created participant as verified immediately after creation, using the tenant's `allowToSkipVerification` mode. Unsupported countries such as `SK`, or tenants without the skip-verification privilege, are ignored without failing the create request."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateParticipantRequest"}}}},"responses":{"200":{"description":"Participant updated (upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Participant"}}}},"201":{"description":"Participant created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Participant"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"get":{"tags":["Participants"],"summary":"List participants available to the authenticated user","description":"API-key variant of participant listing. When `X-Peppol-Participant-Id` is provided, the server resolves the participant from the Peppol identifier and returns the matching accessible participant.","security":[{"apiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Participant list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/participants/{participantId}":{"get":{"tags":["Participants"],"summary":"Get participant details","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"responses":{"200":{"description":"Participant details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Participant"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"oauth2":[]},{"apiKeyAuth":[]}]},"patch":{"tags":["Participants"],"summary":"Update participant","description":"When you change fields that are important for validation like name, registrationNumber, vatId and countryCode, you must invoke verification process so the changed values will get propagated to businessCards in Peppol network.","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateParticipantRequest"}}}},"responses":{"200":{"description":"Participant updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Participant"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"oauth2":[]},{"apiKeyAuth":[]}]},"delete":{"tags":["Participants"],"summary":"Delete participant (admin only)","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"responses":{"200":{"description":"Participant deleted","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"oauth2":[]},{"apiKeyAuth":[]}]}},"/api/participants/{participantId}/allowed-emails":{"get":{"tags":["Allowed Emails"],"summary":"List allowed emails for a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"List of allowed emails","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/AllowedEmail"}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Allowed Emails"],"summary":"Add an allowed email for a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAllowedEmailRequest"}}}},"responses":{"201":{"description":"Allowed email created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/AllowedEmail"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/participants/{participantId}/api-keys":{"get":{"tags":["API Keys"],"summary":"List API keys for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"API key list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["API Keys"],"summary":"Create an API key for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","permissions"],"properties":{"name":{"type":"string"},"permissions":{"type":"array","description":"Developer API key capabilities. `admin` is full access; `send_documents` is outbound sending; `receive_documents` is inbound non-acknowledged visibility; `receive_all_documents` includes acknowledged inbound; `read_all_documents` allows full document read; `read_participant_info` is participant metadata access.","items":{"type":"string","enum":["admin","read_participant_info","send_documents","receive_documents","receive_all_documents","read_all_documents"]}},"rateLimit":{"type":"string"},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/participants/{participantId}/documents":{"get":{"tags":["Documents"],"summary":"List documents for a participant","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"documentTypes","in":"query","description":"Comma-separated list of document types to include. Use `*` for all types. Defaults to `invoice,creditnote`. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"invoice,creditnote"}},{"name":"excludeDocumentTypes","in":"query","required":false,"description":"Comma-separated list of document types to exclude from results. Useful for hiding response document types (e.g. `mlr,order-response`) from inbox views. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"mlr"}},{"name":"documentNumber","in":"query","schema":{"type":"string"}},{"name":"format","in":"query","schema":{"type":"string","enum":["UBL","ISDOC","ISDOCX","POHODA","CII","FACTUR_X","ORDER_X","ZUGFERD"]}},{"name":"dateTo","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"messageId","in":"query","required":false,"description":"Filter by exact Peppol SBDH message identifier (UUID). Useful for correlating a response document (MLR, ILR, Order Response) with the original document it references.","schema":{"type":"string","format":"uuid"}},{"name":"order","in":"query","schema":{"type":"string"}},{"name":"dateSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp (alias for dateFrom).","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Document list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/documents/statistics":{"get":{"tags":["Documents"],"summary":"Get aggregated document counts by status for a participant","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"documentTypes","in":"query","required":false,"description":"Comma-separated list of document types to include. Use `*` for all types. Defaults to all types. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"invoice,creditnote"}},{"name":"excludeDocumentTypes","in":"query","required":false,"description":"Comma-separated list of document types to exclude from statistics. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"mlr"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Grouped participant document statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentStatisticsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"listParticipantDocumentStatistics"}},"/api/participants/{participantId}/documents/import":{"post":{"tags":["Documents"],"summary":"Import document files as drafts","description":"Imports one or more files and stores them as draft documents. Supported input formats include ISDOC, ISDOCX, UBL XML, CII/XRechnung, Factur-X, ZUGFeRD, Order-X, and Pohoda XML. PDFs with embedded XML (for example Factur-X/ZUGFeRD PDF/A-3 or PDF+ISDOC) are also supported.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"allowDuplicates","in":"query","required":false,"description":"When true, documents with duplicate document number and type are imported as new drafts instead of being rejected.","schema":{"type":"boolean","default":false}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["files"],"properties":{"files":{"type":"array","items":{"type":"string","format":"binary"},"description":"One or more invoice/order files to import"}}}}}},"responses":{"201":{"description":"All documents imported successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","example":"draft"},"detectedFormat":{"type":"string","enum":["UBL","ISDOC","ISDOCX","POHODA","CII","FACTUR_X","ORDER_X","ZUGFERD"]},"bisFormat":{"type":"string","enum":["UBL","ISDOC","ISDOCX","POHODA","CII","FACTUR_X","ORDER_X","ZUGFERD"]},"senderPeppolId":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true}}}}}}}},"207":{"description":"Partial success, some files failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"detectedFormat":{"type":"string","enum":["UBL","ISDOC","ISDOCX","POHODA","CII","FACTUR_X","ORDER_X","ZUGFERD"]}}}},"failures":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string"},"errorCode":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/participants/{participantId}/documents/inbox":{"get":{"tags":["Documents"],"summary":"Get unread inbound documents for a participant","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PaginationLimit"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"List of unread inbound documents","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantInboxDocumentListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/email-gateways":{"get":{"tags":["Email Gateways"],"summary":"List email gateways for a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"List of email gateways","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/EmailGateway"}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Email Gateways"],"summary":"Add an email gateway for a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEmailGatewayRequest"}}}},"responses":{"201":{"description":"Email gateway created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/EmailGateway"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/participants/{participantId}/event-logs":{"get":{"tags":["Event Logs"],"summary":"List audit/event logs for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"userId","in":"query","schema":{"type":"string"},"description":"Filter by user ID."},{"name":"eventType","in":"query","schema":{"type":"string"},"description":"Filter by event type."},{"name":"severity","in":"query","schema":{"type":"string","enum":["info","peppol","document","security","warning","error"]},"description":"Filter by severity level."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Event log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/invitations":{"get":{"tags":["Invitations"],"summary":"List invitations for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Invitation list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Invitations"],"summary":"Create an invitation for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["admin","member","viewer"]}}}}}},"responses":{"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/participants/{participantId}/notification-logs":{"get":{"tags":["Notification Logs"],"summary":"List notification logs for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Notification log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/notifications":{"get":{"tags":["Notifications"],"summary":"List notifications for a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"List of notification channels","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Notifications"],"summary":"Add a notification channel for a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateNotificationRequest"}}}},"responses":{"201":{"description":"Notification channel created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Notification"}},"required":["success","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/peppol-logs":{"get":{"tags":["Peppol Logs"],"summary":"List Peppol transmission logs for a participant","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"createdSince","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter logs created after this ISO 8601 timestamp."},{"name":"status","in":"query","schema":{"type":"string","enum":["received","sent","delivery_failed","permanent_failure"]},"description":"Filter by transmission status."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated peppol log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/peppol/register":{"get":{"tags":["Participants"],"summary":"Get participant Peppol registration status","description":"Returns current Peppol registration details for a participant, including whether it is registered, date of registration, and all active Peppol IDs.","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"oauth2":[]},{"apiKeyAuth":[]}],"responses":{"200":{"description":"Participant Peppol registration status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"registered":{"type":"boolean","example":true},"registeredAt":{"type":"string","format":"date-time","nullable":true,"example":"2026-01-01T10:00:00.000Z"},"peppolRegistration":{"type":"string","enum":["none","sending-only","all"],"example":"all"},"peppolIds":{"type":"array","items":{"type":"string"},"example":["iso6523-actorid-upis::9915:cz12345678","iso6523-actorid-upis::0208:12345678"]}},"required":["registered","registeredAt","peppolRegistration","peppolIds"]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Participant not found"}}},"post":{"tags":["Participants"],"summary":"Register participant to Peppol","description":"Registers a fully-verified participant to Peppol. All 5 verification steps must be completed (email, registration, bankAccount, authorizedPerson, phone). Creates a peppolIds record (iso6523-actorid-upis::{ICD}:{registrationNumber}) and stores the requested participant Peppol registration scope. Requires PEPPOL_AP_ENDPOINT_URL environment variable to be set.","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"oauth2":[]},{"apiKeyAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"peppolRegistration":{"type":"string","enum":["sending-only","all"],"default":"all","description":"Requested Peppol registration scope. Use `sending-only` for outbound-only registration or `all` for send-and-receive registration."}}}}}},"responses":{"201":{"description":"Participant registered to Peppol","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"peppolId":{"type":"string","example":"iso6523-actorid-upis::0154:12345678","description":"The Peppol participant identifier that was registered"},"peppolRegistration":{"type":"string","enum":["sending-only","all"],"example":"all","description":"The Peppol registration scope applied to the participant."}}}}}}}},"400":{"description":"Validation error – verification incomplete or already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notVerified":{"value":{"success":false,"error":{"code":"PEPPOL_REGISTRATION_NOT_VERIFIED","message":"All verification steps must be completed before registering to Peppol"}}},"alreadyRegistered":{"value":{"success":false,"error":{"code":"PEPPOL_ALREADY_REGISTERED","message":"Participant is already registered to Peppol"}}},"unsupportedCountry":{"value":{"success":false,"error":{"code":"UNSUPPORTED_COUNTRY","message":"Unsupported country code"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Participant not found"},"500":{"description":"Server configuration error – PEPPOL_AP_ENDPOINT_URL not set","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notConfigured":{"value":{"success":false,"error":{"code":"PEPPOL_AP_ENDPOINT_NOT_CONFIGURED","message":"Peppol AP endpoint URL is not configured (PEPPOL_AP_ENDPOINT_URL)"}}}}}}}}},"delete":{"tags":["Participants"],"summary":"Unregister participant from Peppol","description":"Removes the participant's Peppol registration. Deactivates all peppolIds records, deletes SMP service metadata, and sets participant.peppolRegistration to `none`.","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"oauth2":[]},{"apiKeyAuth":[]}],"responses":{"200":{"description":"Participant unregistered from Peppol","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"unregistered":{"type":"boolean","example":true}}}}}}}},"400":{"description":"Participant is not registered to Peppol","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notRegistered":{"value":{"success":false,"error":{"code":"PEPPOL_NOT_REGISTERED","message":"Participant is not registered to Peppol"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Participant not found"}}}},"/api/participants/{participantId}/reports":{"get":{"tags":["Reports"],"summary":"List Peppol reports for a participant's tenant","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"createdSince","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter reports created after this ISO 8601 timestamp."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated report list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReportListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/users":{"get":{"tags":["Participants"],"summary":"List users assigned to a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"responses":{"200":{"description":"User list","content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"role":{"type":"string","enum":["admin","member","sender","reader","viewer"]}}}},"count":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Participants"],"summary":"Assign a user to a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId"],"properties":{"userId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["admin","member","sender","reader","viewer"],"default":"reader"}}}}}},"responses":{"201":{"description":"User assigned to participant"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/users/{userId}":{"patch":{"tags":["Participants"],"summary":"Update a participant user's role","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["admin","member","sender","reader","viewer"]}}}}}},"responses":{"200":{"description":"Participant user updated"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Participants"],"summary":"Remove a user from a participant","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User removed from participant"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/participants/{participantId}/verify/initiate":{"post":{"tags":["Participants"],"summary":"Initiate participant company verification wizard","description":"Multi-step verification flow: (1) email verified, (2) business identity, (3) authorized person. Returns current stage with per-stage issues and a verificationUrl for finishing the flow in the web UI. When the optional callback query parameter is provided, the generated verificationUrl preserves it and the web flow redirects back to that URL after verification is finished or when the user cancels. You can call this endpoint multiple times to continue the flow where you left off, or to re-run failed steps after fixing the reported issues. When the flow is completed, the participant is automatically registered to Peppol and can send/receive documents via the network.","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","enum":["cs","en","sk"],"default":"cs"},"description":"Language for email notifications and error messages"},{"name":"callback","in":"query","required":false,"schema":{"type":"string","format":"uri"},"description":"Optional absolute http/https URL. When valid, it is appended to the returned verificationUrl and used as the redirect target after verification is finished or cancelled."}],"security":[{"oauth2":[]},{"apiKeyAuth":[]}],"responses":{"200":{"description":"Verification status with staged summary","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"currentStage":{"type":"string","enum":["EMAIL","PHONE","REGISTRATION","BANK_ACCOUNT","AUTHORIZED_PERSON","PEPPOL"],"description":"The first incomplete verification stage"},"verificationUrl":{"type":"string","nullable":true,"description":"Web URL for continuing the verification flow. Returned for user JWT authentication. When callback is supplied, the URL includes it as a query parameter.","example":"/verify/peppol/eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyLTEiLCJwYXJ0aWNpcGFudElkIjoicGFydGljaXBhbnQtMSJ9.signature?callback=https%3A%2F%2Fapp.example.com%2Fverification%2Fdone"},"stages":{"type":"object","description":"Summary of each verification stage","additionalProperties":{"type":"object","properties":{"completed":{"type":"boolean"},"completedAt":{"type":"string","format":"date-time","nullable":true},"issues":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable error code","example":"ARES_DIC_MISMATCH"},"message":{"type":"string","description":"Human-readable error message"}}}}}}},"verification":{"nullable":true,"type":"object","description":"Present only when BANK_ACCOUNT stage is active and a pending payment verification exists","properties":{"verificationId":{"type":"string","format":"uuid"},"variableSymbol":{"type":"string","example":"9987654321","description":"10-digit payment variable symbol starting with 99"},"amount":{"type":"number","example":25},"currency":{"type":"string","example":"CZK"},"expiresAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["pending","verified","expired","refunded","pending_review"]},"qrCodeDataUrl":{"type":"string","description":"Base64 PNG data URL of SPAYD ePlatby QR code"},"qrCodeHtml":{"type":"string","description":"Ready-to-embed HTML img tag for the QR code"}}}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"emailNotVerified":{"value":{"success":false,"error":{"code":"EMAIL_NOT_VERIFIED","message":"User email must be verified before initiating company verification"}}},"missingRegistrationId":{"value":{"success":false,"error":{"code":"MISSING_REGISTRATION_ID","message":"Participant must have a registrationNumber or taxId set"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Participant not found"}}}},"/api/participants/{participantId}/verify/mark-as-verified":{"post":{"tags":["Participants"],"summary":"Mark participant as verified (KYC/AML skip)","description":"Marks a participant as fully verified by bypassing the bank-account micro-payment and authorised-person confirmation steps.\n\n**This endpoint is available exclusively to tenants whose `allowToSkipVerification` mode is not `no`:**\n- Completed external KYC (Know Your Customer) and AML (Anti-Money Laundering) checks for their users\n- Signed a special operator contract granting the skip-verification privilege\n\n**Mode behaviour:**\n- `valid` – ARES + ADISSPR business-identity validation is still performed; the company must be active and found in the Czech business registry.\n- `all` – full bypass; all interactive and business-identity checks are skipped.\n\n**Country support:**\n- ✅ **CZ (Czech Republic)** – fully supported\n- ❌ **SK (Slovakia)** – SK companies must complete verification via the standard flow with Finančná správa. \n\n**Steps performed internally:**\n1. Validates participant belongs to the caller's tenant\n2. Checks `participant.countryCode` is `CZ`\n3. If mode is `valid`: runs ARES + ADISSPR validation (company must be active and found)\n4. Sets all verification flags to `true` (email, registration, bankAccount, authorizedPerson, phone)\n5. Sets `isVerified = true`\n6. Creates an audit event `participant_marked_as_verified`\n\n**Access control:** JWT authentication required, tenant admin role.","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"oauth2":[]}],"responses":{"200":{"description":"Participant marked as verified","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Participant"}}}}}},"400":{"description":"Validation error – unsupported country, missing registration number, or ARES check failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"unsupportedCountry":{"value":{"success":false,"error":{"code":"UNSUPPORTED_COUNTRY_FOR_SKIP","message":"Only Czech (CZ) companies are currently supported for skip-verification. Slovak (SK) companies must complete verification via Finančná správa integration, which is not yet available."}}},"missingRegistrationId":{"value":{"success":false,"error":{"code":"MISSING_REGISTRATION_ID","message":"At least a registration number (IČO) or VAT ID (DIČ) is required"}}},"aresNotFound":{"value":{"success":false,"error":{"code":"ARES_ICO_NOT_FOUND","message":"Company registration number (IČO) not found in ARES"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Tenant not permitted to skip verification","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notAllowed":{"value":{"success":false,"error":{"code":"SKIP_VERIFICATION_NOT_ALLOWED","message":"This organization is not permitted to skip the verification process. The feature is available only to tenants who have completed external KYC/AML procedures and signed a special contract with the operator."}}}}}}},"404":{"description":"Participant not found"}}}},"/api/participants/{participantId}/verify/status":{"get":{"tags":["Participants"],"summary":"Get participant verification status","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantVerificationStatus"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}},"security":[{"oauth2":[]},{"apiKeyAuth":[]}]}},"/api/participants/{participantId}/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Webhook list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Webhooks"],"summary":"Register a webhook for a participant","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Webhook registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookWithSecret"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/participants/ext:{extId}":{"post":{"tags":["Participants"],"summary":"Create or update a participant by external ID in route (API key)","description":"Creates or updates a participant within the tenant bound to the API key (upsert operation). The external ID is provided in the route path, and the participant is identified by this external ID—if a participant with that external ID already exists in the tenant, it will be updated with the request body fields instead of creating a duplicate. Can only be used with an API key that is tied to exactly one tenant. When `mark-as-verified=true` is provided and the tenant's `allowToSkipVerification` mode is not `no`, the server will try to complete the non-interactive verification flow immediately after creation.","security":[{"apiKeyAuth":[]}],"parameters":[{"name":"extId","in":"path","required":true,"schema":{"type":"string"},"description":"External identifier for the participant (from URL path)"},{"name":"mark-as-verified","in":"query","required":false,"schema":{"type":"boolean"},"description":"When `true`, attempts to mark the newly created participant as verified immediately after creation, using the tenant's `allowToSkipVerification` mode."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateParticipantRequest"}}}},"responses":{"200":{"description":"Participant updated (upsert)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Participant"}}}},"201":{"description":"Participant created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Participant"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/peppol-logs":{"get":{"tags":["Peppol Logs"],"summary":"List Peppol transmission logs across accessible tenants","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier.","security":[{"oauth2":[]}],"parameters":[{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"tenantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by tenant ID."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by participant ID."},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"createdSince","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter logs created after this ISO 8601 timestamp."},{"name":"status","in":"query","schema":{"type":"string","enum":["received","sent","delivery_failed","permanent_failure"]},"description":"Filter by transmission status."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated peppol log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/peppol-logs/{logId}":{"get":{"tags":["Peppol Logs"],"summary":"Get a Peppol log entry by ID","security":[{"oauth2":[]}],"parameters":[{"name":"logId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Peppol log detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolLog"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/reports":{"get":{"tags":["Reports"],"summary":"List Peppol reports across accessible tenants","parameters":[{"name":"tenantId","in":"query","schema":{"type":"string"},"description":"Optional tenant filter."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"reportType","in":"query","schema":{"type":"string","enum":["eusr","tsr"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["generated","submitted","failed"]}},{"name":"year","in":"query","schema":{"type":"integer"},"description":"Reporting period year. Must be used together with `month`."},{"name":"month","in":"query","schema":{"type":"integer","minimum":1,"maximum":12},"description":"Reporting period month (1-12). Must be used together with `year`."},{"name":"createdSince","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter reports created after this ISO 8601 timestamp."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by participant (resolves to the participant's tenant)."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated report list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReportListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/reports/{reportId}":{"get":{"tags":["Reports"],"summary":"Get a Peppol report by ID","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Report detail including XML payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReport"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/sapi/auth/renew":{"post":{"tags":["SAPI"],"summary":"Renew access token using a refresh token","description":"Issues a new access + refresh token pair and revokes the supplied refresh token (rotation).","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string"}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string"}}}}}},"responses":{"200":{"description":"New token pair issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"$ref":"#/components/responses/SAPIError"},"401":{"$ref":"#/components/responses/SAPIError"}}}},"/api/sapi/auth/revoke":{"post":{"tags":["SAPI"],"summary":"Revoke a refresh token","description":"Marks the provided refresh token as revoked. Per RFC 7009 §2.2, this endpoint always returns 200 even for unknown or already-expired tokens.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"Refresh token to revoke."}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"Refresh token to revoke."}}}}}},"responses":{"200":{"description":"Revocation acknowledged","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Token revoked successfully"},"timestamp":{"type":"string","format":"date-time"}},"required":["success","message","timestamp"]}}}}}}},"/api/sapi/auth/token":{"post":{"tags":["SAPI"],"summary":"Issue SAPI access + refresh token pair","description":"OAuth 2.0 `client_credentials` grant. Exchange your API key `clientId` / `clientSecret` for a short-lived access token (15 min) and a long-lived refresh token (30 days).","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"],"example":"client_credentials"},"client_id":{"type":"string","description":"API key `clientId`","example":"key_abc123"},"client_secret":{"type":"string","description":"API key `clientSecret`","example":"secret_xyz"},"scope":{"type":"string","description":"Optional subset of permitted scopes.","example":"document:receive"}}}},"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"],"example":"client_credentials"},"client_id":{"type":"string","description":"API key `clientId`","example":"key_abc123"},"client_secret":{"type":"string","description":"API key `clientSecret`","example":"secret_xyz"},"scope":{"type":"string","description":"Optional subset of permitted scopes.","example":"document:receive"}}}}}},"responses":{"200":{"description":"Token pair issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"$ref":"#/components/responses/SAPIError"},"401":{"$ref":"#/components/responses/SAPIError"},"403":{"$ref":"#/components/responses/SAPIError"}}}},"/api/sapi/auth/token/status":{"get":{"tags":["SAPI"],"summary":"Inspect an access token","description":"Returns validity metadata for the supplied Bearer access token, including whether a refresh is recommended (< 3 minutes remaining).","security":[{"oauth2":[]}],"responses":{"200":{"description":"Token status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenStatus"}}}},"401":{"$ref":"#/components/responses/SAPIError"}}}},"/api/sapi/document/receive":{"get":{"tags":["SAPI"],"summary":"List received documents (SAPI)","description":"Returns a page of inbound documents for the participant identified by `X-Peppol-Participant-Id`. Requires scope `document:receive`.","security":[{"oauth2":[]}],"parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"description":"Maximum items per page."},{"name":"pageToken","in":"query","schema":{"type":"string"},"description":"Cursor from the previous response for forward pagination."},{"name":"status","in":"query","schema":{"type":"string","enum":["RECEIVED","ACKNOWLEDGED"]},"description":"Filter by acknowledgement status."},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Page of received documents","content":{"application/json":{"schema":{"type":"object","required":["documents"],"properties":{"documents":{"type":"array","items":{"type":"object","required":["providerDocumentId","documentId","documentTypeId","processId","senderParticipantId","receiverParticipantId","creationDateTime","status","receivedAt"],"properties":{"providerDocumentId":{"type":"string","format":"uuid"},"documentId":{"type":"string"},"documentTypeId":{"type":"string"},"processId":{"type":"string"},"senderParticipantId":{"type":"string"},"receiverParticipantId":{"type":"string"},"creationDateTime":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["RECEIVED","ACKNOWLEDGED"]},"receivedAt":{"type":"string","format":"date-time"}}}},"nextPageToken":{"type":"string","description":"Cursor for the next page. Absent when there are no more results."}}}}}},"400":{"$ref":"#/components/responses/SAPIError"},"401":{"$ref":"#/components/responses/SAPIError"},"403":{"$ref":"#/components/responses/SAPIError"}}}},"/api/sapi/document/receive/{documentId}":{"get":{"tags":["SAPI"],"summary":"Get a received document with payload (SAPI)","description":"Returns metadata and the raw XML payload for a single inbound document. Requires scope `document:receive`.","security":[{"oauth2":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"responses":{"200":{"description":"Document detail with payload","content":{"application/json":{"schema":{"type":"object","required":["metadata","payload","payloadFormat"],"properties":{"metadata":{"type":"object","required":["providerDocumentId","documentId","documentTypeId","processId","senderParticipantId","receiverParticipantId","creationDateTime","status","receivedAt"],"properties":{"providerDocumentId":{"type":"string","format":"uuid"},"documentId":{"type":"string"},"documentTypeId":{"type":"string"},"processId":{"type":"string"},"senderParticipantId":{"type":"string"},"receiverParticipantId":{"type":"string"},"creationDateTime":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["RECEIVED","ACKNOWLEDGED"]},"receivedAt":{"type":"string","format":"date-time"}}},"payload":{"type":"string","description":"Raw XML content."},"payloadFormat":{"type":"string","example":"application/xml"}}}}}},"401":{"$ref":"#/components/responses/SAPIError"},"403":{"$ref":"#/components/responses/SAPIError"},"404":{"$ref":"#/components/responses/SAPIError"}}}},"/api/sapi/document/receive/{documentId}/acknowledge":{"post":{"tags":["SAPI"],"summary":"Acknowledge a received document (SAPI)","description":"Marks a received document as acknowledged. Idempotent — calling it again on an already-acknowledged document returns the same response. Requires scope `document:receive`.","security":[{"oauth2":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"responses":{"200":{"description":"Document acknowledged","content":{"application/json":{"schema":{"type":"object","required":["documentId","status","acknowledgedDateTime"],"properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["ACKNOWLEDGED"],"example":"ACKNOWLEDGED"},"acknowledgedDateTime":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#/components/responses/SAPIError"},"403":{"$ref":"#/components/responses/SAPIError"},"404":{"$ref":"#/components/responses/SAPIError"}}}},"/api/tenants":{"get":{"tags":["Tenants"],"summary":"List tenants for the current user","parameters":[{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Tenant list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Tenants"],"summary":"Create a new tenant","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTenantRequest"}}}},"responses":{"201":{"description":"Tenant created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Tenant"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}":{"get":{"tags":["Tenants"],"summary":"Get tenant details","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tenant details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tenant"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Tenants"],"summary":"Update tenant (admin only)","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTenantRequest"}}}},"responses":{"200":{"description":"Tenant updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tenant"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["Tenants"],"summary":"Delete tenant (admin only)","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tenant deleted"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}/api-keys":{"get":{"tags":["API Keys"],"summary":"List API keys for a tenant","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier within the tenant.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"API key list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["API Keys"],"summary":"Create an API key","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","permissions"],"properties":{"name":{"type":"string"},"participantId":{"type":"string","format":"uuid"},"scope":{"type":"string","enum":["tenant","participant"],"description":"Key context. `tenant` allows tenant-wide access according to permissions. `participant` restricts access to participant-scoped resources."},"permissions":{"type":"array","description":"Developer API key capabilities. `admin` is full access; `send_documents` is outbound sending; `receive_documents` is inbound non-acknowledged visibility; `receive_all_documents` includes acknowledged inbound; `read_all_documents` allows full document read; `read_participant_info` is participant metadata access.","items":{"type":"string","enum":["admin","read_participant_info","send_documents","receive_documents","receive_all_documents","read_all_documents"]}},"rateLimit":{"type":"string"},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}/documents":{"get":{"tags":["Documents"],"summary":"List documents for a tenant","security":[{"oauth2":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"documentTypes","in":"query","description":"Comma-separated list of document types to include. Use `*` for all types. Defaults to `invoice,creditnote`. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"invoice,creditnote"}},{"name":"excludeDocumentTypes","in":"query","required":false,"description":"Comma-separated list of document types to exclude from results. Useful for hiding response document types (e.g. `mlr,order-response`) from inbox views. Supported values: invoice, creditnote, order, order-response, order-change, order-cancellation, despatch-advice, receipt-advice, catalogue, mlr, invoice-response, other.","schema":{"type":"string","example":"mlr"}},{"name":"documentNumber","in":"query","schema":{"type":"string"}},{"name":"format","in":"query","schema":{"type":"string"}},{"name":"dateTo","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"messageId","in":"query","required":false,"description":"Filter by exact Peppol SBDH message identifier (UUID). Useful for correlating a response document (MLR, ILR, Order Response) with the original document it references.","schema":{"type":"string","format":"uuid"}},{"name":"order","in":"query","schema":{"type":"string"}},{"name":"dateSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp (alias for dateFrom).","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Document list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/tenants/{tenantId}/event-logs":{"get":{"tags":["Event Logs"],"summary":"List tenant-level audit/event logs for a tenant","description":"Returns tenant-scoped audit/event logs for the selected tenant. For participant-scoped logs, use `/participants/{participantId}/event-logs`.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"query","schema":{"type":"string"},"description":"Filter by participant ID."},{"name":"userId","in":"query","schema":{"type":"string"},"description":"Filter by user ID."},{"name":"eventType","in":"query","schema":{"type":"string"},"description":"Filter by event type."},{"name":"severity","in":"query","schema":{"type":"string","enum":["info","peppol","document","security","warning","error"]},"description":"Filter by severity level."},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Event log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}/invitations":{"get":{"tags":["Invitations"],"summary":"List invitations for a tenant","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Invitation list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Invitations"],"summary":"Create an invitation for a tenant (admin only)","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"participantId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["admin","member","viewer"]}}}}}},"responses":{"201":{"description":"Invitation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}/participants":{"get":{"tags":["Participants"],"summary":"List participants","description":"When `X-Peppol-Participant-Id` is provided, the server resolves the participant from the Peppol identifier within the tenant and returns only the matching accessible participant.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Participant list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Participants"],"summary":"Create a participant (admin only)","description":"Creates a new participant in the specified tenant. When `mark-as-verified=true` is provided and the tenant's `allowToSkipVerification` mode is not `no`, the server will try to complete the non-interactive verification flow immediately after creation. In `valid` mode it runs the Czech business-identity verification checks before marking the participant as verified; in `all` mode it fully bypasses the remaining verification steps. If the tenant is not allowed to skip verification or the participant country is not supported for the requested flow, the participant is still created and the query flag is ignored.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"mark-as-verified","in":"query","required":false,"schema":{"type":"boolean"},"description":"When `true`, attempts to mark the newly created participant as verified immediately after creation, using the tenant's `allowToSkipVerification` mode. Unsupported countries such as `SK`, or tenants without the skip-verification privilege, are ignored without failing the create request."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateParticipantRequest"}}}},"responses":{"201":{"description":"Participant created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Participant"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}/peppol-logs":{"get":{"tags":["Peppol Logs"],"summary":"List Peppol transmission logs for a tenant","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier within the tenant.","security":[{"oauth2":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by participant ID."},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"name":"status","in":"query","schema":{"type":"string","enum":["received","sent","delivery_failed","permanent_failure"]},"description":"Filter by transmission status."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated peppol log list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolLogListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/tenants/{tenantId}/reports":{"get":{"tags":["Reports"],"summary":"List Peppol reports for a tenant","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"reportType","in":"query","schema":{"type":"string","enum":["eusr","tsr"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["generated","submitted","failed"]}},{"name":"year","in":"query","schema":{"type":"integer"},"description":"Reporting period year. Must be used together with `month`."},{"name":"month","in":"query","schema":{"type":"integer","minimum":1,"maximum":12},"description":"Reporting period month (1-12). Must be used together with `year`."},{"name":"createdSince","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter reports created after this ISO 8601 timestamp."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Reserved for future filtering by participant."},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated report list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReportListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/tenants/{tenantId}/reports/{reportType}/generate":{"post":{"tags":["Reports"],"summary":"Generate a tenant Peppol report (EUSR or TSR)","description":"Generates a report XML for the selected tenant and period, stores it in peppol_reports, and returns the created report row. By default, the previous month is used. For tenants linked to an access point, access-point admin/owner permissions are required.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"reportType","in":"path","required":true,"schema":{"type":"string","enum":["eusr","tsr"]}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"year":{"type":"integer","minimum":2000,"maximum":3000},"month":{"type":"integer","minimum":1,"maximum":12},"reporterId":{"type":"string","description":"Optional explicit reporter ID. If omitted, accessPoint.peppolApSeatId is used for linked tenants, then PEPPOL_AP_SEAT_ID as fallback."},"overwrite":{"type":"boolean","default":false,"description":"When false, returns the latest existing report for the same tenant or access-point context/type/period instead of creating a new one."}}}}}},"responses":{"200":{"description":"Existing report returned (not regenerated)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReportResponse"}}}},"201":{"description":"Report generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolReportResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/tenants/{tenantId}/users":{"get":{"tags":["Tenants"],"summary":"List users in a tenant (admin only)","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"User list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantUserListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Tenants"],"summary":"Add a user to tenant (admin only)","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTenantUserRequest"}}}},"responses":{"201":{"description":"User added","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}/users/{userId}":{"patch":{"tags":["Tenants"],"summary":"Update user role in tenant (admin only)","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTenantUserRoleRequest"}}}},"responses":{"200":{"description":"Role updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["Tenants"],"summary":"Remove a user from tenant (admin only)","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User removed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/tenants/{tenantId}/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks for a tenant","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier within the tenant.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Webhook list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Webhooks"],"summary":"Register a webhook for a tenant","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Webhook registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookWithSecret"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/users":{"get":{"tags":["Users"],"summary":"List users sharing a tenant with the caller","security":[{"oauth2":[]}],"parameters":[{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"}],"responses":{"200":{"description":"List of users","content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}}},"count":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/users/{userId}":{"get":{"tags":["Users"],"summary":"Get a user profile by ID","security":[{"oauth2":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"User profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/users/{userId}/participants":{"get":{"tags":["Users"],"summary":"List participants assigned to a user","security":[{"oauth2":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Participant list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"tenantId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["admin","member","viewer"]}}}},"count":{"type":"integer"}},"required":["data","count"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/users/{userId}/tenants":{"get":{"tags":["Users"],"summary":"List tenants a user belongs to","security":[{"oauth2":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Tenant list","content":{"application/json":{"schema":{"type":"object","properties":{"tenants":{"type":"array","items":{"$ref":"#/components/schemas/Tenant"}},"count":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/users/me":{"get":{"tags":["Users"],"summary":"Get current user profile","responses":{"200":{"description":"User profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"patch":{"tags":["Users"],"summary":"Update current user profile","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserProfileRequest"}}}},"responses":{"200":{"description":"Profile updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/UserProfile"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks","description":"`X-Peppol-Participant-Id` can be used instead of `participantId` to resolve the participant from a Peppol identifier.","parameters":[{"name":"tenantId","in":"query","schema":{"type":"string"},"description":"Optional tenant filter."},{"name":"participantId","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PeppolParticipantIdHeader"},{"$ref":"#/components/parameters/PaginationLimit"},{"$ref":"#/components/parameters/PaginationOffset"},{"$ref":"#/components/parameters/PaginationPageToken"},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":50,"minimum":0}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset into the result set.","schema":{"type":"integer","default":0,"minimum":0}},{"name":"order","in":"query","required":false,"description":"Sort order, optionally prefixed with - for descending.","schema":{"type":"string"}},{"name":"createdSince","in":"query","required":false,"description":"Return items with createdAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"createdTo","in":"query","required":false,"description":"Return items with createdAt <= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedSince","in":"query","required":false,"description":"Return items with updatedAt >= this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"updatedTo","in":"query","required":false,"description":"Return items with updatedAt <= this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Webhook list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Webhooks"],"summary":"Register a webhook","parameters":[{"$ref":"#/components/parameters/PeppolParticipantIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Webhook registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookWithSecret"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/webhooks/{webhookId}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook by ID","parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Webhooks"],"summary":"Update a webhook","parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookRequest"}}}},"responses":{"200":{"description":"Webhook updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["Webhooks"],"summary":"Delete a webhook","parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook deleted","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}}}}