{"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`, `nl`, `bg`, `et`, `lv`, and `lt`. 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 true, waits for up to 120 seconds for transmission to reach a result. A completed wait returns HTTP 200 with the current SQL-backed document status payload (same shape as /api/documents/{documentId}/status). A duplicate invoice number follows the same wait behavior for the existing document. If the time limit expires before a result is available, returns HTTP 202 with data.status=processing and data.waitForResultTimedOut=true; this timeout payload is not a Document status payload. Without this parameter, HTTP 202 means the document was accepted for asynchronous transmission and data.status=accepted.","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}},"SendOrReportQuery":{"name":"send-or-report","in":"query","required":false,"description":"When true, delivers the document via PEPPOL only if the recipient is registered on the network. If the recipient is not registered, the document is routed through the applicable legal reporting channel instead (e.g. SK Tax Data) rather than a direct AS4 transmission. Fails if the recipient is missing or no legal reporting channel is available for the sender.","schema":{"type":"boolean","default":false}}},"schemas":{"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"code":{"type":"string","example":"DOCUMENT_NOT_FOUND"},"message":{"type":"string","example":"Document not found"}}}}},"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","example":"Invalid or expired access token"},"retryable":{"type":"boolean","example":false},"correlation_id":{"type":"string","format":"uuid"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"senderParticipantId"},"issue":{"type":"string","example":"required"},"value":{"type":"string","example":"0245:0000000000"}}}}}},"ErrorResponseEnvelope":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/SAPIError"}}},"TokenResponse":{"type":"object","description":"OAuth token response that includes both an access token for Bearer authentication and a refresh token for rotating the session.","required":["access_token","token_type","expires_in","refresh_token"],"properties":{"access_token":{"type":"string","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhcGlrZXlfYWJjMTIzIn0.dGhpc19pc19hX3NpZ25hdHVyZQ"},"token_type":{"type":"string","enum":["Bearer"],"example":"Bearer"},"expires_in":{"type":"integer","example":900},"scope":{"type":"string","example":"document:send document:receive"},"refresh_token":{"type":"string","description":"JWT refresh token used with POST /api/auth/renew or POST /api/sapi/auth/renew to obtain a new token pair (valid for 30 days)"}}},"TokenStatus":{"type":"object","properties":{"valid":{"type":"boolean","example":true},"token_type":{"type":"string","enum":["access"],"example":"access"},"client_id":{"type":"string","example":"key_abc123"},"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","example":"jan.novak@example.com"},"firstName":{"type":"string","nullable":true,"example":"Jan"},"lastName":{"type":"string","nullable":true,"example":"Novák"},"language":{"type":"string","enum":["en","cs","de","sk","pl","hu","fr","it","es","ro","hr","sl","ua","pt","dk","fi","gr","lu","no","se","nl","bg","et","lv","lt"],"example":"cs"},"phone":{"type":"string","nullable":true,"description":"Phone number in E.164 format","example":"+420123456789"},"jobTitle":{"type":"string","nullable":true,"example":"Finance Manager"},"company":{"type":"string","nullable":true,"example":"Acme s.r.o."},"avatar":{"type":"string","nullable":true,"description":"Avatar image as a base64 data URL"},"createdAt":{"type":"string","format":"date-time"},"otpEnabled":{"type":"boolean","example":false},"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","example":"Jan"},"lastName":{"type":"string","maxLength":100,"description":"Last name","example":"Novák"},"language":{"type":"string","enum":["en","cs","de","sk","pl","hu","fr","it","es","ro","hr","sl","ua","pt","dk","fi","gr","lu","no","se","nl","bg","et","lv","lt"],"description":"Preferred application language","example":"cs"},"phone":{"type":"string","nullable":true,"description":"Phone number in E.164 format; send null or an empty string to clear it","example":"+420123456789"},"jobTitle":{"type":"string","nullable":true,"maxLength":150,"description":"Job title; send null or an empty string to clear it","example":"Finance Manager"},"company":{"type":"string","nullable":true,"maxLength":200,"description":"Company name; send null or an empty string to clear it","example":"Acme s.r.o."},"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","example":"Acme s.r.o."},"slug":{"type":"string","nullable":true,"example":"acme-sro"},"language":{"type":"string","nullable":true,"example":"cs"},"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","example":true},"blocked":{"type":"boolean","readOnly":true,"example":false},"blockedReason":{"type":"string","nullable":true,"readOnly":true,"example":"Payment overdue"},"rateLimit":{"type":"string","nullable":true,"example":"100/minute"},"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,"example":"admin"},"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.","example":"no"},"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.","example":"tenant_config"}},"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","example":"Primary EU Access Point"},"description":{"type":"string","nullable":true,"example":"Production access point for EU tenants"},"termsLink":{"type":"string","nullable":true,"example":"https://example.com/terms"},"privacyLink":{"type":"string","nullable":true,"example":"https://example.com/privacy"},"apDomainName":{"type":"string","nullable":true,"example":"ap.example.com"},"smpDomainName":{"type":"string","nullable":true,"example":"smp.example.com"},"peppolApSeatId":{"type":"string","nullable":true,"example":"PEPPOL_AP_SEAT_ID_1"},"isActive":{"type":"boolean","example":true},"blocked":{"type":"boolean","readOnly":true,"example":false},"blockedReason":{"type":"string","nullable":true,"readOnly":true,"example":"Certificate expired"},"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","example":"Acme s.r.o."},"code":{"type":"string","nullable":true,"example":"CUST-001"},"registrationNumber":{"type":"string","nullable":true,"example":"12345678"},"bankAccount":{"type":"string","nullable":true,"example":"CZ6508000000192000145399"},"registrationInfo":{"type":"string","nullable":true,"example":"Registered in the Commercial Register kept by the Municipal Court in Prague"},"taxId":{"type":"string","nullable":true,"example":"CZ12345678"},"vatId":{"type":"string","nullable":true,"example":"CZ12345678"},"streetWithNo":{"type":"string","nullable":true,"example":"Wenceslas Square 1"},"address2":{"type":"string","nullable":true,"example":"Suite 100"},"city":{"type":"string","nullable":true,"example":"Prague"},"region":{"type":"string","nullable":true,"example":"Prague"},"postCode":{"type":"string","nullable":true,"example":"11000"},"countryCode":{"type":"string","nullable":true,"example":"CZ"},"telephone":{"type":"string","nullable":true,"example":"+420123456789"},"contactPhone":{"type":"string","nullable":true,"example":"+420123456789"},"contactEmail":{"type":"string","format":"email","nullable":true,"example":"info@example.com"},"website":{"type":"string","nullable":true,"example":"https://example.com"},"logoUrl":{"type":"string","nullable":true,"example":"https://example.com/logo.png"},"defaultCostCenterId":{"type":"string","format":"uuid","nullable":true,"description":"Default cost center record ID used for newly created or received documents when no company-specific cost center is assigned.","example":"550e8400-e29b-41d4-a716-446655440000"},"language":{"type":"string","example":"cs"},"isVerified":{"type":"boolean","readOnly":true,"example":true},"blocked":{"type":"boolean","readOnly":true,"example":false},"blockedReason":{"type":"string","nullable":true,"readOnly":true,"example":"Suspicious activity detected"},"rateLimit":{"type":"string","nullable":true,"example":"100/minute"},"verifiedRegistrationNumber":{"type":"string","nullable":true,"example":"12345678"},"verifiedTaxId":{"type":"string","nullable":true,"example":"CZ12345678"},"verifiedVatId":{"type":"string","nullable":true,"example":"CZ12345678"},"emailVerified":{"type":"boolean","example":true},"emailVerifiedAt":{"type":"string","format":"date-time","nullable":true},"registrationVerified":{"type":"boolean","example":true},"registrationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"bankAccountVerified":{"type":"boolean","example":true},"bankAccountVerifiedAt":{"type":"string","format":"date-time","nullable":true},"authorizedPersonVerified":{"type":"boolean","example":true},"authorizedPersonVerifiedAt":{"type":"string","format":"date-time","nullable":true},"phoneVerified":{"type":"boolean","example":true},"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.","example":"all"},"skTddReporting":{"type":"string","enum":["auto","none","domestic-only","all"],"description":"SK TaxData (TDD) reporting mode. `auto` resolves to `none` before 2027-01-01, `domestic-only` from 2027-01-01, and `all` from 2030-01-01 for Slovak participants. Non-Slovak participants never generate SK TDD.","default":"auto","example":"auto"},"isCorporation":{"type":"boolean","nullable":true,"example":true},"isVatPayer":{"type":"boolean","nullable":true,"description":"Whether this participant is a registered VAT payer according to the most recent ADISSPR check.","example":true},"adissrBankAccounts":{"type":"array","items":{"type":"object"},"nullable":true,"example":["CZ6508000000192000145399"]},"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.","example":true},"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.","example":true},"acceptInvoices":{"type":"boolean","description":"Whether inbound invoice-like documents are accepted for this participant.","example":true},"acceptSelfBilling":{"type":"boolean","description":"Whether inbound self-billing invoice and credit note documents are accepted for this participant.","example":true},"acceptOrders":{"type":"boolean","description":"Whether inbound orders are accepted for this participant.","example":false},"disableBusinessCards":{"type":"boolean","description":"When true, business card export is hidden from SMP and the participant is not published to the Peppol Directory.","example":false},"acceptDespatchAdvices":{"type":"boolean","description":"Whether inbound despatch advice documents (BIS 30 shipping notices) are accepted for this participant.","example":false},"acceptOrderConfirmations":{"type":"boolean","description":"Whether inbound order confirmation documents are accepted for this participant.","example":false},"acceptReceiptAdvices":{"type":"boolean","description":"Whether inbound receipt advice documents are accepted for this participant.","example":false},"acceptOrderModifications":{"type":"boolean","description":"Whether inbound OrderChange and OrderCancellation documents are accepted for this participant.","example":false},"acceptCatalogues":{"type":"boolean","description":"Whether inbound catalogue documents are accepted for this participant.","example":false},"extraPeppolIds":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Additional Peppol identifiers accepted for this participant (read-only via participant update API).","example":["0245:9876543210"]},"extraDocumentTypes":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Additional inbound document types accepted for this participant.","example":["despatch-advice"]},"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","skTddReporting","rejectInvalidRegistrations","rejectInvalidBankAccounts","acceptInvoices","acceptSelfBilling","acceptOrders","acceptDespatchAdvices","acceptOrderConfirmations","acceptReceiptAdvices","acceptOrderModifications","acceptCatalogues","peppol","createdAt","updatedAt"]},"ParticipantPeppolSettings":{"type":"object","properties":{"rejectInvalidRegistrations":{"type":"boolean","example":true},"rejectInvalidBankAccounts":{"type":"boolean","example":true},"autoAcknowledge":{"type":"boolean","example":true},"skTddReporting":{"type":"string","enum":["auto","none","domestic-only","all"],"description":"SK TaxData (TDD) reporting mode. `auto` resolves by date for Slovak participants; `none` disables SK TDD; `domestic-only` reports documents whose sender and recipient share the same country code; `all` reports all eligible SK TDD documents.","default":"auto","example":"auto"},"acceptInvoices":{"type":"boolean","description":"Whether inbound invoice-like documents are accepted for this participant.","example":true},"acceptSelfBilling":{"type":"boolean","description":"Whether inbound self-billing invoice and credit note documents are accepted for this participant.","example":true},"acceptOrders":{"type":"boolean","description":"Whether inbound orders are accepted for this participant.","example":false},"acceptDespatchAdvices":{"type":"boolean","description":"Whether inbound despatch advice documents (BIS 30 shipping notices) are accepted for this participant.","example":false},"acceptOrderConfirmations":{"type":"boolean","description":"Whether inbound order confirmation (OrderResponse) documents are accepted for this participant.","example":false},"acceptReceiptAdvices":{"type":"boolean","description":"Whether inbound receipt advice documents are accepted for this participant.","example":false},"acceptOrderModifications":{"type":"boolean","description":"Whether inbound OrderChange and OrderCancellation documents are accepted for this participant.","example":false},"acceptCatalogues":{"type":"boolean","description":"Whether inbound catalogue documents are accepted for this participant.","example":false},"extraPeppolIds":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Read-only additional Peppol IDs accepted for the participant.","example":["0245:9876543210"]},"extraDocumentTypes":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Additional inbound document types accepted for this participant.","example":["despatch-advice"]}}},"ParticipantPeppolSettingsInput":{"type":"object","properties":{"skTddReporting":{"type":"string","enum":["auto","none","domestic-only","all"],"description":"Update SK TaxData (TDD) reporting mode for Slovak participants.","default":"auto","example":"auto"},"acceptInvoices":{"type":"boolean","description":"Update invoice acceptance flag.","example":true},"acceptSelfBilling":{"type":"boolean","description":"Update self-billing document acceptance flag.","example":true},"acceptOrders":{"type":"boolean","description":"Update order acceptance flag.","example":false},"acceptDespatchAdvices":{"type":"boolean","description":"Update despatch advice (BIS 30 shipping notice) acceptance flag.","example":false},"acceptOrderConfirmations":{"type":"boolean","description":"Update order confirmation acceptance flag.","example":false},"acceptReceiptAdvices":{"type":"boolean","description":"Update receipt advice acceptance flag.","example":false},"acceptOrderModifications":{"type":"boolean","description":"Update OrderChange and OrderCancellation acceptance flag.","example":false},"acceptCatalogues":{"type":"boolean","description":"Update catalogue acceptance flag.","example":false},"extraDocumentTypes":{"type":"array","items":{"type":"string"},"description":"Replace list of extra accepted document types.","example":["despatch-advice"]}}},"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,"example":"0245:1234567890"},"receiverPeppolId":{"type":"string","nullable":true,"example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string","nullable":true,"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"},"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"],"example":"invoice"},"documentNumber":{"type":"string","nullable":true,"example":"INV-2026-001"},"costCenter":{"type":"string","nullable":true,"example":"FIN-001"},"originalFormat":{"type":"string","nullable":true,"enum":["UBL","ISDOC","ISDOCX","POHODA","MRP","CII","FACTUR_X","ORDER_X","ZUGFERD","MONEY_S3","FACTURAE","FATTURAPA","KSEF"],"example":"UBL"},"status":{"type":"string","description":"Document processing status. `draft` and `pending` are transient states; `sent`, `confirmed`, `rejected` and `failed` are terminal for the underlying transmission. When returned after a completed wait-for-result request, the status is a transmission result; a timeout instead returns the separate processing payload described by WaitForResultQuery.","enum":["draft","pending","sent","confirmed","received","rejected","failed"],"example":"sent"},"validationStatus":{"type":"string","enum":["need-validation","valid","invalid"],"example":"valid"},"direction":{"type":"string","enum":["inbound","outbound"],"example":"outbound"},"isRead":{"type":"boolean","example":true},"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","enum":["none","pending","pending_review","verified","expired","failed"],"description":"Overall verification status. `none` means no verification has been initiated yet.","example":"verified"},"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,"example":"12345678"},"taxId":{"type":"string","nullable":true,"example":"CZ12345678"},"vatId":{"type":"string","nullable":true,"example":"CZ12345678"}},"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,"example":"Jan"},"lastName":{"type":"string","nullable":true,"example":"Novák"},"email":{"type":"string","example":"jan.novak@example.com"}},"required":["id","email"]},{"type":"null"}]},"eventType":{"type":"string","example":"document_sent"},"severity":{"type":"string","enum":["info","peppol","document","security","warning","error"],"example":"document"},"message":{"type":"string","example":"Document sent successfully"},"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"],"example":"tsr"},"reporterId":{"type":"string","example":"PEPPOL_AP_SEAT_ID_1"},"periodStart":{"type":"string","format":"date","example":"2026-01-01"},"periodEnd":{"type":"string","format":"date","example":"2026-01-31"},"reportXml":{"type":"string","nullable":true},"status":{"type":"string","enum":["generated","submitted","failed"],"example":"submitted"},"transmissionId":{"type":"string","nullable":true},"submittedAt":{"type":"string","format":"date-time","nullable":true},"errorMessage":{"type":"string","nullable":true,"example":"Reporting endpoint returned HTTP 500"},"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,"example":"0245:1234567890"},"receiverPeppolId":{"type":"string","nullable":true,"example":"0245:9876543210"},"documentTypeIdentifier":{"type":"string","nullable":true,"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"},"protocol":{"type":"string","nullable":true,"example":"AS4"},"status":{"type":"string","description":"Current document lifecycle status. This schema is also used by the document status endpoint. When returned after a completed wait-for-result request, the transmission has reached a result; a timeout instead uses the separate processing payload described by WaitForResultQuery.","enum":["draft","pending","sent","confirmed","received","rejected","failed"],"example":"sent"},"errorMessage":{"type":"string","nullable":true,"example":"Connection timed out"},"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, …","example":"invoice"},"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","example":"sk-tax-authority"},"status":{"type":"string","enum":["pending","retrying","failed","sent"],"example":"sent"},"attemptCount":{"type":"integer","example":1},"maxAttempts":{"type":"integer","example":10},"nextAttemptAt":{"type":"string","format":"date-time"},"lastAttemptAt":{"type":"string","format":"date-time","nullable":true},"lastError":{"type":"string","nullable":true,"example":"Reporting endpoint returned HTTP 500"},"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","example":"member"},"status":{"type":"string","example":"pending"},"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","example":"Accounting Integration"},"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.","example":"tenant"},"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`.","example":"admin"},"rateLimit":{"type":"string","nullable":true,"example":"100/minute"},"isActive":{"type":"boolean","example":true},"blocked":{"type":"boolean","readOnly":true,"example":false},"blockedReason":{"type":"string","nullable":true,"readOnly":true,"example":"Suspicious activity detected"},"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","example":"Accounting Integration"},"validTo":{"type":"string","format":"date-time","nullable":true},"isActive":{"type":"boolean","example":true},"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,"example":"https://example.com/webhooks/peppol"},"events":{"type":"array","items":{"type":"string","enum":["document.received","document.sent","document.delivered","document.failed","mlr","invoice.response","order.response","account.verified","sk.portal.received","certificate.expiring"]},"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"]},"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, certificate.expiring, and sk.portal.received events.","example":["invoice","creditnote"]},"isActive":{"type":"boolean","example":true},"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,"example":"https://example.com/webhooks/peppol"},"events":{"type":"array","items":{"type":"string","enum":["document.received","mlr","invoice.response","order.response","document.sent","document.delivered","document.failed","account.verified","sk.portal.received","certificate.expiring"]},"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"]},"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, certificate.expiring, and sk.portal.received events.","example":["invoice","creditnote"]},"secret":{"type":"string","example":"whsec_5f8b2c1e9a3d4f6e7c8b9a0d1e2f3a4b"},"isActive":{"type":"boolean","example":true},"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","example":"Acme s.r.o."},"code":{"type":"string","example":"CUST-001"},"registrationNumber":{"type":"string","example":"12345678"},"bankAccount":{"type":"string","example":"CZ6508000000192000145399"},"registrationInfo":{"type":"string","example":"Registered in the Commercial Register kept by the Municipal Court in Prague"},"taxId":{"type":"string","example":"CZ12345678"},"vatId":{"type":"string","example":"CZ12345678"},"streetWithNo":{"type":"string","example":"Wenceslas Square 1"},"address2":{"type":"string","example":"Suite 100"},"city":{"type":"string","example":"Prague"},"region":{"type":"string","example":"Prague"},"postCode":{"type":"string","example":"11000"},"countryCode":{"type":"string","example":"CZ"},"telephone":{"type":"string","example":"+420123456789"},"contactPhone":{"type":"string","example":"+420123456789"},"contactEmail":{"type":"string","format":"email","example":"info@example.com"},"website":{"type":"string","example":"https://example.com"},"logoUrl":{"type":"string","example":"https://example.com/logo.png"},"defaultCostCenterId":{"type":"string","format":"uuid","nullable":true,"description":"Default cost center record ID used for new outbound/inbound documents without company-specific assignment.","example":"550e8400-e29b-41d4-a716-446655440000"},"language":{"type":"string","minLength":2,"maxLength":2,"example":"cs"},"rateLimit":{"type":"string","example":"100/minute"},"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.","example":true},"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).","example":true},"skTddReporting":{"type":"string","enum":["auto","none","domestic-only","all"],"description":"SK TaxData (TDD) reporting mode for Slovak participants.","default":"auto","example":"auto"},"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","example":"https://example.com/webhooks/peppol"},"events":{"type":"array","items":{"type":"string","enum":["document.received","mlr","invoice.response","order.response","document.sent","document.delivered","document.failed","account.verified","sk.portal.received","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, certificate.expiring, and sk.portal.received events.","example":["invoice","creditnote"]}},"required":["events"]},"UpdateWebhookRequest":{"type":"object","properties":{"extId":{"type":"string"},"url":{"type":"string","format":"uri","example":"https://example.com/webhooks/peppol"},"events":{"type":"array","items":{"type":"string","enum":["document.received","mlr","invoice.response","order.response","document.sent","document.delivered","document.failed","account.verified","sk.portal.received","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"]},"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.","example":["invoice","creditnote"]},"isActive":{"type":"boolean","example":true}}},"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,"example":"accounting@example.com"},"isActive":{"type":"boolean","example":true},"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,"example":"accounting@example.com"}},"required":["email"]},"UpdateAllowedEmailRequest":{"description":"Request body for updating an allowed email entry.","type":"object","properties":{"isActive":{"type":"boolean","example":true}}},"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,"example":"pripona123@in.example.com"},"isActive":{"type":"boolean","example":true},"blocked":{"type":"boolean","readOnly":true,"example":false},"blockedReason":{"type":"string","nullable":true,"readOnly":true,"example":"Spam reports exceeded threshold"},"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","example":true}}},"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,"example":"email"},"address":{"type":"string","nullable":true,"description":"Destination address — email address or phone number depending on the type.","example":"accounting@example.com"},"isActive":{"type":"boolean","example":true},"sendReceivedInvoices":{"type":"boolean","description":"Whether received invoices and credit notes should trigger this notification. Defaults to true.","example":true},"sendDeliveryStatus":{"type":"boolean","description":"Whether sent/failed delivery status updates should trigger this notification. Defaults to true.","example":true},"sendOtherDocumentTypes":{"type":"boolean","description":"Whether other received document types such as orders should trigger this notification. Defaults to true.","example":true},"costCenters":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Optional list of cost centers that should trigger this notification. When omitted, all cost centers are included.","example":["FIN-001","OPS-001"]},"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","example":"pdf"},"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"],"example":"email"},"address":{"type":"string","maxLength":255,"example":"accounting@example.com"},"sendReceivedInvoices":{"type":"boolean","default":true},"sendDeliveryStatus":{"type":"boolean","default":true},"sendOtherDocumentTypes":{"type":"boolean","default":true},"costCenters":{"type":"array","items":{"type":"string"},"description":"Optional list of cost centers that should trigger this notification.","example":["FIN-001"]},"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.","example":"pdf"}},"required":["type"]},"UpdateNotificationRequest":{"description":"Request body for updating a notification channel.","type":"object","properties":{"type":{"type":"string","enum":["email","sms"],"example":"email"},"address":{"type":"string","maxLength":255,"example":"accounting@example.com"},"isActive":{"type":"boolean","example":true},"sendReceivedInvoices":{"type":"boolean","example":true},"sendDeliveryStatus":{"type":"boolean","example":true},"sendOtherDocumentTypes":{"type":"boolean","example":true},"costCenters":{"type":"array","items":{"type":"string"},"description":"Optional replacement list of cost centers that should trigger this notification.","example":["FIN-001"]},"attachmentType":{"type":"string","enum":["none","original","pdf","isdoc","isdocx","cii","factur-x","order-x","zugferd"],"example":"pdf"}}},"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"],"example":"email"},"address":{"type":"string","example":"accounting@example.com"},"subject":{"type":"string","example":"New invoice received"},"body":{"type":"string","example":"You have received a new invoice INV-2026-001 from Acme s.r.o."},"status":{"type":"string","enum":["to-send","sent","rejected","failed"],"example":"sent"},"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","example":"Acme s.r.o."},"accessPointId":{"type":"string","format":"uuid","description":"Optional access point to associate with the tenant."},"language":{"type":"string","minLength":2,"maxLength":2,"example":"cs"}},"required":["name"]},"UpdateTenantRequest":{"type":"object","properties":{"extId":{"type":"string"},"name":{"type":"string","example":"Acme s.r.o."},"language":{"type":"string","minLength":2,"maxLength":2,"example":"cs"},"accessPointId":{"type":"string","nullable":true,"format":"uuid","description":"Optional access point to associate with the tenant, or null to clear it."},"isActive":{"type":"boolean","example":true}}},"AddTenantUserRequest":{"type":"object","properties":{"userId":{"type":"string","description":"User UUID or external reference in ext:{extId} format."},"role":{"type":"string","enum":["owner","admin","member","sender","reader"],"example":"member"}},"required":["userId"]},"UpdateTenantUserRoleRequest":{"type":"object","properties":{"role":{"type":"string","enum":["owner","admin","member","sender","reader"],"example":"member"}},"required":["role"]},"CreateParticipantRequest":{"type":"object","properties":{"extId":{"type":"string"},"name":{"type":"string","example":"Acme s.r.o."},"code":{"type":"string","example":"CUST-001"},"registrationNumber":{"type":"string","example":"12345678"},"bankAccount":{"type":"string","example":"CZ6508000000192000145399"},"registrationInfo":{"type":"string","example":"Registered in the Commercial Register kept by the Municipal Court in Prague"},"taxId":{"type":"string","example":"CZ12345678"},"vatId":{"type":"string","example":"CZ12345678"},"streetWithNo":{"type":"string","example":"Wenceslas Square 1"},"address2":{"type":"string","example":"Suite 100"},"city":{"type":"string","example":"Prague"},"region":{"type":"string","example":"Prague"},"postCode":{"type":"string","example":"11000"},"countryCode":{"type":"string","example":"CZ"},"telephone":{"type":"string","example":"+420123456789"},"contactPhone":{"type":"string","example":"+420123456789"},"contactEmail":{"type":"string","example":"info@example.com"},"website":{"type":"string","example":"https://example.com"},"logoUrl":{"type":"string","example":"https://example.com/logo.png"},"defaultCostCenterId":{"type":"string","format":"uuid","nullable":true,"description":"Default cost center record ID used for new outbound/inbound documents without company-specific assignment.","example":"550e8400-e29b-41d4-a716-446655440000"},"language":{"type":"string","minLength":2,"maxLength":2,"example":"cs"},"skTddReporting":{"type":"string","enum":["auto","none","domestic-only","all"],"description":"SK TaxData (TDD) reporting mode for Slovak participants.","default":"auto","example":"auto"},"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"],"example":"outbound"},"format":{"type":"string","nullable":true,"example":"UBL"},"documentTypeIdentifier":{"type":"string","nullable":true,"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"},"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"],"example":"invoice"},"senderPeppolId":{"type":"string","nullable":true,"example":"0245:1234567890"},"receiverPeppolId":{"type":"string","nullable":true,"example":"0245:9876543210"},"status":{"type":"string","description":"Current document lifecycle status. This schema is also used by the document status endpoint. When returned after a completed wait-for-result request, the transmission has reached a result; a timeout instead uses the separate processing payload described by WaitForResultQuery.","enum":["draft","pending","sent","confirmed","received","rejected","failed"],"example":"sent"},"validationStatus":{"type":"string","enum":["need-validation","valid","invalid"],"example":"valid"},"isRead":{"type":"boolean","example":true},"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,"example":"delivered"},"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).","example":"sent"},"attempts":{"type":"integer","description":"Number of send attempts already performed.","example":1},"maxAttempts":{"type":"integer","description":"Maximum number of allowed attempts before permanent failure.","example":10},"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.","example":"Connection timed out"},"receivingServer":{"type":"string","nullable":true,"description":"Receiving access point/server reported by transport layer.","example":"ap.example.com"}},"required":["status","attempts","maxAttempts","nextAttemptAt","lastAttemptAt","lastError","receivingServer"]}},"required":["documentId","direction","documentType","status","validationStatus","isRead","createdAt","updatedAt"]},"WaitForResultTimeoutResponse":{"description":"Returned when wait-for-result reaches its 120-second limit before a transmission result is available.","type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["processing"]},"waitForResultTimedOut":{"type":"boolean","enum":[true]},"message":{"type":"string"}},"required":["documentId","status","waitForResultTimedOut","message"]}},"required":["success","data"]},"WaitForResultCompletedResponse":{"description":"Returned when wait-for-result observes a transmission result before its time limit.","type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/ParticipantDocumentStatus"}},"required":["success","data"]},"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"]},"DocumentSyncResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"items":{"type":"array","description":"Changed document metadata. XML and PDF content are never included.","items":{"$ref":"#/components/schemas/Document"}},"deletedIds":{"type":"array","items":{"type":"string","format":"uuid"}},"nextOffset":{"type":"integer","nullable":true,"description":"Pass this value as offset to retrieve the next page, or null when synchronization is complete."},"serverTime":{"type":"string","format":"date-time"}},"required":["items","deletedIds","nextOffset","serverTime"]}},"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","example":"jan.novak@example.com"},"firstName":{"type":"string","nullable":true,"example":"Jan"},"lastName":{"type":"string","nullable":true,"example":"Novák"},"role":{"type":"string","enum":["owner","admin","member","sender","reader"],"example":"member"},"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","example":"jan.novak@example.com"},"firstName":{"type":"string","nullable":true,"example":"Jan"},"lastName":{"type":"string","nullable":true,"example":"Novák"},"language":{"type":"string","enum":["en","cs","de","sk","pl","hu","fr","it","es","ro","hr","sl","ua","pt","dk","fi","gr","lu","no","se","nl","bg","et","lv","lt"],"example":"cs"},"phone":{"type":"string","nullable":true,"example":"+420123456789"},"jobTitle":{"type":"string","nullable":true,"example":"Finance Manager"},"company":{"type":"string","nullable":true,"example":"Acme s.r.o."},"avatar":{"type":"string","nullable":true,"description":"Avatar image as a base64 data URL"},"otpEnabled":{"type":"boolean","example":false},"isEmailVerified":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"role":{"type":"string","enum":["admin","member","sender","reader","viewer"],"example":"member"},"costCenters":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Optional participant-user scope limiting access to documents with matching cost centers.","example":["FIN-001"]}},"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"]},"CostCenter":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"FIN-001"},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","participantId","name","isActive","createdAt","updatedAt"]},"Company":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Acme s.r.o."},"identityKey":{"type":"string","nullable":true,"example":"acme-s-r-o"},"costCenter":{"type":"string","nullable":true,"example":"FIN-001"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","participantId","name","createdAt","updatedAt"]},"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","example":"Acme s.r.o."},"tenantId":{"type":"string","format":"uuid"},"tenantName":{"type":"string","example":"Acme Holding s.r.o."},"role":{"type":"string","enum":["admin","member","sender","reader","viewer"],"example":"member"},"isVerified":{"type":"boolean","example":true}},"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","example":"9987654321"},"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","example":false},"reviewNote":{"type":"string","nullable":true,"example":"Amount mismatch"}},"required":["id","variableSymbol","paymentReceivedAt","verifiedAt","refundSentAt","createdAt","expiresAt","pendingManualReview","reviewNote"]},"PeppolLookupResult":{"type":"object","properties":{"peppolId":{"type":"string","example":"0245:1234567890"},"scheme":{"type":"string","example":"iso6523-actorid-upis"},"exists":{"type":"boolean","example":true},"participantName":{"type":"string","example":"Acme s.r.o."},"smpServer":{"type":"string","example":"smp.example.com"},"businessCard":{"type":"object","description":"Included when `extended` query parameter is enabled.","additionalProperties":true},"supportsInvoiceResponse":{"type":"boolean","description":"Whether the participant advertises support for receiving IMR (Invoice Response, BIS 63).","example":true},"supportsOrderResponse":{"type":"boolean","description":"Whether the participant advertises support for receiving OrderResponse (BIS 28, T76).","example":false},"capabilities":{"type":"object","nullable":true,"properties":{"canReceiveInvoices":{"type":"boolean","example":true},"canReceiveOrders":{"type":"boolean","example":false},"documentTypes":{"type":"array","items":{"type":"string"},"example":["invoice","creditnote"]},"endpoint":{"type":"string","example":"https://ap.example.com/as4"}},"required":["canReceiveInvoices","canReceiveOrders"]},"cachedAt":{"type":"string","format":"date-time"},"originalIdentifier":{"type":"string","example":"CZ12345678"}},"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","example":"secret_5f8b2c1e9a3d4f6e7c8b9a0d1e2f3a4b"}},"required":["clientSecret"]}]},"Developer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Acme Integrations"},"description":{"type":"string","nullable":true,"example":"Third-party developer account for Acme integrations"},"isActive":{"type":"boolean","example":true},"rateLimit":{"type":"string","nullable":true,"example":"100/minute"},"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","example":"Acme Web App"},"description":{"type":"string","nullable":true,"example":"Third-party web application integrating with Peppol"},"requiredPermissions":{"type":"string","description":"Comma-separated list of required application permissions.","example":"send_documents,receive_documents"},"allowedLogoutUrls":{"type":"string","description":"JSON-encoded array of allowed logout URLs.","example":"[\"https://app.example.com/logout\"]"},"allowedOrigins":{"type":"string","description":"JSON-encoded array of allowed origins.","example":"[\"https://app.example.com\"]"},"allowedCallbackUrls":{"type":"string","nullable":true,"description":"JSON-encoded array of allowed callback URLs.","example":"[\"https://app.example.com/callback\"]"},"isActive":{"type":"boolean","example":true},"blocked":{"type":"boolean","readOnly":true,"example":false},"blockedReason":{"type":"string","nullable":true,"readOnly":true,"example":"Suspicious activity detected"},"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","example":"Production key"},"rateLimit":{"type":"string","nullable":true,"example":"100/minute"},"isActive":{"type":"boolean","example":true},"blocked":{"type":"boolean","readOnly":true,"example":false},"blockedReason":{"type":"string","nullable":true,"readOnly":true,"example":"Suspicious activity detected"},"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.","example":"secret_5f8b2c1e9a3d4f6e7c8b9a0d1e2f3a4b"},"message":{"type":"string","example":"Developer API key created successfully"}},"required":["clientSecret"]}]},"DeveloperUser":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"role":{"type":"string","example":"owner"},"email":{"type":"string","example":"jan.novak@example.com"},"firstName":{"type":"string","nullable":true,"example":"Jan"},"lastName":{"type":"string","nullable":true,"example":"Novák"}},"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","example":"sent"},"sentAt":{"type":"string","format":"date-time","nullable":true},"receivedAt":{"type":"string","format":"date-time","nullable":true},"errorMessage":{"type":"string","nullable":true,"example":"Connection timed out"},"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"],"example":"inbound"},"format":{"type":"string","nullable":true,"example":"UBL"},"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"],"example":"invoice"},"documentNumber":{"type":"string","nullable":true,"example":"INV-2026-001"},"senderPeppolId":{"type":"string","nullable":true,"example":"0245:1234567890"},"receiverPeppolId":{"type":"string","nullable":true,"example":"0245:9876543210"},"status":{"type":"string","example":"received"},"validationStatus":{"type":"string","enum":["need-validation","valid","invalid"],"example":"valid"},"isRead":{"type":"boolean","example":false},"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. When `send-or-report=true` and the recipient is not registered on the Peppol network, the document is routed through the applicable legal reporting channel instead (e.g. SK Tax Data).","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"Transmission result returned when wait-for-result completes before its 120-second limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitForResultCompletedResponse"}}}},"202":{"description":"Without wait-for-result, the document was accepted for asynchronous transmission (data.status=accepted). With wait-for-result, the 120-second wait timed out (data.status=processing and data.waitForResultTimedOut=true).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/WaitForResultTimeoutResponse"},{"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","enum":["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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"Raw XML document content (UTF-8)."}},"text/xml":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"Transmission result returned when wait-for-result completes before its 120-second limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitForResultCompletedResponse"}}}},"202":{"description":"Without wait-for-result, the document was accepted for asynchronous transmission (data.status=accepted). With wait-for-result, the 120-second wait timed out (data.status=processing and data.waitForResultTimedOut=true).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/WaitForResultTimeoutResponse"},{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["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":["isdoc","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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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/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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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":["isdoc","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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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":["isdoc","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"},{"$ref":"#/components/parameters/SendOrReportQuery"}],"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},"parentAccessPointId":{"type":"string","format":"uuid","nullable":true},"primaryParticipantId":{"type":"string","format":"uuid","nullable":true},"fsSrPortalId":{"type":"string","nullable":true,"maxLength":50}}}}}},"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},"parentAccessPointId":{"type":"string","format":"uuid","nullable":true},"primaryParticipantId":{"type":"string","format":"uuid","nullable":true},"fsSrPortalId":{"type":"string","nullable":true,"maxLength":50},"blocked":{"type":"boolean"},"blockedReason":{"type":"string","nullable":true,"maxLength":4000},"skPortalWebhookSecretEncrypted":{"type":"string","nullable":true,"maxLength":2048,"description":"Write-only plaintext secret. Value is encrypted before storage and never returned by API."}}}}}},"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","failed","delivery_failed","permanent_failure","response_sent","error","reporting_enqueued","reporting_sent","reporting_delivery_failed","reporting_permanent_failure","sml_registered","sml_unregistered","sml_register_failed","sml_unregister_failed","directory_publish_succeeded","directory_publish_failed","directory_delete_succeeded","directory_delete_failed"]},"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","receive_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 a 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 include both `access_token` and `refresh_token` in the returned payload.","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/auth/renew":{"post":{"tags":["Auth"],"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/auth/revoke":{"post":{"tags":["Auth"],"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/auth/token/status":{"get":{"tags":["Auth"],"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/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","enum":["draft","pending","sent","confirmed","received","rejected","failed"]},"description":"Filter by document status."},{"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)"},"statusClarificationReason":{"type":"string","description":"Optional IMR status clarification reason code (listID OPStatusReason): NON, REF, LEG, REC, QUA, DEL, PRI, QTY, ITM, PAY, UNR, FIN, PPD, OTH"},"statusClarificationAction":{"type":"string","description":"Optional IMR status clarification action code (listID OPStatusAction): NOA, PIN, NIN, CNF, CNP, CNA, OTH"}}}}}},"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","failed","delivery_failed","permanent_failure","response_sent","error","reporting_enqueued","reporting_sent","reporting_delivery_failed","reporting_permanent_failure","sml_registered","sml_unregistered","sml_register_failed","sml_unregister_failed","directory_publish_succeeded","directory_publish_failed","directory_delete_succeeded","directory_delete_failed"]},"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":"documentType","in":"query","description":"Filter inbound documents by document type. Accepts comma-separated values from: `order`, `invoice`, `creditInvoice`, `mlr`.","schema":{"type":"string","example":"invoice,mlr"}},{"name":"wait-for-data","in":"query","description":"Presence-only flag (value is ignored) enabling long-polling. If the request would otherwise return zero documents, the connection is held open until a matching document is created/updated or a server-side timeout elapses (default 25s, configurable via `INBOX_WAIT_FOR_DATA_TIMEOUT_MS`), then the same query is re-run once before responding. Returning an empty result after the timeout is a normal, successful response — callers should immediately repeat the request to keep waiting for new documents.","schema":{"type":"string"},"allowEmptyValue":true,"example":""},{"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":"documentType","in":"query","required":false,"description":"Filter unread inbound documents by document type. Accepts comma-separated values from: `order`, `invoice`, `creditInvoice`, `mlr`.","schema":{"type":"string","example":"creditInvoice,order"}},{"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","enum":["draft","pending","sent","confirmed","received","rejected","failed"]},"description":"Filter by document status."},{"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","MRP","CII","FACTUR_X","ORDER_X","ZUGFERD","MONEY_S3","FACTURAE","FATTURAPA","KSEF"]}},{"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/sync":{"get":{"tags":["Documents"],"summary":"Synchronize participant document metadata changes","description":"Returns document metadata changed since the requested timestamp and hard-deletion tombstones. Use this to update an offline cache; XML and PDF content are not returned.","security":[{"oauth2":[]},{"apiKeyAuth":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"since","in":"query","required":true,"description":"ISO 8601 timestamp from the last successful synchronization.","schema":{"type":"string","format":"date-time"}},{"name":"offset","in":"query","required":false,"description":"Zero-based offset for the next synchronization page.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Changed document metadata and deletion tombstones","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentSyncResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"operationId":"syncParticipantDocuments"}},"/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","FACTURAE","FATTURAPA","KSEF"]},"bisFormat":{"type":"string","enum":["UBL","ISDOC","ISDOCX","POHODA","CII","FACTUR_X","ORDER_X","ZUGFERD","FACTURAE","FATTURAPA","KSEF"]},"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","FACTURAE","FATTURAPA","KSEF"]}}}},"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","failed","delivery_failed","permanent_failure","response_sent","error","reporting_enqueued","reporting_sent","reporting_delivery_failed","reporting_permanent_failure","sml_registered","sml_unregistered","sml_register_failed","sml_unregister_failed","directory_publish_succeeded","directory_publish_failed","directory_delete_succeeded","directory_delete_failed"]},"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}/set-vpds":{"post":{"tags":["Participants"],"summary":"Set Slovakia VPDS selection for a participant","description":"Specify code for Slovakia VPDS selection. This is useful when e-postary (Sprostredkovateľ) is changing certified provider (Certifikovaný poskytovateľ).","parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"oauth2":[]},{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"verification_token":{"type":"string","description":"VPDS verification token. Either verification_token or code is required."},"code":{"type":"string","description":"Legacy alias for verification_token."}}},"example":{"verification_token":"vpds-token-123"}}}},"responses":{"201":{"description":"VPDS hook log created and applied","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"hookLogId":{"type":"string","format":"uuid"},"participantId":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"accessPointId":{"type":"string","format":"uuid"},"dic":{"type":"string"},"selected":{"type":"boolean"},"skFsSrPortalVerified":{"type":"boolean"},"isVerified":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid payload or participant is not eligible for Slovakia VPDS"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Participant or access point not found"}}}},"/api/tenants/{tenantId}/participants/{participantId}/set-vpds":{"post":{"tags":["Participants"],"summary":"Set Slovakia VPDS selection for a tenant participant","description":"Tenant-scoped alias of /api/participants/{participantId}/set-vpds.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"oauth2":[]},{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"verification_token":{"type":"string"},"code":{"type":"string"}}},"example":{"verification_token":"vpds-token-123"}}}},"responses":{"201":{"description":"VPDS hook log created and applied"},"400":{"description":"Invalid payload or participant is not eligible for Slovakia VPDS"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Participant or access point not found"}}}},"/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"]},"costCenters":{"type":"array","items":{"type":"string"},"nullable":true}}}},"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"},"costCenters":{"type":"array","items":{"type":"string"},"description":"Optional document access scope by cost center. Available only when participant cost centers are enabled."}}}}}},"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"]},"costCenters":{"type":"array","items":{"type":"string"},"description":"Optional replacement document access scope by cost center."}}}}}},"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}/cost-centers":{"get":{"tags":["Participants"],"summary":"List participant cost centers","description":"Returns cost center records for the participant. When the participant has cost centers disabled (`enableCostCenters=false`), returns an empty list.","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Cost center list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"costCenters":{"type":"array","items":{"$ref":"#/components/schemas/CostCenter"}},"count":{"type":"integer","example":2}},"required":["success","costCenters","count"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"tags":["Participants"],"summary":"Create participant cost center","description":"Creates a cost center for the participant. Requires member-or-higher participant role and `enableCostCenters=true`.","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","example":"FIN-001"}}}}}},"responses":{"201":{"description":"Cost center created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CostCenter"}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/cost-centers/{costCenterId}":{"patch":{"tags":["Participants"],"summary":"Update participant cost center","description":"Updates cost center name and/or active state. Requires member-or-higher participant role and `enableCostCenters=true`.","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"costCenterId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"OPS-001"},"isActive":{"type":"boolean","example":true}}}}}},"responses":{"200":{"description":"Cost center updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CostCenter"}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Participants"],"summary":"Delete participant cost center","description":"Deletes a cost center. Requires member-or-higher participant role and `enableCostCenters=true`.","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"costCenterId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Cost center deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/companies":{"get":{"tags":["Participants"],"summary":"List participant companies","description":"Returns sender/receiver companies auto-discovered from documents for this participant. When cost centers are disabled (`enableCostCenters=false`), returns an empty list.","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Company list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"companies":{"type":"array","items":{"$ref":"#/components/schemas/Company"}},"count":{"type":"integer","example":10}},"required":["success","companies","count"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/participants/{participantId}/companies/{companyId}":{"patch":{"tags":["Participants"],"summary":"Assign company cost center","description":"Sets or clears the default cost center mapping for a discovered company. Requires member-or-higher participant role and `enableCostCenters=true`.","security":[{"oauth2":[]}],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"costCenter":{"type":"string","nullable":true,"example":"FIN-001"}}}}}},"responses":{"200":{"description":"Company updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Company"}},"required":["success","data"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"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."},{"name":"skip-kyc","in":"query","required":false,"schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"When 'true', skips the entire KYC chain (email, phone, business identity, bank account, authorized person) and evaluates only the SK-Portal step. Useful for callers who already performed KYC elsewhere and only need to manage the SK-Portal (Digitálny poštár) selection."},{"name":"skip-sk-portal","in":"query","required":false,"schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"When 'true', skips the SK-Portal (Digitálny poštár) step entirely, even for eligible Slovak participants."}],"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","SK-PORTAL","PEPPOL"],"description":"The first incomplete verification stage. SK-PORTAL applies only to Slovak participants who still need to select this access point as their 'Digitálny poštár' on the FS SR portal."},"finished":{"type":"boolean","description":"True when there is nothing left for the caller to do: the KYC chain (unless skip-kyc was used) and, when applicable, the SK-Portal step (unless skip-sk-portal was used) are both handled. When true, verificationUrl is an empty string."},"verificationUrl":{"type":"string","nullable":true,"description":"URL for continuing the verification flow: the web magic-link when the current stage is a KYC step, or the SK FS SR portal URL (with callback appended) when currentStage is SK-PORTAL. Empty string when finished=true. When callback is supplied, it is preserved as a query parameter on either URL.","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**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","failed","delivery_failed","permanent_failure","response_sent","error","reporting_enqueued","reporting_sent","reporting_delivery_failed","reporting_permanent_failure","sml_registered","sml_unregistered","sml_register_failed","sml_unregister_failed","directory_publish_succeeded","directory_publish_failed","directory_delete_succeeded","directory_delete_failed"]},"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). Successful responses include both `access_token` and `refresh_token` in the JSON body.","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","enum":["draft","pending","sent","confirmed","received","rejected","failed"]},"description":"Filter by document status."},{"name":"documentTypes"},{"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","failed","delivery_failed","permanent_failure","response_sent","error","reporting_enqueued","reporting_sent","reporting_delivery_failed","reporting_permanent_failure","sml_registered","sml_unregistered","sml_register_failed","sml_unregister_failed","directory_publish_succeeded","directory_publish_failed","directory_delete_succeeded","directory_delete_failed"]},"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"}},{"name":"tenantId","in":"query","required":false,"description":"Restrict the result to participants of this tenant.","schema":{"type":"string","format":"uuid"}},{"name":"q","in":"query","required":false,"description":"Case-insensitive participant name filter.","schema":{"type":"string"}},{"name":"includeAll","in":"query","required":false,"description":"Include every participant of the given tenantId (role is null when the user has no assignment). Requires the caller to be a member of that tenant.","schema":{"type":"boolean"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"maximum":200}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}}],"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","nullable":true,"enum":["admin","member","sender","reader","viewer"]}}}},"count":{"type":"integer"}},"required":["data","count"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/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"}}}}}}