{"openapi":"3.0.3","info":{"title":"ePostak Enterprise API — Full","description":"Pure Enterprise API contract. Connector is published as a separate product contract; the retired pre-launch compatibility aliases are no longer served.","version":"1.10.0","contact":{"email":"info@epostak.sk","url":"https://epostak.sk"}},"servers":[{"url":"https://epostak.sk/api/v1","description":"Production"}],"tags":[{"name":"Box","description":"ePošťák Box durable execution layer for staged, scheduled and retryable Peppol dispatch. No public RabbitMQ/Kafka API in v1."},{"name":"Documents","description":"Odosielanie dokumentov cez Peppol"},{"name":"Inbox","description":"Prijate dokumenty"},{"name":"Account","description":"Informacie o ucte a firme"},{"name":"Webhooks","description":"Push webhook subscriptions and Events pull subscriptions (Enterprise only). Prefer /events/pull for pull-based event handling; webhook-queue paths remain compatibility endpoints."},{"name":"Firms","description":"Sprava firiem a Peppol identifikatorov"},{"name":"White Label","description":"Accountless participant registration and migration for approved White Label intermediaries. These control-plane calls never accept X-Firm-Id."},{"name":"Peppol","description":"SMP lookup a Peppol directory"},{"name":"Reporting","description":"Statistiky a reporty"},{"name":"OAuth","description":"OAuth 2.0 token exchange"},{"name":"Auth","description":"API key introspection and rotation"},{"name":"Validation","description":"Public UBL/Peppol validator (no auth)"},{"name":"Payload Assistant","description":"Payload creation, OCR extraction, parse, convert and validation helpers for integrators. Retired Extraction/Documents aliases are no longer served; use the canonical Payload Assistant paths."},{"name":"Webhooks & Events","description":"Push webhooks and canonical Events pull endpoints for reliable ERP delivery. Retired webhook-queue aliases are no longer served."},{"name":"Lifecycle & proof","description":"Document status, timeline, responses and support/evidence packets for audit and dispute workflows."},{"name":"Integrator","description":"Integrator operations in this generated Enterprise profile."},{"name":"Outbox","description":"Outbox operations in this generated Enterprise profile."},{"name":"Pull API — Inbound","description":"Pull API — Inbound operations in this generated Enterprise profile."},{"name":"Pull API — Outbound","description":"Pull API — Outbound operations in this generated Enterprise profile."}],"security":[{"bearerAuth":[]}],"paths":{"/box/items":{"get":{"tags":["Box"],"summary":"List ePošťák Box items","description":"Lists durable Box items for the authenticated firm from the dedicated Box model. Box is not a Connector outbox alias; REST, Connector and Dashboard flows attach to it as a shared reliability layer.","operationId":"boxListItems","responses":{"200":{"description":"OK"},"401":{"description":"Request rejected with HTTP 401. The response includes a stable error code and requestId when available."},"403":{"description":"Request rejected with HTTP 403. The response includes a stable error code and requestId when available."},"429":{"description":"Request rejected with HTTP 429. The response includes a stable error code and requestId when available."}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:box","x-epostak-docs-anchor":"enterprise-boxlistitems"},"post":{"tags":["Box"],"summary":"Create ePošťák Box item","description":"Stages a document into ePošťák Box for durable, scheduled and retryable Peppol dispatch.","operationId":"boxCreateItem","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["payloadXml"],"properties":{"payloadXml":{"type":"string","description":"UBL XML payload to stage in encrypted Box storage."},"scheduledFor":{"type":"string","format":"date-time","description":"Optional future dispatch time."},"externalId":{"type":"string","description":"Optional caller-side id for idempotency and lookup."},"metadata":{"type":"object","additionalProperties":true}}}}}},"responses":{"201":{"description":"Created"},"400":{"description":"Request rejected with HTTP 400. The response includes a stable error code and requestId when available."},"401":{"description":"Request rejected with HTTP 401. The response includes a stable error code and requestId when available."},"403":{"description":"Request rejected with HTTP 403. The response includes a stable error code and requestId when available."},"409":{"description":"Request rejected with HTTP 409. The response includes a stable error code and requestId when available."},"413":{"description":"Request rejected with HTTP 413. The response includes a stable error code and requestId when available."},"422":{"description":"Request rejected with HTTP 422. The response includes a stable error code and requestId when available."},"429":{"description":"Request rejected with HTTP 429. The response includes a stable error code and requestId when available."}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:box","x-epostak-docs-anchor":"enterprise-boxcreateitem"}},"/box/items/{itemId}":{"get":{"tags":["Box"],"summary":"Get ePošťák Box item detail","description":"Returns status, safe storage summary, dispatch attempts and audit timeline without plaintext invoice payloads or attachments.","operationId":"boxGetItem","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Not found"}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:box","x-epostak-docs-anchor":"enterprise-boxgetitem"}},"/box/items/{itemId}/schedule":{"post":{"tags":["Box"],"summary":"Schedule a Box item","operationId":"boxScheduleItem","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scheduledFor"],"properties":{"scheduledFor":{"type":"string","format":"date-time","description":"Future dispatch time."}}}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Request rejected with HTTP 400. The response includes a stable error code and requestId when available."},"401":{"description":"Request rejected with HTTP 401. The response includes a stable error code and requestId when available."},"403":{"description":"Request rejected with HTTP 403. The response includes a stable error code and requestId when available."},"404":{"description":"Request rejected with HTTP 404. The response includes a stable error code and requestId when available."},"409":{"description":"Request rejected with HTTP 409. The response includes a stable error code and requestId when available."},"422":{"description":"Request rejected with HTTP 422. The response includes a stable error code and requestId when available."},"429":{"description":"Request rejected with HTTP 429. The response includes a stable error code and requestId when available."}},"description":"Schedule a Box item","x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:box","x-epostak-docs-anchor":"enterprise-boxscheduleitem"}},"/box/items/{itemId}/send-now":{"post":{"tags":["Box"],"summary":"Send a Box item now","description":"Attempts dispatch for an outbound Box item when a Connector/Enterprise dispatch pointer is available. Returns 409 when the item cannot be dispatched by this route.","operationId":"boxSendNow","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Dispatch attempted"},"409":{"description":"Dispatch pointer unavailable"}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:box","x-epostak-docs-anchor":"enterprise-boxsendnow"}},"/box/items/{itemId}/retry":{"post":{"tags":["Box"],"summary":"Retry a Box item","description":"Moves a failed or repairable outbound Box item back into the retry flow and records an audit event.","operationId":"boxRetryItem","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Request rejected with HTTP 400. The response includes a stable error code and requestId when available."},"401":{"description":"Request rejected with HTTP 401. The response includes a stable error code and requestId when available."},"403":{"description":"Request rejected with HTTP 403. The response includes a stable error code and requestId when available."},"404":{"description":"Request rejected with HTTP 404. The response includes a stable error code and requestId when available."},"409":{"description":"Request rejected with HTTP 409. The response includes a stable error code and requestId when available."},"422":{"description":"Request rejected with HTTP 422. The response includes a stable error code and requestId when available."},"429":{"description":"Request rejected with HTTP 429. The response includes a stable error code and requestId when available."}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:box","x-epostak-docs-anchor":"enterprise-boxretryitem"}},"/box/items/{itemId}/cancel":{"post":{"tags":["Box"],"summary":"Cancel a Box item","description":"Cancels an unsent outbound Box item. Sent or received archive items are retained by retention policy.","operationId":"boxCancelItem","parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Request rejected with HTTP 400. The response includes a stable error code and requestId when available."},"401":{"description":"Request rejected with HTTP 401. The response includes a stable error code and requestId when available."},"403":{"description":"Request rejected with HTTP 403. The response includes a stable error code and requestId when available."},"404":{"description":"Request rejected with HTTP 404. The response includes a stable error code and requestId when available."},"409":{"description":"Request rejected with HTTP 409. The response includes a stable error code and requestId when available."},"422":{"description":"Request rejected with HTTP 422. The response includes a stable error code and requestId when available."},"429":{"description":"Request rejected with HTTP 429. The response includes a stable error code and requestId when available."}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:box","x-epostak-docs-anchor":"enterprise-boxcancelitem"}},"/auth/token":{"post":{"tags":["Auth"],"summary":"Mint a JWT access token (OAuth 2.0 client_credentials)","description":"Exchange a `sk_live_*` or `sk_int_*` API key for a short-lived JWT access token + refresh token.\n\n**Body** (JSON or `application/x-www-form-urlencoded`):\n- `grant_type`: must be `client_credentials`\n- `client_id`: the client_id shown with the key; it must match the API key row UUID or displayed key prefix and must not be the secret\n- `client_secret`: the full `sk_live_*` or `sk_int_*` key\n- `scope` (optional): space-separated subset of the key's allowed scopes\n\n**Response** (RFC 6749):\n```json\n{\n  \"access_token\": \"eyJhbGciOiJSUzI1NiIs...\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 900,\n  \"refresh_token\": \"rt_...\",\n  \"scope\": \"documents:send documents:read\"\n}\n```\n\n**Errors** use Peppol error envelope: `{ error: { category, code, message, retryable, correlation_id, details? } }`.\n\nFailed-credential throttling: after 5 invalid attempts within 15 min, repeated exact-pair attempts and further invalid guesses targeting the same `client_id` return 423. A valid secret is authenticated before client-wide failure state is enforced and remains usable.\n\nThis endpoint is the canonical Enterprise URL; `/sapi/v1/auth/token` is the SAPI-spec equivalent and shares the same handler.","operationId":"authToken","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtTokenRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/JwtTokenRequest"}}}},"responses":{"200":{"description":"Access token + refresh token issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtTokenResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Invalid grant_type or malformed body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}}},"401":{"description":"Invalid client credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}}},"403":{"description":"Requested scope(s) not allowed by key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}}},"423":{"description":"Invalid credential attempts throttled after 5 failures; valid credentials remain usable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-api-key","integrator-api-key","peppol-client"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-authtoken"}},"/auth/renew":{"post":{"tags":["Auth"],"summary":"Refresh access token using a refresh token","description":"Rotate a refresh token: returns a new access JWT (15 min) + a new refresh token (30 days). The old refresh token is invalidated.\n\n**Body**:\n```json\n{ \"grant_type\": \"refresh_token\", \"refresh_token\": \"rt_...\" }\n```\n\nRefresh tokens are stateless JWTs verified server-side via Redis presence — once consumed, they cannot be reused (replay → 401).","operationId":"authRenew","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtRenewRequest"}}}},"responses":{"200":{"description":"New access + refresh token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtTokenResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Missing or malformed refresh_token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}}},"401":{"description":"Refresh token invalid, expired, or already consumed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-authrenew"}},"/auth/revoke":{"post":{"tags":["Auth"],"summary":"Revoke an access or refresh token (RFC 7009)","description":"Idempotent — always returns 200. Revoking an access token adds its `jti` to the Redis blocklist for the remainder of its lifetime. Revoking a refresh token deletes its server-side state.\n\n**Body**:\n```json\n{ \"token\": \"<jwt or refresh token>\", \"token_type_hint\": \"access_token\" | \"refresh_token\" }\n```\n\n`token_type_hint` is optional; the server detects the type automatically (`eyJ` prefix → JWT, `rt_` prefix → refresh).","operationId":"authRevoke","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtRevokeRequest"}}}},"responses":{"200":{"description":"Token revoked (or was already invalid — idempotent)","content":{"application/json":{"schema":{"type":"object","properties":{"revoked":{"type":"boolean"}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Missing token field","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-authrevoke"}},"/auth/token/status":{"get":{"tags":["Auth"],"summary":"Inspect current JWT — expiry, refresh hint, scope","description":"Returns metadata about the JWT presented in `Authorization: Bearer`. Useful for SDKs to decide whether to renew before making a long-running request.","operationId":"authTokenStatus","responses":{"200":{"description":"Token introspection","content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean"},"expires_at":{"type":"string","format":"date-time"},"expires_in_seconds":{"type":"integer"},"should_refresh":{"type":"boolean","description":"True if within the last 25% of the access token's TTL"},"refresh_recommended_at":{"type":"string","format":"date-time"},"scope":{"type":"string"},"firm_id":{"type":"string","format":"uuid","nullable":true},"integrator_id":{"type":"string","format":"uuid","nullable":true}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Missing or invalid JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-authtokenstatus"}},"/auth/status":{"get":{"tags":["Auth"],"summary":"API key introspection","description":"Returns metadata about the calling API key: permissions, linked firm, plan, rate-limit window. Cheap health-check alternative to `/account`.","operationId":"authStatus","responses":{"200":{"description":"Introspection OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthStatusResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-authstatus"}},"/auth/rotate-secret":{"post":{"tags":["Auth"],"summary":"Rotate the current API key","description":"Issues a new API key with the same name/permissions and marks the old one inactive immediately. The new key is returned ONCE in the response. Integrator keys (sk_int_*) are not rotatable via this endpoint — use the integrator dashboard.","operationId":"rotateApiKey","responses":{"200":{"description":"Key rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateSecretResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Integrator keys cannot be rotated via this endpoint, or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"API key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-rotateapikey"}},"/auth/ip-allowlist":{"get":{"tags":["Auth"],"summary":"Get IP allowlist for current key","description":"Returns the IP allowlist for the API key authenticating this request. Empty array → no IP restriction (any caller IP allowed). Per-key, not per-firm — `sk_live_*` and `sk_int_*` allowlists live in their own tables.\n\n**Requires `account:read` scope and an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"getIpAllowlist","responses":{"200":{"description":"Current allowlist","content":{"application/json":{"schema":{"type":"object","properties":{"ip_allowlist":{"type":"array","items":{"type":"string"}}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan does not allow this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-getipallowlist"},"put":{"tags":["Auth"],"summary":"Replace IP allowlist for current key","description":"Replaces the IP allowlist for the API key authenticating this request. Each entry is either a bare IP (v4 or v6) or a CIDR `addr/prefix`. Max 50 entries. Empty array clears the restriction. Cache is busted so changes are effective on the next request.\n\n**Requires `account:read` scope and an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"updateIpAllowlist","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ip_allowlist"],"properties":{"ip_allowlist":{"type":"array","maxItems":50,"items":{"type":"string","example":"203.0.113.42"}}}}}}},"responses":{"200":{"description":"Updated allowlist","content":{"application/json":{"schema":{"type":"object","properties":{"ip_allowlist":{"type":"array","items":{"type":"string"}}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Invalid entry or too many entries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan does not allow this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:auth","x-epostak-docs-anchor":"enterprise-updateipallowlist"}},"/oauth/token":{"post":{"tags":["OAuth"],"summary":"OAuth 2.0 token exchange","description":"**Public endpoint at `https://epostak.sk/api/oauth/token`** (NOT under `/api/v1/`). Exchange an authorization code for a new `sk_int_*` client secret. The returned secret is not a bearer token; exchange it via `POST /api/v1/auth/token` to mint the short-lived JWT used on `/api/v1/*` routes. Supports PKCE via `code_verifier`.","operationId":"oauthTokenExchange","servers":[{"url":"https://epostak.sk/api","description":"Public base (no /v1 prefix)"}],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenRequest"},"example":{"grant_type":"authorization_code","code":"auth_code_here","client_id":"client_id_here","client_secret":"client_secret_here","redirect_uri":"https://example.com/callback","code_verifier":"pkce_verifier_here"}}}},"responses":{"200":{"description":"Integrator client secret issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Invalid grant or request parameters (RFC 6749 error body)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthErrorResponse"}}}},"401":{"description":"Invalid client credentials (RFC 6749 error body)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["oauth-client"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:oauth","x-epostak-docs-anchor":"enterprise-oauthtokenexchange"}},"/account":{"get":{"tags":["Account"],"summary":"Informacie o ucte","description":"Vrati zakladne informacie o firme, stav Peppol registracie, aktivny plan a statistiky odoslanych/prijatych dokumentov.","operationId":"getAccount","responses":{"200":{"description":"Informacie o ucte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Firma nenajdena","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:account","x-epostak-docs-anchor":"enterprise-getaccount"}},"/licenses/info":{"get":{"tags":["Account"],"summary":"Plan and current-period usage","description":"Returns the firm's plan tier, current billing period usage (outbound + inbound API counts), overage so far, quota remaining, estimated month cost, and pricing tiers. Use for billing dashboards and quota warnings.\n\n**Requires `account:read` scope and an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"getLicenseInfo","responses":{"200":{"description":"Plan + usage snapshot","content":{"application/json":{"schema":{"type":"object","properties":{"firm":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"sandbox":{"type":"boolean"}}},"plan":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"active":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time","nullable":true},"daysUntilExpiry":{"type":"integer","nullable":true},"gracePeriodActive":{"type":"boolean"},"monthlyBase":{"type":"number"},"outboundLimit":{"type":"integer","nullable":true},"overageRate":{"type":"number","nullable":true},"inboundApiRate":{"type":"number","nullable":true},"hasApiAccess":{"type":"boolean"}}},"usage":{"type":"object","properties":{"period":{"type":"string","example":"2026-04"},"nextResetAt":{"type":"string","format":"date-time"},"outboundCount":{"type":"integer"},"inboundApiCount":{"type":"integer"},"overageAmount":{"type":"number"},"quotaRemaining":{"type":"integer","nullable":true},"usagePercent":{"type":"number","nullable":true},"estimatedMonthCost":{"type":"number"}}},"pricing":{"type":"object","properties":{"currency":{"type":"string","example":"EUR"},"model":{"type":"string","example":"tiered"},"outboundTiers":{"type":"array","items":{"type":"object"}},"inboundApiTiers":{"type":"array","items":{"type":"object"}}}}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan does not allow this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Firm not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:account","x-epostak-docs-anchor":"enterprise-getlicenseinfo"}},"/integrator/keys":{"get":{"tags":["Integrator"],"summary":"List integrator API keys","description":"Returns integrator API keys for the current `sk_int_*` JWT. No X-Firm-Id header — this is an integrator-level endpoint. Use it to find the `id` or `keyPrefix` of a key issued via `/api/oauth/token`.","operationId":"listIntegratorKeys","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Integrator API keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"keyPrefix":{"type":"string","example":"sk_int_xxxxx...abcd"},"name":{"type":"string","nullable":true},"scopes":{"type":"array","items":{"type":"string"}},"ipAllowlist":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing `firms:manage` scope or non-integrator key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:integrator","x-epostak-docs-anchor":"enterprise-listintegratorkeys"},"delete":{"tags":["Integrator"],"summary":"Deactivate an integrator API key","description":"Deactivates an active integrator API key. Send either `keyId` from `GET /api/v1/integrator/keys`, or `client_id` / `keyPrefix` returned by `/api/oauth/token`. The endpoint will not deactivate the integrator's last active key.","operationId":"deactivateIntegratorKey","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","format":"uuid","description":"UUID from `GET /api/v1/integrator/keys`."},"client_id":{"type":"string","description":"`sk_int_*` keyPrefix/client_id returned by `/api/oauth/token`.","example":"sk_int_xxxxx...abcd"}},"anyOf":[{"required":["keyId"]},{"required":["client_id"]}]},"example":{"client_id":"sk_int_xxxxx...abcd"}}}},"responses":{"200":{"description":"API key deactivated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"API key deactivated."}}}}}},"400":{"description":"Invalid body, already inactive, or last active key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing `firms:manage` scope or non-integrator key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"API key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:integrator","x-epostak-docs-anchor":"enterprise-deactivateintegratorkey"}},"/integrator/licenses/info":{"get":{"tags":["Account"],"summary":"Aggregate plan + current-period usage for an integrator","description":"Returns the integrator plan, current-period usage aggregated across managed firms, and the exact signed pricing snapshot used for billing. Outbound and inbound documents are tiered separately; under V1.2, document 20,001 and every later document in either direction is €0.04 without a custom order.\n\n**Requires `account:read` scope on a `sk_int_*` integrator key.** No X-Firm-Id header — the endpoint is integrator-scoped, not firm-scoped.","operationId":"getIntegratorLicenseInfo","security":[{"bearerAuth":[]}],"parameters":[{"name":"offset","in":"query","description":"Pagination offset for the per-firm list. Default 0.","required":false,"schema":{"type":"integer","minimum":0,"default":0}},{"name":"limit","in":"query","description":"Page size for the per-firm list. Max 100. Default 50.","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Plan + aggregate usage snapshot","content":{"application/json":{"schema":{"type":"object","properties":{"integrator":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"plan":{"type":"string","example":"integrator"},"monthlyDocumentLimit":{"type":"integer","nullable":true}}},"period":{"type":"string","example":"2026-04","description":"Current billing period in YYYY-MM (SK timezone)."},"nextResetAt":{"type":"string","format":"date-time","description":"When counters reset — 1st of next month, SK midnight in UTC."},"billable":{"type":"object","description":"Aggregate over firms on the `integrator-managed` plan (the integrator pays).","properties":{"managedFirms":{"type":"integer"},"outboundCount":{"type":"integer"},"inboundApiCount":{"type":"integer"},"outboundCharge":{"type":"number","description":"Tier rates applied to the aggregate outboundCount."},"inboundApiCharge":{"type":"number","description":"Tier rates applied to the aggregate inboundApiCount."},"totalCharge":{"type":"number","description":"Sum of outboundCharge + inboundApiCharge, rounded to cents."},"currency":{"type":"string","example":"EUR"}}},"nonManaged":{"type":"object","description":"Linked firms that pay their own plan (not billed to the integrator).","properties":{"firms":{"type":"integer"},"outboundCount":{"type":"integer"},"inboundApiCount":{"type":"integer"}}},"exceedsAutoTier":{"type":"boolean","description":"Historical signed-schedule flag. False for V1.2 because the 20,001+ public tier is billable automatically."},"contactThreshold":{"type":"integer","example":20000,"description":"Compatibility field retaining the historical threshold. For V1.2 it does not require contact; use contactRequired=false on the 20,001+ tier."},"pricing":{"type":"object","properties":{"scheduleVersion":{"type":"string","example":"pricing-v1.2-2026-07-24"},"model":{"type":"string","example":"tiered"},"currency":{"type":"string","example":"EUR"},"thresholdScope":{"type":"string","enum":["combined","per_direction"],"example":"per_direction"},"marginalBandStartsAt":{"type":"integer","example":20001},"outboundTiers":{"type":"array","items":{"type":"object","properties":{"upTo":{"type":"integer","nullable":true},"rate":{"type":"number"},"label":{"type":"string"},"contactRequired":{"type":"boolean"}}}},"inboundApiTiers":{"type":"array","items":{"type":"object","properties":{"upTo":{"type":"integer","nullable":true},"rate":{"type":"number"},"label":{"type":"string"},"contactRequired":{"type":"boolean"}}}}}},"firms":{"type":"array","description":"Per-firm breakdown for the requested page (sorted by outboundCount desc).","items":{"type":"object","properties":{"firmId":{"type":"string"},"name":{"type":"string","nullable":true},"ico":{"type":"string","nullable":true},"managed":{"type":"boolean","description":"true → counts in `billable`; false → counts in `nonManaged`."},"outboundCount":{"type":"integer"},"inboundApiCount":{"type":"integer"}}}},"pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"}}}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing `account:read` scope or non-integrator key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Integrator not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:account","x-epostak-docs-anchor":"enterprise-getintegratorlicenseinfo"}},"/documents/send":{"post":{"tags":["Documents"],"summary":"Odoslat dokument cez Peppol","description":"Odosle fakturu cez Peppol siet. Podporuje dva rezimy:\n\n**JSON mode** — poskytnete strukturovane data (`items`) pre standardnu fakturu, UBL XML sa vygeneruje automaticky. Odosielatel sa berie z autentifikovanej firmy, nie z payloadu.\n\n**XML mode** — poskytnete hotove UBL XML (`xml`), odosle sa priamo.\n\nV oboch pripadoch je `receiverPeppolId` povinne.\n\n**Idempotency (always strict):** pass `Idempotency-Key: <any unique string>` (alias `X-Idempotency-Key`) to safely retry after network errors — the second completed call with the same body returns HTTP 200 with the current document status and `duplicate: true`, without creating or sending another document. If the same key is currently being processed, returns 409 CONFLICT. If the body SHA-256 differs from the stored hash, returns 422 IDEMPOTENCY_KEY_MISMATCH (body is canonicalized — keys sorted recursively — before hashing). There is no non-strict mode.\n\n**Cross-path dedup (XML mode):** if the same UBL XML SHA-256 was already accepted for this firm via dashboard mass-import, returns 200 with `{ data: { invoice_id, peppol_message_id, status, duplicate: true } }`.\n\n**Items[] max 999.** Unit codes use UN/ECE Rec 20 (C62, HUR, KGM, MTR, LTR, DAY, ...).\n\n**Attachments (BG-24):** up to 20 files, 10 MB per file, 15 MB total after base64 decode. MIME types enforced per BR-CL-22.\n\n**Required scope:** `documents:send`. Wildcard scopes (`*`, `full`, or empty `[]`) also satisfy this requirement.","operationId":"sendDocument","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"Client-supplied idempotency key (canonical RFC-draft header). If the same key was used recently with the same body, the prior response is replayed."},{"name":"X-Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"Alias for `Idempotency-Key`. Both headers are accepted."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SendDocumentJsonRequest"},{"$ref":"#/components/schemas/SendDocumentXmlRequest"}]},"examples":{"json_mode":{"summary":"Complete JSON invoice mode","value":{"receiverPeppolId":"0245:0000000001","receiverName":"Zakaznik Demo s.r.o.","receiverIco":"12345678","receiverDic":"0000000001","receiverIcDph":"SK0000000001","receiverStreet":"Testovacia 1","receiverCity":"Bratislava","receiverPostalCode":"811 01","receiverCountry":"SK","invoiceNumber":"FA-2026-001","issueDate":"2026-07-01","dueDate":"2026-07-15","currency":"EUR","paymentMethod":"bank_transfer","iban":"SK9811000000000000000001","variableSymbol":"2026001","buyerReference":"PO-2026-0001","note":"Services for June 2026. Attachment: signed acceptance protocol.","prepaidAmount":100,"items":[{"description":"Implementation services","quantity":16,"unit":"HUR","unitPrice":75,"vatRate":23,"vatCategoryCode":"S","discount":5,"deliveryDate":"2026-06-30"},{"description":"Support subscription","quantity":1,"unit":"C62","unitPrice":240,"vatRate":23,"vatCategoryCode":"S"}],"attachments":[{"fileName":"acceptance-protocol.pdf","mimeType":"application/pdf","content":"JVBERi0xLjQKJc...","description":"Signed acceptance protocol"}]}},"json_mode_with_attachments":{"summary":"JSON mode s prilohami (BG-24)","value":{"receiverPeppolId":"0245:12345678","receiverName":"Zakaznik s.r.o.","invoiceNumber":"FAK-2026-0001","items":[{"description":"Konzultacne sluzby","quantity":10,"unitPrice":50,"vatRate":23}],"attachments":[{"fileName":"invoice-detail.pdf","mimeType":"application/pdf","content":"JVBERi0xLjQKJeLjz9MKMS...","description":"Rozpis odpracovanych hodin"}]}},"xml_mode":{"summary":"XML mode for ready UBL, including self-billing","value":{"receiverPeppolId":"0245:0000000001","xml":"<?xml version=\"1.0\" encoding=\"UTF-8\"?><Invoice>...<cbc:InvoiceTypeCode>389</cbc:InvoiceTypeCode>...</Invoice>"}}}}}},"responses":{"200":{"description":"Idempotent replay; no new document or send was created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendDocumentResponse"}}}},"201":{"description":"Dokument uspesne odoslany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendDocumentResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"202":{"description":"Dokument bol dorucenny cez Peppol, ale zapis lokalneho stavu zlyhal. Reconcile cron stav doplni; idempotent retry vrati identicku odpoved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendDocumentResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"409":{"description":"Idempotency key in-flight — same X-Idempotency-Key is currently being processed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload too large (> 25 MB JSON mode, > 5 MB XML mode)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error. Two distinct failure shapes return 422 here: (a) UBL pre-flight rule violation — body matches UblValidationError with `code: \"UBL_VALIDATION_ERROR\"` and a `rule` field naming the violated BR-* / BT-* / PEPPOL-R* code; (b) IDEMPOTENCY_KEY_MISMATCH — same X-Idempotency-Key was replayed with a different request body hash, body matches the generic ErrorResponse.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/UblValidationError"},{"$ref":"#/components/schemas/ErrorResponse"}]}}}},"502":{"description":"SEND_FAILED — Peppol AP dispatch failed (retryable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"IDEMPOTENCY_STORE_UNAVAILABLE — Redis idempotency layer unreachable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":true,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-senddocument"}},"/documents/send/batch":{"post":{"tags":["Documents"],"summary":"Send up to 50 documents in one call","description":"Batch version of `/documents/send`. Each item is dispatched through the regular send pipeline and returns its own status + documentId (or per-item error). Partial success is expected — the HTTP status is 200 even if some items fail; inspect each result. Body size cap: 20 MB (use individual sends for larger batches).","operationId":"sendDocumentBatch","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchSendRequest"}}}},"responses":{"200":{"description":"Batch processed (partial-success semantics)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchSendResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"413":{"description":"Payload too large (> 20 MB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"UBL validation error (schematron rule failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UblValidationError"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-senddocumentbatch"}},"/documents/preflight":{"post":{"tags":["Documents"],"summary":"Pred-odosielacia validacia","description":"Enterprise reliability contract: capability -> preflight -> send -> events -> support. Dry-run send without creating a document or billing usage; run it after capability checks and before POST /documents/send. Read decision/canSend/errors/checks for the result, and retry the later send call with the same Idempotency-Key when it is the same payload.","operationId":"preflightDocument","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["receiverPeppolId"],"properties":{"receiverPeppolId":{"type":"string","example":"0245:12345678","description":"Peppol ID prijemcu"},"documentTypeId":{"type":"string","example":"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2","description":"Typ dokumentu (volitelne, default: Invoice)"}}}}}},"responses":{"200":{"description":"Vysledok preflight kontroly (tri-state booleans)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreflightResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"413":{"description":"Payload too large (> 6 MB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"UBL validation error (schematron rule failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UblValidationError"}}}},"503":{"description":"SMP lookup service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":true,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-preflightdocument"}},"/documents/inbox":{"get":{"tags":["Inbox"],"summary":"Zoznam prijatych fakturacnych dokumentov","description":"Vrati strankovany zoznam fakturacnych dokumentov prijatych cez Peppol pre vasu firmu. Pre plny Peppol scope vratane non-billing typov pouzite GET /api/v1/inbound/documents. Oba endpointy funguju pre api-enterprise priamo alebo pre integrator-managed firmu cez spravujuci sk_int_* integratorsky token.","operationId":"listInbox","parameters":[{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Pocet preskocenych zaznamov"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Pocet vratenych zaznamov"},{"name":"status","in":"query","schema":{"type":"string","enum":["RECEIVED","ACKNOWLEDGED","ACCEPTED","REJECTED","PAID","VALIDATION_FAILED","FAILED"]},"description":"Filter podla stavu dokumentu"},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Return only documents received after this ISO 8601 timestamp"},{"name":"peppolMessageId","in":"query","schema":{"type":"string","maxLength":100},"description":"Filter by Peppol message ID (exact match)"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from previous response's nextCursor. Stable pagination — preferred over offset for large result sets."}],"responses":{"200":{"description":"Zoznam prijatych dokumentov (response root key je `documents`, kazdy item je normalizovany InvoiceResponse so supplier/customer/totals nested objektami podla `formatInvoice()` v `lib/api/format.ts`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxListResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"422":{"description":"Invalid status or since parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:inbox","x-epostak-docs-anchor":"enterprise-listinbox"}},"/documents/inbox/{id}":{"get":{"tags":["Inbox"],"summary":"Detail prijateho dokumentu","description":"Vrati kompletne data prijateho dokumentu vratane UBL XML payloadu (ak je dostupny).","operationId":"getInboxDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"responses":{"200":{"description":"Detail dokumentu","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxDocumentDetailResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Dokument nepatri vasej firme","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Dokument nenajdeny alebo nie je inbound","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:inbox","x-epostak-docs-anchor":"enterprise-getinboxdocument"}},"/documents/inbox/{id}/acknowledge":{"post":{"tags":["Inbox"],"summary":"Potvrdit prijatie dokumentu","description":"Idempotentne zaznamena, ze prijimatelov ERP alebo iny klient spracoval inbound dokument. Ide o jeden spolocny lokalny stav firmy, nie o samostatne potvrdenie pre kazdy API kluc alebo konzumny system. Opakovane volanie vrati HTTP 200 s povodnym casom prveho potvrdenia a `idempotent=true`. Potvrdenie dokument nezmaze, nezablokuje jeho detail ani opatovne stiahnutie a neodosiela Peppol Invoice Response odosielatelovi.","operationId":"acknowledgeDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"responses":{"200":{"description":"Spracovanie zaznamenane alebo uz bolo zaznamenane","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcknowledgeResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Dokument nepatri vasej firme alebo API plan je vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Dokument nenajdeny alebo nie je inbound","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Dokument nie je v stave, ktory mozno lokalne potvrdit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:inbox","x-epostak-docs-anchor":"enterprise-acknowledgedocument"}},"/documents/inbox/all":{"get":{"tags":["Inbox"],"summary":"Cross-firm bulk inbox","description":"Returns received documents across all assigned firms. No X-Firm-Id header needed. Requires a JWT minted from an sk_int_* key.","operationId":"getCrossFirmInbox","security":[{"bearerAuth":[]}],"parameters":[{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Pagination offset"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Maximum number of documents to return (max 200)"},{"name":"status","in":"query","schema":{"type":"string","enum":["RECEIVED","ACKNOWLEDGED","ACCEPTED","REJECTED","PAID","VALIDATION_FAILED","FAILED"]},"description":"Filter by document status"},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Return only documents received after this ISO 8601 timestamp"},{"name":"firm_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by firm UUID"}],"responses":{"200":{"description":"List of received documents across all firms","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrossFirmInboxResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:inbox","x-epostak-docs-anchor":"enterprise-getcrossfirminbox"}},"/documents/outbox":{"get":{"tags":["Outbox"],"summary":"Zoznam odoslanych dokumentov","description":"Vrati strankovany zoznam dokumentov odoslanych cez Peppol pre vasu firmu.","operationId":"listOutbox","parameters":[{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Pocet preskocenych zaznamov"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Pocet vratenych zaznamov"},{"name":"status","in":"query","schema":{"type":"string","enum":["SENT","DELIVERED","FAILED","REJECTED","ACKNOWLEDGED","SENDING","SEND_FAILED","VALIDATION_FAILED","PAID","DRAFT","OVERDUE","ACCEPTED"]},"description":"Filter podla stavu dokumentu"},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Return only documents created after this ISO 8601 timestamp"},{"name":"peppolMessageId","in":"query","schema":{"type":"string","maxLength":100},"description":"Filter by Peppol message ID (exact match)"}],"responses":{"200":{"description":"Zoznam odoslanych dokumentov (response root key je `documents`, kazdy item je normalizovany InvoiceResponse so supplier/customer/totals nested objektami podla `formatInvoice()` v `lib/api/format.ts`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutboxListResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"422":{"description":"Invalid status, since or peppolMessageId parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:outbox","x-epostak-docs-anchor":"enterprise-listoutbox"}},"/documents/{id}":{"get":{"tags":["Documents"],"summary":"Detail dokumentu — invoice alebo non-billing Peppol doc","description":"Vráti dokument podľa ID. Najprv hľadá medzi invoices (BIS Billing); ak ho tam nenájde, hľadá medzi peppol_documents (non-billing T01/T16/T19/T76 atď.). Tenant-isolated cez firmId — dokumenty inej firmy nikdy nevráti.\n\n**Required scope:** `documents:read`.","operationId":"getDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu (invoice alebo peppol_document)"}],"responses":{"200":{"description":"Detail dokumentu — Invoice (BIS Billing) alebo PeppolDocument (non-billing) shape, podľa toho kam dokument patrí","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatný alebo chýbajúci JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Enterprise plán vyžadovaný","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Dokument nenájdený","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-getdocument"},"patch":{"tags":["Documents"],"summary":"Upraviť draft fakturu","description":"Aktualizuje draft fakturu pred odoslaním. Pracuje len s `status=draft` invoice rows — non-draft a non-invoice dokumenty vrátia 422. Telo je strict (neznáme polia odmietne). Polia, ktoré nie sú v tele, ostanú nezmenené.\n\n**Required scope:** `documents:write`.","operationId":"patchDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID draft faktury"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"invoiceNumber":{"type":"string","minLength":1},"issueDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"dueDate":{"type":"string","nullable":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"currency":{"type":"string","minLength":1},"note":{"type":"string","nullable":true},"iban":{"type":"string","nullable":true},"variableSymbol":{"type":"string","nullable":true},"buyerReference":{"type":"string","nullable":true},"receiverName":{"type":"string","minLength":1},"receiverIco":{"type":"string","nullable":true},"receiverDic":{"type":"string","nullable":true},"receiverIcDph":{"type":"string","nullable":true},"receiverAddress":{"type":"string","nullable":true},"receiverCountry":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true},"items":{"type":"array","minItems":1,"items":{"type":"object","required":["description","quantity","unitPrice","vatRate"],"properties":{"description":{"type":"string","minLength":1},"quantity":{"type":"number","minimum":0,"exclusiveMinimum":true},"unit":{"type":"string","default":"C62","description":"UN/ECE Rec 20"},"unitPrice":{"type":"number","minimum":0},"vatRate":{"type":"number","enum":[0,5,10,19,20,23],"description":"SK VAT rates from 2025 plus historical 20% for older correction documents"},"discount":{"type":"number","minimum":0,"maximum":100,"default":0}}}}}}}}},"responses":{"200":{"description":"Updated invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error or non-draft / non-invoice document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-patchdocument"}},"/documents/{id}/status":{"get":{"tags":["Documents"],"summary":"Stav dokumentu — uplny lifecycle","description":"Vrati aktualny stav dokumentu vratane kompletnej historie stavov.","operationId":"getDocumentStatus","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"responses":{"200":{"description":"Stav dokumentu","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentStatusResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Dokument nenajdeny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-getdocumentstatus"}},"/documents/status/batch":{"post":{"tags":["Documents"],"summary":"Hromadný status check (až 100 dokumentov)","description":"Vráti stav až 100 dokumentov v jednom volaní. Výsledky sú v rovnakom poradí ako vstupné `ids`. Dokumenty, ktoré nepatria volajúcej firme alebo neexistujú, sú v odpovedi označené `{ \"error\": \"not_found\" }` — endpoint nikdy nevráti 404 pre celé volanie ani neprezradí existenciu dokumentov inej firmy.\n\n**Rate limit:** 300 req/min na API kľúč (až 30 000 stavov za minútu). Pre jednotlivé dokumenty použite `GET /documents/{id}/status` (limit 400 req/min).\n\n**Telo cap:** 64 KB.\n\n**Required scope:** `documents:read`.","operationId":"batchDocumentStatus","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1},"description":"Pole 1-100 document IDs. Duplicity sú deduplikované pred query, ale poradie volajúceho je zachované v results."}}}}}},"responses":{"200":{"description":"Per-item statuses v poradí volajúcich `ids`","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer","example":42},"found":{"type":"integer","example":38,"description":"Count of items in results that are NOT marked {error: not_found}."},"notFound":{"type":"integer","example":4},"results":{"type":"array","items":{"oneOf":[{"type":"object","required":["id","status","statusHistory","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"status":{"type":"string"},"documentType":{"type":"string","nullable":true},"direction":{"type":"string","enum":["inbound","outbound"],"description":"`inbound` = my sme prijímateľ. `outbound` = my sme odosielateľ. Sémantika `deliveredAt`/`acknowledgedAt` závisí od smeru — pozri DocumentStatusResponse popis."},"senderPeppolId":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true},"statusHistory":{"type":"array","items":{"type":"object"}},"validationResult":{"type":"object","nullable":true},"deliveredAt":{"type":"string","format":"date-time","nullable":true},"acknowledgedAt":{"type":"string","format":"date-time","nullable":true},"invoiceResponseStatus":{"type":"string","nullable":true},"peppolMessageId":{"type":"string","nullable":true,"description":"Alias k `as4MessageId` (rovnaká hodnota)."},"as4MessageId":{"type":"string","nullable":true,"description":"Alias k `peppolMessageId` (rovnaká hodnota)."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},{"type":"object","required":["id","error"],"properties":{"id":{"type":"string"},"error":{"type":"string","enum":["not_found"]}}}]}}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Invalid request — empty ids[], > 100, non-string elements","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Body exceeds 64 KB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-batchdocumentstatus"}},"/documents/{id}/events":{"get":{"tags":["Documents"],"summary":"Document timeline — AS4/Peppol/lifecycle events","description":"Paginated, reverse-chronological timeline for a single document: creation, validation, AS4 send/receipt, MLR, invoice response, FS SR reporting, user actions. Synthesized from invoice fields when `document_events` has no rows yet, real DB rows once events are emitted.","operationId":"listDocumentEvents","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from previous response"}],"responses":{"200":{"description":"Event list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentEventsResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-listdocumentevents"}},"/documents/{id}/mark":{"post":{"tags":["Documents"],"summary":"Report downstream state (delivered/processed/failed/read)","description":"Granular state-transition endpoint for integrators running their own processing pipeline. Report when the external channel confirmed delivery, the ERP consumed the document, the user opened it, or delivery terminally failed. Keeps status/events/reporting accurate.","operationId":"markDocumentState","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkRequest"}}}},"responses":{"200":{"description":"State updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid state value","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-markdocumentstate"}},"/documents/{id}/pdf":{"get":{"tags":["Documents"],"summary":"Stiahnut PDF dokumentu","description":"Vrati PDF verziu faktury ako binarny subor.","operationId":"getDocumentPdf","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"responses":{"200":{"description":"PDF subor","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Dokument nenajdeny alebo PDF nie je dostupne","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-getdocumentpdf"}},"/documents/{id}/ubl":{"get":{"tags":["Documents"],"summary":"Stiahnut UBL XML dokumentu","description":"Vrati UBL XML reprezentaciu dokumentu.","operationId":"getDocumentUbl","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"responses":{"200":{"description":"UBL XML subor","content":{"application/xml":{"schema":{"type":"string","format":"binary"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Dokument nenajdeny alebo UBL nie je dostupne","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-getdocumentubl"}},"/documents/{id}/evidence":{"get":{"tags":["Documents"],"summary":"Dokazy o doruceni dokumentu","description":"Vrati AS4 receipt, Message Level Response (MLR) a invoice response pre odoslany dokument.","operationId":"getDocumentEvidence","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"responses":{"200":{"description":"Dokazy o doruceni","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentEvidenceResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Dokument nenajdeny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-getdocumentevidence"}},"/documents/{id}/envelope":{"get":{"tags":["Documents"],"summary":"Download signed AS4 envelope","description":"Streams the raw multipart AS4 envelope for this document from the Enterprise API evidence archive exactly as it was transmitted on the Peppol network — signed, timestamped, tamper-evident. The archive is available during the active contract term and for 30 days after termination for export; it is not a standalone accounting archive outside the contract. Response headers include `X-Envelope-Archived-At` (ISO 8601) and `X-Envelope-Direction` (inbound|outbound).\n\nArchive cron runs on a short interval, so brand-new documents may briefly 404 until archived.\n\n**Requires an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"getDocumentEnvelope","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"responses":{"200":{"description":"Signed AS4 envelope","headers":{"Content-Disposition":{"schema":{"type":"string","example":"attachment; filename=\"<id>.as4\""}},"X-Envelope-Archived-At":{"schema":{"type":"string","format":"date-time"},"description":"When the envelope was written to the WORM archive"},"X-Envelope-Direction":{"schema":{"type":"string","enum":["inbound","outbound"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/related":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found OR envelope not yet archived","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-getdocumentenvelope"}},"/documents/{id}/responses":{"get":{"tags":["Documents"],"summary":"Zoznam invoice responses dokumentu","description":"Vrati zoznam invoice responses (AP/RE/UQ) pre odoslany dokument.","operationId":"listDocumentResponses","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"responses":{"200":{"description":"Zoznam invoice responses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponsesListResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Dokument nenajdeny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-listdocumentresponses"}},"/documents/{id}/respond":{"post":{"tags":["Documents"],"summary":"Odoslat invoice response","description":"Odosle invoice response (UBL ApplicationResponse) pre prijaty dokument. Podporuje 7 stavov: AB, IP, UQ, CA, RE, AP, PD.\n\nReturns HTTP 200 when AS4 dispatch succeeded, 202 when the response was persisted but dispatch failed (will retry async — inspect `dispatchError`).","operationId":"respondToDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID dokumentu"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceRespondRequest"},"example":{"status":"AP","note":"Faktura akceptovana"}}}},"responses":{"200":{"description":"Invoice response dispatched successfully via AS4","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceRespondResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"202":{"description":"Response persisted; AS4 dispatch failed and will be retried (inspect `dispatchError`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceRespondResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Dokument nenajdeny alebo nie je inbound","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"UBL validation error (schematron rule failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UblValidationError"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-respondtodocument"}},"/peppol-documents":{"get":{"tags":["Documents"],"summary":"List non-billing Peppol documents","description":"List endpoint for non-billing Peppol doctypes (Order, OrderResponse, DespatchAdvice, Catalogue, CatalogueResponse, OrderAgreement, AdvancedOrdering family, PunchOut). Lives in its own `peppol_documents` table to avoid changing the `/documents/inbox`/`/documents/outbox` Invoice-shaped contract.\n\n**Requires `documents:read` scope and an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"listPeppolDocuments","parameters":[{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"doctypeKey","in":"query","schema":{"type":"string"},"description":"Specific non-billing doctype key (see registry)"},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"peppolMessageId","in":"query","schema":{"type":"string"}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Non-billing Peppol documents","content":{"application/json":{"schema":{"type":"object","properties":{"documents":{"type":"array","items":{"type":"object","properties":{"document_id":{"type":"string"},"doctype_key":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"status":{"type":"string"},"sender_peppol_id":{"type":"string","nullable":true},"receiver_peppol_id":{"type":"string","nullable":true},"sender_name":{"type":"string","nullable":true},"receiver_name":{"type":"string","nullable":true},"document_type_id":{"type":"string","nullable":true},"process_id":{"type":"string","nullable":true},"peppol_message_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan does not allow this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:documents","x-epostak-docs-anchor":"enterprise-listpeppoldocuments"}},"/webhooks":{"post":{"tags":["Webhooks"],"summary":"Vytvorit webhook","description":"Zaregistruje novu webhook URL alebo pull-only subscription pre vybrane udalosti. Subscription je forward-only: zaradia sa iba udalosti vytvorene po jej aktivacii; historicke sender-side ani receiver-side udalosti sa spatne nedoplnaju. Push URL musi byt HTTPS a nesmie byt localhost ani privatna siet (SSRF ochrana). Max 10 subscriptions per firma.\n\n**Vyzaduje API pristup: `api-enterprise` priamo alebo `integrator-managed` cez spravujuceho integratora.**\n\nPodporovane udalosti (7): `document.created`, `document.sent`, `document.received`, `document.validated`, `document.delivered`, `document.rejected`, `document.response_received`.","operationId":"createWebhook","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"},"example":{"url":"https://vas-system.sk/webhooks/epostak","events":["document.received","document.sent"]}}}},"responses":{"201":{"description":"Webhook vytvoreny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDetailResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Neplatna URL alebo udalosti","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan je vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-createwebhook"},"get":{"tags":["Webhooks"],"summary":"Zoznam webhookov","description":"Vrati vsetky webhook odoberania pre vasu firmu.\n\n**Vyzaduje API pristup: `api-enterprise` priamo alebo `integrator-managed` cez spravujuceho integratora.**","operationId":"listWebhooks","responses":{"200":{"description":"Zoznam webhookov","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan je vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-listwebhooks"}},"/webhooks/{id}":{"get":{"tags":["Webhooks"],"summary":"Detail webhooku","description":"Vrati detaily webhooku vratane poslednych 20 doruceni.\n\n**Vyzaduje API pristup: `api-enterprise` priamo alebo `integrator-managed` cez spravujuceho integratora.**","operationId":"getWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID webhooku"}],"responses":{"200":{"description":"Detail webhooku","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookWithDeliveriesResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook nenajdeny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-getwebhook"},"patch":{"tags":["Webhooks"],"summary":"Upravit webhook","description":"Aktualizuje URL, zoznam udalosti alebo aktivny stav webhooku. Vsetky polia su volitelne.\n\n**Vyzaduje API pristup: `api-enterprise` priamo alebo `integrator-managed` cez spravujuceho integratora.**","operationId":"updateWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID webhooku"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookRequest"}}}},"responses":{"200":{"description":"Webhook aktualizovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Neplatna URL alebo udalosti","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty alebo API plan vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook nenajdeny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-updatewebhook"},"delete":{"tags":["Webhooks"],"summary":"Zmazat webhook","description":"Trvalo zmaze webhook.\n\n**Vyzaduje API pristup: `api-enterprise` priamo alebo `integrator-managed` cez spravujuceho integratora.**","operationId":"deleteWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID webhooku"}],"responses":{"204":{"description":"Webhook zmazany (prazdne telo odpovede)","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty alebo API plan vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook nenajdeny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-deletewebhook"}},"/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"summary":"Send a synthetic test delivery","description":"Dispatches one or more synthetic test payloads to the webhook URL with fresh HMAC signatures. Returns HTTP 200 with a result envelope regardless of whether delivery succeeded — inspect `success`, `succeeded`, `failed`, and `statusCodes`. One aggregate `webhook_deliveries` row is written so the test run appears in `/webhooks/{id}/deliveries`.\n\n**Requires an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"testWebhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID"},{"name":"event","in":"query","required":false,"schema":{"type":"string","enum":["document.sent","document.received","document.delivered","document.delivery_failed","document.rejected","document.response_received"]},"description":"Event type to simulate. Takes precedence over the request body field. Default: document.sent"},{"name":"count","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":30000,"default":1},"description":"Number of synthetic webhook POSTs to send in one test run. Takes precedence over the request body field."}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","enum":["document.sent","document.received","document.delivered","document.delivery_failed","document.rejected","document.response_received"],"description":"Event to simulate (default: document.sent)"},"count":{"type":"integer","minimum":1,"maximum":30000,"default":1,"description":"Number of synthetic webhook POSTs to send in one test run."}}}}}},"responses":{"200":{"description":"Test dispatched (check `success` for delivery outcome)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid event type supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-testwebhook"}},"/webhooks/{id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"Paginated delivery history","description":"Returns the full delivery log for a webhook (test deliveries included). Supports status + event filters.\n\n**`responseBody` is omitted by default** because a legitimate webhook receiver may echo sensitive content (PII, tokens) in its 4xx/5xx body. Pass `?includeResponseBody=true` (or `?include=responseBody`) to opt in. The first 200 chars are stored at delivery time — older deliveries written before this cap shipped may be longer.\n\n**Requires an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"listWebhookDeliveries","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","schema":{"type":"string","enum":["PENDING","SUCCESS","FAILED","RETRYING"]},"description":"Filter by delivery status (UPPERCASE enum)"},{"name":"event","in":"query","schema":{"type":"string"},"description":"Filter by event name"},{"name":"includeResponseBody","in":"query","schema":{"type":"boolean","default":false},"description":"Set to `true` to include the (truncated, 200-char) `responseBody` field on each delivery. Default `false` to avoid leaking content from receivers that echo sensitive data."},{"name":"include","in":"query","schema":{"type":"string","enum":["responseBody"]},"description":"Alternative spelling: `?include=responseBody` is equivalent to `?includeResponseBody=true`."}],"responses":{"200":{"description":"Delivery list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveriesResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-listwebhookdeliveries"}},"/webhook-dead-letter":{"get":{"tags":["Webhooks"],"summary":"Webhook dead-letter queue","description":"Returns unresolved terminally failed push deliveries across your firm's webhooks. Use it for ERP runbooks: what needs replay or manual resolution.","operationId":"listWebhookDeadLetters","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"event","in":"query","schema":{"type":"string"},"description":"Filter by event name"},{"name":"subscriptionId","in":"query","schema":{"type":"string"},"description":"Filter to one webhook subscription"},{"name":"includeResponseBody","in":"query","schema":{"type":"boolean","default":false},"description":"Set to true to include the last ERP endpoint response body."}],"responses":{"200":{"description":"Dead-letter delivery list","content":{"application/json":{"schema":{"type":"object","required":["items","total","limit","offset"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryDetail"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-listwebhookdeadletters"}},"/webhook-dead-letter/{deliveryId}/replay":{"post":{"tags":["Webhooks"],"summary":"Replay failed webhook delivery","description":"Creates a new PENDING delivery from the original FAILED row and enqueues it. The original row remains in audit history and is marked resolved by replay. webhook_event_id stays stable; webhook_id is a new per-delivery identifier.","operationId":"replayWebhookDeadLetter","parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Delivery ID from GET /webhook-dead-letter"}],"responses":{"202":{"description":"Replay accepted","content":{"application/json":{"schema":{"type":"object","required":["replayedFrom","deliveryId","webhookId","webhookEventId"],"properties":{"replayedFrom":{"type":"string","format":"uuid"},"deliveryId":{"type":"string","format":"uuid"},"webhookId":{"type":"string"},"webhookEventId":{"type":"string","format":"uuid"}}}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Dead-letter delivery not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Delivery cannot be replayed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-replaywebhookdeadletter"}},"/webhook-dead-letter/{deliveryId}/resolve":{"post":{"tags":["Webhooks"],"summary":"Resolve webhook failure","description":"Hides a failed delivery from the dead-letter queue without deleting or overwriting audit history. Use when the state was handled manually in the ERP or replay is no longer needed.","operationId":"resolveWebhookDeadLetter","parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Delivery ID from GET /webhook-dead-letter"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Resolved","content":{"application/json":{"schema":{"type":"object","required":["resolved"],"properties":{"resolved":{"type":"boolean"}}}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Dead-letter delivery not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-resolvewebhookdeadletter"}},"/webhooks/{id}/rotate-secret":{"post":{"tags":["Webhooks"],"summary":"Rotate HMAC signing secret","description":"Generates a new 64-char hex secret and immediately discards the old one. In-flight deliveries signed with the old secret will fail signature verification at the receiver. Returns the new secret ONCE.","operationId":"rotateWebhookSecret","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID"}],"responses":{"200":{"description":"Secret rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRotateSecretResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access denied or API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-rotatewebhooksecret"}},"/webhook-queue/all":{"get":{"tags":["Webhooks"],"summary":"Cross-firm webhook queue poll","description":"Poll pending webhook events across all assigned firms. No X-Firm-Id header needed. Requires a JWT minted from an sk_int_* key.","operationId":"getCrossFirmWebhookQueue","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"description":"Maximum number of events to return (max 500)"},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Return only events created after this ISO 8601 timestamp"}],"responses":{"200":{"description":"Pending webhook events across all firms","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrossFirmWebhookQueueResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-getcrossfirmwebhookqueue"}},"/webhook-queue/all/batch-ack":{"post":{"tags":["Webhooks"],"summary":"Cross-firm batch acknowledge webhook events","description":"Acknowledge multiple webhook events across all firms in a single request. Maximum 1000 event IDs.","operationId":"batchAckCrossFirmWebhookEvents","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAckWebhookRequest"},"example":{"event_ids":["uuid-1","uuid-2"]}}}},"responses":{"200":{"description":"Number of events acknowledged","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAckWebhookResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks","x-epostak-docs-anchor":"enterprise-batchackcrossfirmwebhookevents"}},"/peppol/participants/{scheme}/{identifier}":{"get":{"tags":["Peppol"],"summary":"SMP lookup ucastnika","description":"Vyhlada Peppol ucastnika v SMP (Service Metadata Publisher) podla scheme a identifikatora.","operationId":"smpLookup","parameters":[{"name":"scheme","in":"path","required":true,"schema":{"type":"string","example":"0245"},"description":"ICD scheme kod (napr. 0245 pre slovenske ICO)"},{"name":"identifier","in":"path","required":true,"schema":{"type":"string","example":"12345678"},"description":"Identifikator v danej scheme"}],"responses":{"200":{"description":"Ucastnik najdeny","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmpLookupResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Ucastnik nie je registrovany v Peppol sieti","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:peppol","x-epostak-docs-anchor":"enterprise-smplookup"}},"/peppol/participants/batch":{"post":{"tags":["Peppol"],"summary":"Bulk participant existence + capability lookup","description":"Pre-check a list of recipients before fan-out send. Max 100 per batch. Individual results are cached so repeat queries are cheap.","operationId":"peppolParticipantsBatch","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantsBatchRequest"}}}},"responses":{"200":{"description":"Batch results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantsBatchResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"422":{"description":"participants[] missing/empty or > 100","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:peppol","x-epostak-docs-anchor":"enterprise-peppolparticipantsbatch"}},"/peppol/participants/resolve":{"get":{"tags":["Peppol"],"summary":"Resolve company to Peppol participant","description":"One-step lookup for ERP integrations: pass exactly one identifier (`ico`, `dic`, `icDph`, `peppolId`, or `scheme` + `identifier`). The endpoint enriches Slovak company data when available and checks the exact Peppol routing capability for `documentTypeId` + `processId`. Use this before preflight/send when the ERP knows IČO or DIČ, not the final Peppol ID.","operationId":"resolvePeppolParticipant","parameters":[{"name":"ico","in":"query","required":false,"schema":{"type":"string"},"description":"Slovak IČO, 6-8 digits. Mutually exclusive with other identifiers."},{"name":"dic","in":"query","required":false,"schema":{"type":"string"},"description":"Slovak DIČ, 10 digits. Mutually exclusive with other identifiers."},{"name":"icDph","in":"query","required":false,"schema":{"type":"string"},"description":"VAT ID, e.g. SK2020123456. Mutually exclusive with other identifiers."},{"name":"peppolId","in":"query","required":false,"schema":{"type":"string","example":"0245:2020123456"},"description":"Direct Peppol participant ID."},{"name":"scheme","in":"query","required":false,"schema":{"type":"string","example":"0245"},"description":"ISO 6523 scheme when using scheme+identifier."},{"name":"identifier","in":"query","required":false,"schema":{"type":"string","example":"2020123456"},"description":"Participant identifier when using scheme+identifier."},{"name":"documentTypeId","in":"query","required":false,"schema":{"type":"string"},"description":"Peppol document type URN. Defaults to BIS Billing 3.0 Invoice."},{"name":"processId","in":"query","required":false,"schema":{"type":"string"},"description":"Peppol process ID. Defaults to BIS Billing 3.0."}],"responses":{"200":{"description":"Company and Peppol routing capability","content":{"application/json":{"schema":{"type":"object"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Invalid or ambiguous query","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Company or participant candidate not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:peppol","x-epostak-docs-anchor":"enterprise-resolvepeppolparticipant"}},"/peppol/capabilities":{"post":{"tags":["Peppol"],"summary":"Capability probe — does receiver accept this doctype?","description":"Storecove-style `discovery/receives`: given a participant + optional candidate document type + process id, answer whether the receiver accepts it. Enterprise reliability contract starts here: before building the payload, read `networkReady` and `matchedDocumentTypes`, then continue capability -> preflight -> send -> events -> support.\n\nWhen `documentType` or `processId` are omitted, the endpoint defaults to BIS Billing 3.0 Invoice over the BIS Billing process. Response `matchedDocumentType` is the probed document type when accepted, otherwise `null`. Send `documentTypes[]` to check 1-20 document type URNs in one request; the response includes `capabilities[]` and `matchedDocumentTypes[]`.","operationId":"peppolCapabilities","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapabilitiesRequest"}}}},"responses":{"200":{"description":"Lookup result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapabilitiesResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Participant not registered in Peppol network","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapabilitiesResponse"}}}},"422":{"description":"Invalid scheme/identifier format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:peppol","x-epostak-docs-anchor":"enterprise-peppolcapabilities"}},"/peppol/directory/search":{"get":{"tags":["Peppol"],"summary":"Prehladavat Peppol directory","description":"Prehladava Peppol Business Card directory podla nazvu firmy, krajiny a inych kriterii.","operationId":"peppolDirectorySearch","parameters":[{"name":"q","in":"query","schema":{"type":"string","example":"Moja firma"},"description":"Vyhladavaci vyraz (nazov firmy, ICO)"},{"name":"country","in":"query","schema":{"type":"string","example":"SK"},"description":"Filtrovanie podla kodu krajiny (ISO 3166-1 alpha-2)"},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1},"description":"Cislo strany"},{"name":"page_size","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Pocet vysledkov na stranu"}],"responses":{"200":{"description":"Vysledky vyhladavania","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolDirectorySearchResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Neplatne parametre","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:peppol","x-epostak-docs-anchor":"enterprise-peppoldirectorysearch"}},"/company/lookup/{ico}":{"get":{"tags":["Peppol"],"summary":"Vyhladanie firmy podla ICO","description":"Vyhlada verejne informacie o firme podla ICO (slovensky obchodny register).","operationId":"companyLookup","parameters":[{"name":"ico","in":"path","required":true,"schema":{"type":"string","example":"12345678"},"description":"ICO firmy (8 cislic)"}],"responses":{"200":{"description":"Informacie o firme","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyLookupResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Firma s danym ICO nenajdena","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:peppol","x-epostak-docs-anchor":"enterprise-companylookup"}},"/customers":{"get":{"tags":["Firms"],"summary":"List White Label customers","description":"Lists customer companies managed by the authenticated White Label integrator. Requires a JWT minted from an active `sk_int_*` key with `firms:manage`, an active White Label entitlement, and Enterprise API production authorization. This is a cross-firm operation: do not send `X-Firm-Id`.","operationId":"listWhiteLabelCustomers","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["firms:manage"],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["action_required","activating","active","suspended","blocked"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Visible White Label customers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelCustomerListResponse"}}}},"400":{"description":"Invalid query","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid integrator JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label, Enterprise API, or required scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Managed customer account is not ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-listwhitelabelcustomers"},"post":{"tags":["Firms"],"summary":"Create an accountless managed API customer","description":"Creates or idempotently returns a represented Enterprise API customer from an independently collected, auditable customer mandate. This endpoint does not register a Peppol participant and does not consume the FS SR verification_token. For White Label Peppol onboarding, call POST /white-label/participants/registrations separately. Requires a JWT minted from an active sk_int_* key with firms:manage, an active White Label entitlement, and Enterprise API production authorization. Do not send X-Firm-Id; use the returned firmId as X-Firm-Id on subsequent firm-scoped Enterprise API calls.","operationId":"createWhiteLabelCustomer","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["firms:manage"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Recommended retry key. Reusing the same customerRef with identical data is also idempotent.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelCustomerCreateRequest"},"example":{"customerRef":"klient-001","relationship":"represented","country":"SK","companyId":"12345678","taxId":"2020123456","contactEmail":"konatel@example.sk","customerAuthorization":{"confirmed":true,"evidenceReference":"ZMLUVA-2026-001"}}}}},"responses":{"200":{"description":"Idempotent replay of an existing customer","headers":{"Idempotent-Replay":{"description":"Set to true when the response is a replay","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelCustomer"}}}},"201":{"description":"Customer created and verified","headers":{"ETag":{"description":"Resource version ETag","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelCustomer"}}}},"400":{"description":"Invalid JSON or customer authorization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid integrator JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label, Enterprise API, or required scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflicting customer reference, idempotency key, or account state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request exceeds 32 KiB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Content-Type is not application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Registry validation or customer identity failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Company registry is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":true,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-createwhitelabelcustomer"}},"/white-label/participants":{"get":{"tags":["White Label"],"summary":"List managed White Label participants","description":"Lists only participants currently bound to the authenticated White Label integrator. Requires an active White Label production entitlement and an integrator JWT with participants:read. Do not send X-Firm-Id.","operationId":"listWhiteLabelParticipants","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["participants:read"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Visible managed participants","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantList"}}}},"400":{"description":"Invalid cursor or limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid integrator JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label entitlement or scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:white-label","x-epostak-docs-anchor":"enterprise-listwhitelabelparticipants"}},"/white-label/participants/registrations":{"post":{"tags":["White Label"],"summary":"Register a participant from an FS SR provider webhook","description":"Creates an accountless White Label participant from the verification_token delivered to the intermediary's signed FS SR provider webhook. ePošťák passes the token to SMP as dic_verification_code and stores only a domain-separated keyed HMAC digest. A local firm and tenant binding are committed only after SMP confirms success. An SMP 409 never proves ownership and never reuses the existing participant. Do not send X-Firm-Id.","operationId":"registerWhiteLabelParticipant","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["participants:write"],"parameters":[{"$ref":"#/components/parameters/WhiteLabelIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantRegistrationRequest"},"example":{"customerRef":"klient-001","dic":"2020123456","companyEmail":"fakturacia@klient.sk","verificationToken":"token-received-from-fs-webhook"}}}},"responses":{"200":{"description":"Idempotent replay of a completed operation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"}}}},"201":{"description":"SMP registration and local binding succeeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"}}}},"202":{"description":"Poll the Location operation URL and do not retry with a new key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"}}}},"400":{"description":"Invalid request or missing Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid integrator JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label entitlement or scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Participant, authorization, idempotency, or tenant conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Company verification or SMP authorization was rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":true,"x-epostak-owner":"enterprise:white-label","x-epostak-docs-anchor":"enterprise-registerwhitelabelparticipant"}},"/white-label/participants/migrations":{"post":{"tags":["White Label"],"summary":"Migrate a participant into the White Label tenant","description":"Uses an SMP migration code to take over an existing participant. The code is sent only to SMP and stored only as a digest. A local tenant binding is created only after SMP confirms the migration. Do not send X-Firm-Id.","operationId":"migrateWhiteLabelParticipantIn","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["participants:migrate"],"parameters":[{"$ref":"#/components/parameters/WhiteLabelIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantMigrationRequest"},"example":{"customerRef":"klient-001","dic":"2020123456","companyEmail":"fakturacia@klient.sk","migrationCode":"migration-code-from-current-provider"}}}},"responses":{"200":{"description":"Idempotent replay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"}}}},"201":{"description":"Migration and local binding succeeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"}}}},"202":{"description":"Result requires polling or manual review","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label entitlement or scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Participant, tenant, idempotency, or migration state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Migration code or company verification was rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:white-label","x-epostak-docs-anchor":"enterprise-migratewhitelabelparticipantin"}},"/white-label/participants/{participantId}":{"get":{"tags":["White Label"],"summary":"Get one managed White Label participant","description":"Returns a participant only when it belongs to the authenticated White Label tenant.","operationId":"getWhiteLabelParticipant","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["participants:read"],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Managed participant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipant"}}}},"401":{"description":"Missing or invalid JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label entitlement or scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Participant is absent or belongs to another tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:white-label","x-epostak-docs-anchor":"enterprise-getwhitelabelparticipant"}},"/white-label/participants/{participantId}/migration-code":{"post":{"tags":["White Label"],"summary":"Request an outgoing SMP migration code","description":"Requests a migration code only for a participant currently managed by the authenticated White Label tenant. The returned code is never stored in readable form. Requesting a code does not itself release ownership; release completes only after SMP confirms transfer.","operationId":"requestWhiteLabelParticipantMigrationCode","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["participants:migrate"],"parameters":[{"name":"participantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/WhiteLabelIdempotencyKey"}],"responses":{"200":{"description":"Idempotent replay while the code remains available from SMP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelMigrationCodeResponse"}}}},"201":{"description":"Migration code requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelMigrationCodeResponse"}}}},"202":{"description":"SMP result requires manual review","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelMigrationCodeResponse"}}}},"401":{"description":"Missing or invalid JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label entitlement or scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Participant is absent or belongs to another tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Migration code is unavailable or the idempotency key conflicts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:white-label","x-epostak-docs-anchor":"enterprise-requestwhitelabelparticipantmigrationcode"}},"/white-label/operations/{operationId}":{"get":{"tags":["White Label"],"summary":"Get White Label participant operation status","description":"Returns only operations owned by the authenticated White Label tenant. Poll the Location URL returned by 202 responses.","operationId":"getWhiteLabelParticipantOperation","security":[{"integratorBearerAuth":[]}],"x-epostak-required-scopes":["participants:read"],"parameters":[{"name":"operationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Operation status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"}}}},"401":{"description":"Missing or invalid JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"White Label entitlement or scope is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Operation is absent or belongs to another tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["integrator-bearer"],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:white-label","x-epostak-docs-anchor":"enterprise-getwhitelabelparticipantoperation"}},"/firms":{"get":{"tags":["Firms"],"summary":"Zoznam pristupnych firiem","description":"Vrati zoznam firiem, ku ktorym ma API kluc pristup. Relevantne pre multi-tenant API kluce.","operationId":"listFirms","responses":{"200":{"description":"Zoznam firiem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirmsListResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-listfirms"}},"/firms/consent-link":{"post":{"tags":["Firms"],"summary":"Create a one-time firm consent link","description":"Creates a new one-time owner/admin consent URL bound to exactly one Slovak DIC or ICO. The invitation authorizes Enterprise API, so the requested scopes must include firms:manage and at least one documents:* scope. The API never grants consent on the firm's behalf: an owner or admin of the target firm must sign in and accept the exact scopes. Every successful request creates a fresh URL that is returned once. Requires a JWT minted from an active sk_int_* key with firms:manage. No X-Firm-Id header needed.","operationId":"createFirmConsentLink","security":[{"bearerAuth":[]}],"x-epostak-required-scopes":["firms:manage"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["scopes"],"oneOf":[{"required":["dic"],"not":{"required":["ico"]}},{"required":["ico"],"not":{"required":["dic"]}}],"properties":{"dic":{"type":"string","pattern":"^\\d{10}$","description":"Slovak DIC (10 digits). Provide exactly one of dic or ico."},"ico":{"type":"string","pattern":"^\\d{8}$","description":"Slovak ICO (8 digits). Provide exactly one of dic or ico."},"customer_reference":{"type":"string","maxLength":120,"nullable":true,"description":"Optional integrator-side customer reference."},"scopes":{"type":"array","minItems":2,"maxItems":9,"uniqueItems":true,"description":"Exact owner/admin consent scopes. Must include firms:manage and at least one documents:* scope.","items":{"type":"string","enum":["firms:manage","documents:send","documents:read","documents:write","events:read","webhooks:read","webhooks:write","evidence:read","account:read"]}}}},"example":{"dic":"2022988022","customer_reference":"BUGLO-001","scopes":["firms:manage","documents:send","documents:read"]}}}},"responses":{"201":{"description":"A fresh one-time consent URL was created","headers":{"Cache-Control":{"description":"The one-time URL response must not be cached.","schema":{"type":"string","example":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","required":["id","consent_url","customer_reference","integration_path","requested_interfaces","scopes","status","expires_at","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"consent_url":{"type":"string","format":"uri","description":"One-time owner/admin consent URL. Returned only on this response."},"customer_reference":{"type":"string","nullable":true},"integration_path":{"type":"string","enum":["enterprise_api"]},"requested_interfaces":{"type":"array","items":{"type":"string","enum":["enterprise_api"]}},"scopes":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["issued"]},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"example":{"id":"49702ea6-41bf-47ef-9cb6-657450fdb299","consent_url":"https://epostak.sk/auth/integrator-consent?token=...","customer_reference":"BUGLO-001","integration_path":"enterprise_api","requested_interfaces":["enterprise_api"],"scopes":["documents:read","documents:send","firms:manage"],"status":"issued","expires_at":"2026-08-18T10:00:00.000Z","created_at":"2026-08-11T10:00:00.000Z"}}}},"400":{"description":"Invalid JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing integrator token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing firms:manage scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"409":{"description":"The integrator agreement, entitlement, billing, or Enterprise API authorization is not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body is too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Provide exactly one valid firm identifier and scopes containing firms:manage plus a documents:* scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Consent-link creation is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-createfirmconsentlink"}},"/firms/consent-status":{"get":{"tags":["Firms"],"summary":"Get firm consent status","description":"Read-only check of a firm's integrator-consent state by DIC or ICO. The endpoint returns active only when the active, unrevoked link authorizes the current Enterprise API through a valid relationship and includes firms:manage. A mismatched link is returned as required with next_action=request_integrator_reconsent, a reason, and the required interface; the endpoint never rewrites the link. Completed owner OAuth in the dev sandbox does not override an interface mismatch. Requires a JWT minted from an sk_int_* key with the firms:manage scope. No X-Firm-Id header needed.","operationId":"getFirmConsentStatus","security":[{"bearerAuth":[]}],"parameters":[{"name":"dic","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{10}$"},"description":"DIC firmy (10 cislic), preferovane"},{"name":"ico","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{8}$"},"description":"ICO firmy (8 cislic), fallback"}],"responses":{"200":{"description":"Firm consent status","content":{"application/json":{"schema":{"type":"object","required":["identifier","firm","consent_status","assign_status","next_action"],"properties":{"identifier":{"type":"object","properties":{"dic":{"type":"string","example":"2122701339"},"ico":{"type":"string","example":"52345678"}},"description":"Identifier used for lookup; contains either dic or ico."},"firm":{"type":"object","required":["id","name","ico","dic","peppol_id","peppol_status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"ico":{"type":"string","nullable":true},"dic":{"type":"string","nullable":true},"peppol_id":{"type":"string","nullable":true},"peppol_status":{"type":"string","nullable":true}}},"consent_status":{"type":"string","enum":["active","pending","revoked","required"]},"assign_status":{"type":"string","enum":["already_assigned","consent_required","consent_revoked"]},"next_action":{"type":"string","enum":["use_firm_id","await_consent_acceptance","request_integrator_consent","request_integrator_reconsent","start_oauth_consent"]},"reason":{"type":"string","enum":["inactive_link","interface_mismatch","invalid_relationship","relationship_not_authorized","insufficient_scope"],"description":"Present when an active stored link does not authorize this Enterprise API operation. It identifies the mismatch without exposing the stored interface or relationship."},"required_interface":{"type":"string","enum":["enterprise_api"],"description":"Interface a fresh owner/admin consent must authorize."},"required_scopes":{"type":"array","items":{"type":"string"},"description":"Firm-consent scopes required by this operation."},"environment":{"type":"string","enum":["sandbox","production"]},"consent_flow":{"type":"string","enum":["sandbox_owner_test","owner_consent"]},"oauth_test":{"type":"object","description":"Present for sandbox firms. Points to the real dev authorization_code and PKCE test flow.","properties":{"available":{"type":"boolean"},"completed":{"type":"boolean"},"owner_accounts_path":{"type":"string"},"authorize_path":{"type":"string"},"token_path":{"type":"string"}}}}},"examples":{"pending":{"value":{"identifier":{"dic":"2122701339"},"firm":{"id":"b1022d80-5016-4dad-a8d2-53685cab1701","name":"Kaja Solutions s.r.o.","ico":"52345678","dic":"2122701339","peppol_id":"0245:2122701339","peppol_status":"active"},"consent_status":"pending","assign_status":"consent_required","next_action":"await_consent_acceptance"}},"required":{"value":{"identifier":{"ico":"52345678"},"firm":{"id":"b1022d80-5016-4dad-a8d2-53685cab1701","name":"Kaja Solutions s.r.o.","ico":"52345678","dic":"2122701339","peppol_id":"0245:2122701339","peppol_status":"active"},"consent_status":"required","assign_status":"consent_required","next_action":"request_integrator_consent"}},"interfaceMismatch":{"value":{"identifier":{"dic":"2122701339"},"firm":{"id":"b1022d80-5016-4dad-a8d2-53685cab1701","name":"Kaja Solutions s.r.o.","ico":"52345678","dic":"2122701339","peppol_id":"0245:2122701339","peppol_status":"active"},"consent_status":"required","assign_status":"consent_required","next_action":"request_integrator_reconsent","reason":"interface_mismatch","required_interface":"enterprise_api","required_scopes":["firms:manage"]}}}}}},"400":{"description":"Provide dic or ico in a valid format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing integrator token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing firms:manage scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Firm is not registered in ePostak yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-getfirmconsentstatus"}},"/firms/{id}":{"get":{"tags":["Firms"],"summary":"Detail firmy","description":"Vrati detailne informacie o konkretnej firme vratane Peppol statusu.","operationId":"getFirm","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID firmy"}],"responses":{"200":{"description":"Detail firmy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirmDetailResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Firma nenajdena","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-getfirm"}},"/firms/{id}/documents":{"get":{"tags":["Firms"],"summary":"Dokumenty firmy","description":"Vrati strankovany zoznam dokumentov (odoslanych aj prijatych) pre danu firmu.","operationId":"listFirmDocuments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID firmy"},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Pocet preskocenych zaznamov"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Pocet vratenych zaznamov"},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]},"description":"Filter podla smeru"}],"responses":{"200":{"description":"Zoznam dokumentov firmy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxListResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Firma nenajdena","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-listfirmdocuments"}},"/firms/{id}/peppol-identifiers":{"post":{"tags":["Firms"],"summary":"Registrovat Peppol identifikator","description":"Zaregistruje novy Peppol identifikator (scheme:identifier) pre firmu v SMP.","operationId":"registerPeppolIdentifier","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID firmy"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scheme","identifier"],"properties":{"scheme":{"type":"string","example":"0245","description":"ICD scheme kod"},"identifier":{"type":"string","example":"12345678","description":"Identifikator v danej scheme"}}},"example":{"scheme":"0245","identifier":"12345678"}}}},"responses":{"201":{"description":"Peppol identifikator zaregistrovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeppolIdentifierResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Neplatny scheme alebo identifikator","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Pristup odmietnuty","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Identifikator uz existuje","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-registerpeppolidentifier"}},"/firms/assign":{"post":{"tags":["Firms"],"summary":"Assign firm by DIC or ICO","description":"Assign a firm link in the pending state to the Enterprise API account by its DIC or ICO. DIC is preferred because Slovak PFS/SMP and Peppol use 0245:DIC. An active link is already assigned only when it authorizes Enterprise API through a valid relationship and includes firms:manage. An interface or relationship mismatch returns API_INTERFACE_NOT_AUTHORIZED. FIRM_ACTIVATION_PENDING means a dedicated entitlement or payer-change workflow is still finalizing the link. This endpoint never rewrites the integration path or bypasses a controlled lifecycle state. Requires a JWT minted from an sk_int_* key. No X-Firm-Id header needed.","operationId":"assignFirmByIco","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignFirmRequest"},"example":{"dic":"0000000001"}}}},"responses":{"201":{"description":"Firm assigned successfully (plan automatically promoted to `integrator-managed`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignFirmResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Invalid JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing integrator token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing `firms:manage` scope, absent/currently insufficient firm consent, or API_INTERFACE_NOT_AUTHORIZED because the stored firm link does not authorize Enterprise API through the current relationship","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"},"examples":{"interfaceMismatch":{"value":{"error":{"code":"API_INTERFACE_NOT_AUTHORIZED","message":"Firm consent does not authorize Enterprise API through the current partner relationship.","reason":"interface_mismatch","required_interface":"enterprise_api","required_scopes":["firms:manage"]}}}}}}},"404":{"description":"Firm not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Already assigned with a valid active link, current agreement missing, or FIRM_ACTIVATION_PENDING while a controlled entitlement/payer workflow finalizes the link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"UNPROCESSABLE_ENTITY — provide a 10-digit DIC or 8-digit ICO","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-assignfirmbyico"}},"/firms/assign/batch":{"post":{"tags":["Firms"],"summary":"Batch assign firms by DIC or ICO list","description":"Assign multiple pending firm links at once. Prefer `dics`; `icos` remains supported for backward compatibility. An item is already_assigned only when its active link authorizes Enterprise API through a valid relationship and includes firms:manage. Interface or relationship mismatches are returned per item as API_INTERFACE_NOT_AUTHORIZED with the reason and required interface. FIRM_ACTIVATION_PENDING means a controlled entitlement or payer-change workflow must finish that item. Links and lifecycle states are never rewritten automatically. Maximum 50 identifiers per request.","operationId":"batchAssignFirms","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAssignFirmsRequest"},"example":{"dics":["0000000001","0000000002"]}}}},"responses":{"200":{"description":"Batch assignment results per DIC/ICO, including consent and interface-authorization errors per item","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAssignFirmsResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:firms","x-epostak-docs-anchor":"enterprise-batchassignfirms"}},"/reporting/statistics":{"get":{"tags":["Reporting"],"summary":"Statistiky dokumentov","description":"Vrati agregovane statistiky odoslanych a prijatych dokumentov za zvolene obdobie.","operationId":"getStatistics","parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date","example":"2026-01-01"},"description":"Zaciatok obdobia (YYYY-MM-DD)"},{"name":"to","in":"query","schema":{"type":"string","format":"date","example":"2026-03-31"},"description":"Koniec obdobia (YYYY-MM-DD)"}],"responses":{"200":{"description":"Statistiky dokumentov","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatisticsResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:reporting","x-epostak-docs-anchor":"enterprise-getstatistics"}},"/reporting/submissions":{"get":{"tags":["Reporting"],"summary":"List EUSR/TSR submissions to OpenPeppol","description":"Paginated read-only history of EUSR/TSR statistics reports submitted by ePošťák as a Peppol AP operator to OpenPeppol. Internal fields (checksum, raw error message, receiver ID) are intentionally omitted; clients receive a `has_error` boolean instead.\n\nThis is a global operator-level history (not per-firm), reflecting that EUSR/TSR are AP-operator obligations.","operationId":"listReportingSubmissions","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}},{"name":"report_type","in":"query","required":false,"schema":{"type":"string","enum":["EUSR","TSR"]}}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportingSubmissionsResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"422":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"optional","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:reporting","x-epostak-docs-anchor":"enterprise-listreportingsubmissions"}},"/audit":{"get":{"tags":["Account"],"summary":"Audit event feed (Wave 3.4)","description":"Per-firm security/auth audit log. Tenant-isolated by firmId from JWT (sk_live_*) or X-Firm-Id header (sk_int_*). Cursor pagination over `(occurred_at DESC, id DESC)`.\n\n**Requires `audit:read` scope and an API-eligible actor: `api-enterprise` directly, or `integrator-managed` through the managing integrator.**","operationId":"listAuditEvents","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"event","in":"query","schema":{"type":"string"},"description":"Exact event name match (e.g. `jwt.issued`, `webhook.created`)"},{"name":"actor_type","in":"query","schema":{"type":"string","enum":["user","apiKey","integratorKey","system"]}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"until","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from previous response's `next_cursor`"}],"responses":{"200":{"description":"Audit events","content":{"application/json":{"schema":{"type":"object","required":["items","has_more"],"properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"occurred_at":{"type":"string","format":"date-time"},"actor_type":{"type":"string"},"actor_id":{"type":"string","nullable":true},"event":{"type":"string"},"target_type":{"type":"string","nullable":true},"target_id":{"type":"string","nullable":true},"ip":{"type":"string","nullable":true},"user_agent":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":true,"nullable":true}}}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Plan does not allow this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"forbidden","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:account","x-epostak-docs-anchor":"enterprise-listauditevents"}},"/validate":{"post":{"tags":["Validation"],"summary":"Public UBL validator (no auth)","description":"**Public endpoint — NOT under `/api/v1/`.** Full path: `https://epostak.sk/api/validate`.\n\nValidator-as-a-service. Anyone can POST UBL XML (or `{ xml: \"...\" }` JSON) and get back the full 3-layer report our own send pipeline runs: UBL 2.1 XSD, EN 16931, Peppol BIS 3.0 schematrons. Rate-limited per-IP to 20/min. Body cap: 2 MB. Designed as a dry-run hook for integrators pre-signup.\n\nServer: `https://epostak.sk` (override the `/api/v1` server shown elsewhere).","operationId":"validatePublic","servers":[{"url":"https://epostak.sk/api","description":"Public base (no /v1 prefix)"}],"security":[],"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","format":"xml"}},"application/json":{"schema":{"type":"object","required":["xml"],"properties":{"xml":{"type":"string"}}}}}},"responses":{"200":{"description":"Validation report (3-layer)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Malformed request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Payload too large (> 2 MB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"body.xml is required or empty body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded (20/min/IP)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"503":{"description":"ion-docval unreachable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:validation","x-epostak-docs-anchor":"enterprise-validatepublic"}},"/inbound/import":{"post":{"tags":["Pull API — Inbound"],"summary":"Import received UBL document","description":"Stores a UBL billing document received outside the Peppol network (email, SFTP, migration from another access point) in the same inbound document store as Peppol receipts. Accepts raw `application/xml` or `application/json` with an `xml` field. The XML receiver Peppol ID must match the authenticated firm. Emits `document.received` after the row is stored.","operationId":"importInboundDocument","requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","format":"xml"}},"text/xml":{"schema":{"type":"string","format":"xml"}},"application/json":{"schema":{"$ref":"#/components/schemas/InboundImportRequest"}}}},"responses":{"201":{"description":"Document imported","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundImportResponse"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires documents:write)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid XML, unsupported document type, or receiver Peppol ID does not match this firm","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-inbound","x-epostak-docs-anchor":"enterprise-importinbounddocument"}},"/inbound/documents":{"get":{"tags":["Pull API — Inbound"],"summary":"List inbound documents","description":"Cursor-based list of documents received from Peppol. Returns newest-first by default. Use ?since= cursor for forward-paging (oldest-to-newest order is ascending).\n\n**Auth:** scope `documents:read`, plan `api-enterprise` directly, or `integrator-managed` through the managing integrator.\n\nResponse shape is produced by `formatInboundDocument`.","operationId":"listInboundDocuments","parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque versioned cursor from previous response next_cursor. Omit to start from beginning."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"kind","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by doctype key (invoice, credit_note, etc.)"},{"name":"sender","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by sender Peppol ID (exact match)"}],"responses":{"200":{"description":"Paginated list of inbound documents","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundDocumentsListResponse"}}}},"400":{"description":"Invalid query parameters (e.g. malformed cursor, limit out of range)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-inbound","x-epostak-docs-anchor":"enterprise-listinbounddocuments"}},"/inbound/documents/{id}":{"get":{"tags":["Pull API — Inbound"],"summary":"Get inbound document","description":"Fetch a single inbound document by ID. 404 when the document does not exist or belongs to a different tenant.","operationId":"getInboundDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Document ID"}],"responses":{"200":{"description":"Inbound document","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundDocument"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found or does not belong to this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-inbound","x-epostak-docs-anchor":"enterprise-getinbounddocument"}},"/inbound/documents/{id}/ubl":{"get":{"tags":["Pull API — Inbound"],"summary":"Get raw UBL XML for inbound document","description":"Returns the raw AS4-received UBL XML. 404 when no rawXmlPath stored (documents received before the raw-archive feature was enabled).\n\n**Response:**  with .","operationId":"getInboundDocumentUbl","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Raw UBL XML","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/xml":{"schema":{"type":"string","format":"xml"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found or does not belong to this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-inbound","x-epostak-docs-anchor":"enterprise-getinbounddocumentubl"}},"/inbound/documents/{id}/ack":{"post":{"tags":["Pull API — Inbound"],"summary":"Acknowledge inbound document","description":"Mark an inbound document as acknowledged by the client. Idempotent — calling again with a new client_reference overwrites the previous one (latest-ack-wins).\n\n**Auth:** scope `documents:write` (NOT `documents:read` — this is a write operation).\n\n**Response:** Returns the full document shape post-ack.","operationId":"ackInboundDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundAckRequest"}}}},"responses":{"200":{"description":"Document acknowledged; returns updated document shape","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundDocument"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:write)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found or does not belong to this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-inbound","x-epostak-docs-anchor":"enterprise-ackinbounddocument"}},"/outbound/documents":{"get":{"tags":["Pull API — Outbound"],"summary":"List outbound documents","description":"Cursor-based list of outbound documents (both Invoice-backed billing and PeppolDocument non-billing). Merged and sorted newest-first. Uses a union cursor (-prefixed base64url, v=1) to correctly paginate across two source tables.\n\n**Auth:** scope `documents:read`, plan `api-enterprise` directly, or `integrator-managed` through the managing integrator.","operationId":"listOutboundDocuments","parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"Union cursor from previous next_cursor"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"kind","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by doctype key"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["queued","sending","sent","delivered","failed","dead"]},"description":"Filter by transport_status"},{"name":"business_status","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by invoice business_status (billing docs only)"},{"name":"recipient","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by recipient Peppol ID"},{"name":"since_date","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Filter: rows created at or after this timestamp (ISO 8601)"}],"responses":{"200":{"description":"Paginated list of outbound documents","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutboundDocumentsListResponse"}}}},"400":{"description":"Invalid query params","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-outbound","x-epostak-docs-anchor":"enterprise-listoutbounddocuments"}},"/outbound/documents/{id}":{"get":{"tags":["Pull API — Outbound"],"summary":"Get outbound document","description":"Fetch a single outbound document by ID. Probes Invoice and PeppolDocument tables. The detail view includes attempt_history (delivery attempts) which is absent from the list view.","operationId":"getOutboundDocument","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Outbound document with attempt_history populated","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutboundDocument"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found or does not belong to this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-outbound","x-epostak-docs-anchor":"enterprise-getoutbounddocument"}},"/outbound/documents/{id}/ubl":{"get":{"tags":["Pull API — Outbound"],"summary":"Get raw UBL XML for outbound document","description":"Returns the raw UBL XML. Probes Invoice.ublXmlPath then PeppolDocument.rawXmlPath, returning whichever is populated first. 404 when neither path is stored.","operationId":"getOutboundDocumentUbl","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Raw UBL XML","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/xml":{"schema":{"type":"string","format":"xml"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found or does not belong to this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-outbound","x-epostak-docs-anchor":"enterprise-getoutbounddocumentubl"}},"/outbound/documents/{id}/mdn":{"get":{"tags":["Pull API — Outbound"],"summary":"Get raw AS4 MDN receipt for outbound document","description":"Returns the raw AS4 signal-message receipt (MDN/receipt) for an outbound document when it has been forward-retained in the evidence archive. This endpoint is for audit/dispute scenarios; normal delivery tracking should use `transport_status`, `delivered_at`, or webhooks/events. 404 when the document is missing, foreign-tenant, not outbound, or no retained MDN receipt exists yet.","operationId":"getOutboundDocumentMdn","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Raw AS4 receipt bytes. Headers include X-MDN-Message-Id, X-MDN-Ref-To-Message-Id, X-MDN-SHA256, and X-MDN-Received-At.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/xml":{"schema":{"type":"string","format":"xml"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Document not found, not outbound, or no retained MDN receipt exists yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"MDN evidence integrity check failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-outbound","x-epostak-docs-anchor":"enterprise-getoutbounddocumentmdn"}},"/outbound/events":{"get":{"tags":["Pull API — Outbound"],"summary":"Outbound document lifecycle event stream","description":"Cursor-based stream of outbound document lifecycle events (DocumentEvent table). Sorted oldest-to-newest (ascending) — a saved cursor naturally consumes events forward in time.\n\n**Coverage:** Invoice-backed events only in v1. Non-billing outbound docs (Order, DespatchAdvice, etc.) are tracked by polling /outbound/documents directly.\n\n**Auth:** scope `documents:read`, plan `api-enterprise` directly, or `integrator-managed` through the managing integrator.","operationId":"getOutboundEvents","parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"Versioned cursor from previous next_cursor"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"document_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"Filter to events for a specific document ID"}],"responses":{"200":{"description":"Paginated event stream","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutboundEventsListResponse"}}}},"400":{"description":"Invalid cursor","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:pull-api-outbound","x-epostak-docs-anchor":"enterprise-getoutboundevents"}},"/company/search":{"get":{"tags":["Peppol"],"summary":"Search companies by name","description":"Full-text search against the Slovak company registry (ARES/FinStat). Returns matches scored by relevance. Minimum 2-character query.\n\n**Auth:** scope `peppol:lookup`, API-eligible actor.","operationId":"searchCompanies","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2},"description":"Search query (company name, minimum 2 chars)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":10}}],"responses":{"200":{"description":"Company search results","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"description":"Invalid or missing API key / JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Insufficient plan or scope (requires api-enterprise directly or integrator-managed through the managing integrator, scope documents:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:peppol","x-epostak-docs-anchor":"enterprise-searchcompanies"}},"/payloads/extract":{"post":{"tags":["Payload Assistant"],"summary":"Extract payload fields from PDF or image","description":"Canonical Payload Assistant OCR extraction endpoint. Call OCR once, then correct its response through POST /payloads/review by sending the returned `extraction` and all human corrections together; the review endpoint does not upload the PDF or invoke OCR again. The original resend of the same file with multipart `fields` remains supported for compatibility. The response identifies accepted corrections in `applied_overrides`; always follow `missing_fields` and `next_action`. The retired /extract alias is no longer served.","operationId":"payloadExtractDocument","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"PDF alebo obrazok faktury (max 20 MB)"},"fields":{"type":"string","description":"Optional JSON object with corrected OCR values. Resend the same file and supply only fields that should override OCR, for example {\"vendor_dic\":\"2020123456\",\"vendor_ic_dph\":\"SK2020123456\",\"iban\":\"SK6807200002891987426353\"}. Supported values include supplier and buyer identifiers, dates, payment data, amounts, items, and document_type.","example":"{\"vendor_dic\":\"2020123456\",\"vendor_ic_dph\":\"SK2020123456\",\"iban\":\"SK6807200002891987426353\"}"}}}}}},"responses":{"200":{"description":"Extrakcia uspesna","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Chybajuci subor, nepodporovany typ alebo prilis velky subor","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleErrorResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan je vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleErrorResponse"}}}},"422":{"description":"Extrakcia alebo UBL generovanie zlyhalo. Vystavene/outbound PDF faktury vracaju 200 s direction=outbound; standardne faktury obsahuju send_payload na kontrolu.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractErrorResponse"}}}},"429":{"description":"Rate limit exceeded (10/min/firm)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"503":{"description":"Gemini API key not configured (SERVICE_UNAVAILABLE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:payload-assistant","x-epostak-docs-anchor":"enterprise-payloadextractdocument"}},"/payloads/review":{"post":{"tags":["Payload Assistant"],"summary":"Review and correct an extraction without rerunning OCR","description":"Accepts the `extraction` object returned by `/payloads/extract` and all human corrections together in `fields`. Corrections are applied before tenant ownership and direction checks. The endpoint rebuilds and validates the UBL or outbound `send_payload` without uploading the source file or invoking OCR again. `review_decision=approve` can clear a low/medium confidence review after a human checked the result, but never bypasses blocking missing fields, tenant mismatch, invalid or deferred validation, or high vendor risk. This endpoint never sends the document.","operationId":"payloadReviewExtraction","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayloadReviewRequest"}}}},"responses":{"200":{"description":"Corrected payload rebuilt without another OCR call","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Invalid extraction snapshot, correction object, or review decision","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API access denied or corrected extraction belongs to another firm","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"JSON body exceeds 2 MB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Corrected extraction cannot be converted to a usable UBL or outbound payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractErrorResponse"}}}},"429":{"description":"Rate limit exceeded (60/min/firm)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:payload-assistant","x-epostak-docs-anchor":"enterprise-payloadreviewextraction"}},"/payloads/extract/batch":{"post":{"tags":["Payload Assistant"],"summary":"Batch OCR extraction for payload creation","description":"Canonical batch OCR endpoint. Each successful row contains an `extraction` object. Correct exception rows individually through POST /payloads/review by sending that extraction and all corrected fields together; no PDF re-upload or repeat OCR is required. The retired /extract/batch alias is no longer served.","operationId":"payloadExtractBatch","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["files"],"properties":{"files":{"type":"array","items":{"type":"string","format":"binary"},"maxItems":50,"description":"PDF or image files"}}}}}},"responses":{"200":{"description":"Batch extraction results (per-file success or error)","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"413":{"description":"Total body exceeds 200 MB or individual file > 20 MB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded (3/min/firm)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"503":{"description":"Gemini API not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:payload-assistant","x-epostak-docs-anchor":"enterprise-payloadextractbatch"}},"/payloads/parse":{"post":{"tags":["Payload Assistant"],"summary":"Parse raw UBL into normalized JSON","description":"Canonical Payload Assistant endpoint for parsing UBL/XML into normalized JSON. The retired /documents/parse alias is no longer served.","operationId":"payloadParseDocument","requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","format":"xml"}},"application/json":{"schema":{"type":"object","required":["xml"],"properties":{"xml":{"type":"string","description":"UBL Invoice or CreditNote XML"}}}}}},"responses":{"200":{"description":"Parsed invoice payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"413":{"description":"Payload too large (> 10 MB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation or parse error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:payload-assistant","x-epostak-docs-anchor":"enterprise-payloadparsedocument"}},"/payloads/convert":{"post":{"tags":["Payload Assistant"],"summary":"Convert payload formats","description":"Canonical Payload Assistant endpoint for converting supported document payload formats. The retired /documents/convert alias is no longer served.","operationId":"payloadConvertDocument","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertDocumentRequest"},"examples":{"jsonToUbl":{"summary":"JSON → UBL","value":{"input_format":"json","output_format":"ubl","document":{"invoiceNumber":"FAK-001","items":[{"description":"Sluzba s prenesenim DPH","quantity":1,"unitPrice":200,"vatRate":0,"vatCategoryCode":"AE"}]}}},"ublToJson":{"summary":"UBL → JSON","value":{"input_format":"ubl","output_format":"json","document":"<?xml version=\"1.0\"?>..."}}}}}},"responses":{"200":{"description":"Konverzia uspesna. Pre `output_format=ubl` je `document` string, pre `output_format=json` je objekt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertDocumentResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"413":{"description":"Payload too large (> 6 MB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Konverzia zlyhala alebo nepodporovana kombinacia input_format/output_format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Backend conversion service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:payload-assistant","x-epostak-docs-anchor":"enterprise-payloadconvertdocument"}},"/payloads/validate":{"post":{"tags":["Payload Assistant"],"summary":"Validate payload without sending","description":"Canonical Payload Assistant endpoint for preflight document validation. The retired /documents/validate alias is no longer served.","operationId":"payloadValidateDocument","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SendDocumentJsonRequest"},{"$ref":"#/components/schemas/SendDocumentXmlRequest"}]}}}},"responses":{"200":{"description":"Validacia uspesna","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateDocumentResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"413":{"description":"Payload too large (> 6 MB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"UBL validation error (schematron rule failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UblValidationError"}}}},"503":{"description":"VALIDATION_SERVICE_UNAVAILABLE — ion-docval unreachable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:payload-assistant","x-epostak-docs-anchor":"enterprise-payloadvalidatedocument"}},"/events/pull":{"get":{"tags":["Webhooks & Events"],"summary":"Pull unacknowledged events","description":"Canonical Events endpoint for polling queued webhook events in the Enterprise reliability contract. The queue is forward-only: only events created while a matching pull subscription is active are queued; older sender-side and receiver-side events are not backfilled. After send, poll unacknowledged events and acknowledge after local commit in the ERP; if processing fails, leave the event unacknowledged and pull it again. The server keeps state through acknowledgements, so clients do not need client-side cursor bookkeeping. The retired /webhook-queue alias is no longer served.","operationId":"eventsPull","responses":{"200":{"description":"Zoznam cakajucich udalosti","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventsPullResponse"}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan je vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks-events","x-epostak-docs-anchor":"enterprise-eventspull"}},"/events/batch-ack":{"post":{"tags":["Webhooks & Events"],"summary":"Acknowledge multiple events","description":"Canonical Events endpoint for batch acknowledgement. Enterprise reliability contract: acknowledge after local commit, not when the event is fetched. Use this after a batch import commit; on retry, leave events unacknowledged and read them again from /events/pull. The retired /webhook-queue/batch-ack alias is no longer served.","operationId":"eventsBatchAck","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["event_ids"],"properties":{"event_ids":{"type":"array","items":{"type":"string"},"example":["evt_1","evt_2","evt_3"],"description":"Zoznam ID udalosti na potvrdenie"}}}}}},"responses":{"200":{"description":"Udalosti potvrdene","content":{"application/json":{"schema":{"type":"object","properties":{"acknowledged":{"type":"integer","example":3,"description":"Pocet potvrdenych udalosti"}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"400":{"description":"Chybajuci alebo prazdny zoznam event_ids","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan je vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks-events","x-epostak-docs-anchor":"enterprise-eventsbatchack"}},"/events/{eventId}/ack":{"post":{"tags":["Webhooks & Events"],"summary":"Acknowledge one event","description":"Canonical Events endpoint for acknowledging one queued event. The retired /webhook-queue/{eventId} DELETE alias is no longer served.","operationId":"eventsAck","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string"},"description":"ID udalosti"}],"responses":{"200":{"description":"Udalost potvrdena","content":{"application/json":{"schema":{"type":"object","properties":{"acknowledged":{"type":"boolean","example":true}}}}},"headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}}},"401":{"description":"Neplatny alebo chybajuci API kluc","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan je vyzadovany","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForbiddenErrorResponse"}}}},"404":{"description":"Udalost nenajdena","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"advanced","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:webhooks-events","x-epostak-docs-anchor":"enterprise-eventsack"}},"/documents/{id}/support-packet":{"get":{"tags":["Lifecycle & proof"],"summary":"Document support packet","description":"Canonical Lifecycle & proof endpoint for the document support ZIP bundle. Enterprise reliability contract final step: store requestId, documentId/submissionId, messageId, payloadSha256 and support-packet for incidents instead of sending full XML when a hash and support packet are enough. The retired /documents/{id}/evidence-bundle alias is no longer served.","operationId":"getDocumentSupportPacket","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Document ID"}],"responses":{"200":{"description":"Document support packet","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API plan required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Support packet too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"MDN evidence integrity check failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-epostak-product":"enterprise","x-epostak-profile-visibility":"core","x-epostak-lifecycle":"active","x-epostak-deprecation-at":null,"x-epostak-sunset-at":null,"x-epostak-replacement":null,"x-epostak-accepted-credential-types":["enterprise-bearer"],"x-epostak-required-scopes":[],"x-epostak-firm-context":"required","x-epostak-idempotency":false,"x-epostak-owner":"enterprise:lifecycle-proof","x-epostak-docs-anchor":"enterprise-getdocumentsupportpacket"}}},"components":{"schemas":{"JwtTokenRequest":{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"]},"client_id":{"type":"string","description":"The client_id shown with the key. It must match the API key row UUID or displayed key prefix; it is not the sk_live_*/sk_int_* secret."},"client_secret":{"type":"string","description":"The full `sk_live_*` or `sk_int_*` API key."},"scope":{"type":"string","description":"Optional space-separated subset of the key's allowed scopes. If omitted, the JWT inherits the key's full scope set (or `*` for wildcard keys)."}}},"JwtTokenResponse":{"type":"object","required":["access_token","token_type","expires_in","refresh_token","scope"],"properties":{"access_token":{"type":"string","description":"Short-lived JWT (RS256, 15 min TTL). Use as `Authorization: Bearer <token>` on all `/api/v1/*` endpoints."},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"integer","example":900},"refresh_token":{"type":"string","description":"Refresh token (30 day TTL). Single-use — rotated on each `/auth/renew` call."},"scope":{"type":"string","example":"documents:send documents:read"}}},"PeppolErrorResponse":{"type":"object","description":"Error envelope used by the JWT auth endpoints (`/auth/token`, `/auth/renew`, `/auth/revoke`) and any `/sapi/v1/*` endpoint. Different from `ErrorResponse` — designed for Peppol Access Point error semantics with retry hints.","required":["error"],"properties":{"error":{"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","description":"Stable machine-readable code (e.g. `SAPI-AUTH-001` invalid creds, `SAPI-AUTH-008` scope denied, `SAPI-AUTH-099` internal)."},"message":{"type":"string","example":"Invalid client credentials"},"retryable":{"type":"boolean","description":"True for 5xx/429 — caller may retry with backoff."},"correlation_id":{"type":"string","format":"uuid"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"issue":{"type":"string"},"value":{"type":"string"}}}}}}}},"JwtRenewRequest":{"type":"object","required":["grant_type","refresh_token"],"properties":{"grant_type":{"type":"string","enum":["refresh_token"]},"refresh_token":{"type":"string"}}},"JwtRevokeRequest":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"Either a JWT access token (starts with `eyJ`) or a refresh token."},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"],"description":"Optional hint — the server detects type automatically."}}},"ErrorResponse":{"type":"object","description":"Standard error envelope for `/api/v1/*` endpoints (excluding `/auth/token|renew|revoke` which use `PeppolErrorResponse`, and `/oauth/token` which uses RFC 6749 `OAuthErrorResponse`). The `requestId` echoes the `X-Request-Id` response header — quote it in support tickets.","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","description":"Machine-readable error code. Branch on this value, not only on HTTP status. Known codes:\n- VALIDATION_ERROR (422) - JSON, XML shape, or required field validation failed; fix the payload and retry.\n- UBL_VALIDATION_ERROR (422) - Peppol/CEN schematron rejection; inspect details[].rule such as BR-CO-26.\n- UNPROCESSABLE_ENTITY (422) - business rule rejection.\n- IDEMPOTENCY_KEY_MISMATCH (422) - the same Idempotency-Key was reused with a different canonicalized body.\n- IDEMPOTENCY_IN_FLIGHT (409) - the same idempotency key is still processing; wait and poll status.\n- CONNECTOR_LEGACY_IDEMPOTENCY_OWNER_UNPROVEN (409) - a pre-deploy Connector send cannot yet prove the historical key owner; if retryable=true wait 30 seconds and retry the exact same key/body, never change the key; if retryable=false do not resubmit and contact support.\n- AUTOPILOT_REPLAY_MISMATCH (409) - the command changed or a historical direct reference is reserved in another/unproven ownership namespace; no timed retry, reconcile first.\n- CONNECTOR_OUTBOX_REFERENCE_RESERVED (409) - a historical outbox item without proven integrator ownership already reserves the ERP reference; reconcile first.\n- NOT_FOUND (404).\n- FORBIDDEN (403) - plan, scope, or ownership denied.\n- CONFLICT (409) - duplicate or unique-constraint collision.\n- BAD_REQUEST (400) - malformed body or parameters.\n- INVALID_PARAM (400).\n- PAYLOAD_TOO_LARGE (413).\n- RATE_LIMITED (429) - respect Retry-After when present.\n- VALIDATION_SERVICE_UNAVAILABLE (503) - retry with backoff.\n- IDEMPOTENCY_STORE_UNAVAILABLE (503) - retry the same payload with the same Idempotency-Key.\n- SEND_FAILED (502) - Peppol AP dispatch failed, retryable when the same payload and key are used.\n- SERVICE_UNAVAILABLE (503) - upstream dependency unavailable.\n- INTERNAL_ERROR (500).\nBusiness error catalog:\n- participant_not_found (422) - retryable=false; fix_hint=change or verify the receiver Peppol ID.\n- receiver_unsupported_document_type (422) - retryable=false; fix_hint=change document type/profile or receiver capability.\n- validation_failed (422) - retryable=false; fix_hint=fix the UBL/JSON payload using details/rule.\n- temporary_transport_error (502/503) - retryable=true; fix_hint=retry with backoff and the same Idempotency-Key.\n- delivery_dead_lettered (409) - retryable=false; fix_hint=inspect events/support-packet, then retry manually or contact support.\n- duplicate_idempotency_key (422) - retryable=false; fix_hint=send the original body or use a new key for changed payload.","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"receiverPeppolId is required"},"requestId":{"type":"string","format":"uuid","description":"Mirror of the `X-Request-Id` response header — for tracing."},"details":{"description":"Optional structured details (e.g., Zod error array, Peppol schematron rule IDs)"},"conflictTarget":{"type":"string","description":"On 409 from a unique-constraint collision: comma-joined target columns (e.g. `firm_id,idempotency_key`)."}}}}},"AuthStatusResponse":{"type":"object","properties":{"key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","example":"Production integration"},"prefix":{"type":"string","example":"sk_live_abc123"},"permissions":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true}}},"firm":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"peppolStatus":{"type":"string","example":"active"}}},"plan":{"type":"object","properties":{"name":{"type":"string","example":"api-enterprise"},"expiresAt":{"type":"string","format":"date-time","nullable":true},"active":{"type":"boolean"}}},"rateLimit":{"type":"object","properties":{"perMinute":{"type":"integer","example":200},"window":{"type":"string","example":"60s"}}},"integrator":{"type":"object","nullable":true,"description":"Present only for sk_int_* keys","properties":{"id":{"type":"string","format":"uuid"}}}}},"ForbiddenErrorResponse":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}],"description":"403 variant of `ErrorResponse`. The 401/403 responses also include `WWW-Authenticate: Bearer error=\"invalid_token\"|\"insufficient_scope\" scope=\"<required-scope>\"` per RFC 6750 — clients should parse `scope=\"…\"` to learn what scope is required."},"RotateSecretResponse":{"type":"object","properties":{"key":{"type":"string","description":"New full API key, shown once.","example":"sk_live_abc...xyz"},"prefix":{"type":"string","example":"sk_live_abc123"},"message":{"type":"string","example":"Key rotated. Save it — it will not be shown again. The previous key is now inactive."}}},"OAuthTokenRequest":{"type":"object","required":["grant_type","code","client_id","client_secret","redirect_uri"],"properties":{"grant_type":{"type":"string","enum":["authorization_code"],"example":"authorization_code"},"code":{"type":"string","example":"auth_code_here"},"client_id":{"type":"string","example":"client_id_here"},"client_secret":{"type":"string","example":"client_secret_here"},"redirect_uri":{"type":"string","format":"uri","example":"https://example.com/callback"},"code_verifier":{"type":"string","description":"PKCE code verifier (optional)","example":"pkce_verifier_here"}}},"OAuthTokenResponse":{"type":"object","required":["client_id","client_secret","secret_type","token_type","scope","firm_id"],"properties":{"client_id":{"type":"string","description":"Identifier to send as client_id when exchanging this secret at /api/v1/auth/token.","example":"sk_int_abc...xyz"},"client_secret":{"type":"string","description":"New sk_int_* secret. Store once; it is not shown again.","example":"sk_int_abc123"},"secret_type":{"type":"string","enum":["sk_int"]},"token_type":{"type":"string","enum":["client_secret"]},"scope":{"type":"string","example":"firms:manage documents:send documents:read"},"firm_id":{"type":"string","format":"uuid"},"firm_name":{"type":"string","example":"Example s.r.o."},"firm_ico":{"type":"string","example":"12345678"}}},"OAuthErrorResponse":{"type":"object","description":"RFC 6749 OAuth 2.0 error response. Uses top-level `error` and `error_description` strings, not the `error: { code, message }` envelope used everywhere else in this API.","required":["error"],"properties":{"error":{"type":"string","enum":["invalid_request","invalid_client","invalid_grant","unauthorized_client","unsupported_grant_type","invalid_scope"],"example":"invalid_grant"},"error_description":{"type":"string","example":"Authorization code is invalid or expired"}}},"AccountResponse":{"type":"object","properties":{"firm":{"type":"object","properties":{"name":{"type":"string","example":"Moja firma s.r.o."},"ico":{"type":"string","nullable":true,"example":"12345678"},"peppolId":{"type":"string","nullable":true,"example":"0245:12345678"},"peppolStatus":{"type":"string","example":"active"}}},"plan":{"type":"object","properties":{"name":{"type":"string","example":"api-enterprise"},"status":{"type":"string","enum":["active","expired"]}}},"usage":{"type":"object","properties":{"outbound":{"type":"integer","description":"Pocet odoslanych dokumentov"},"inbound":{"type":"integer","description":"Pocet prijatych dokumentov"}}}}},"SendDocumentJsonRequest":{"type":"object","required":["items"],"allOf":[{"description":"A successful JSON billing request needs a Peppol recipient ID. Use receiverPeppolId for invoice/credit_note; self-billing may use supplierPeppolId.","anyOf":[{"required":["receiverPeppolId"]},{"required":["supplierPeppolId"]}]},{"description":"A successful JSON billing request needs the counterparty legal name. Use receiverName for invoice/credit_note; self-billing may use supplierName.","anyOf":[{"required":["receiverName"]},{"required":["supplierName"]}]}],"description":"Complete JSON billing contract shared by Enterprise send and Connector. UBL XML is generated automatically for invoice, credit_note, self_billing and self_billing_credit_note. Only items is unconditionally required under one fixed field name; a successful request also needs one accepted Peppol recipient ID and one accepted counterparty name. receiverPeppolId and receiverName are required for invoice/credit_note, while self-billing may use supplierPeppolId and supplierName. Credit-note types additionally require precedingInvoiceRef. Sender fields are not accepted: the authenticated firm is the supplier for regular invoices/credit notes and the buyer for self-billing. Unknown fields are not mapped into the generated UBL.","properties":{"processId":{"type":"string","description":"Peppol process URN. Accepts the bare URN or the cenbii-procid-ubl:: prefixed form. Defaults to profile 01; use urn:peppol:bis:billing_with_response to require an Invoice Response."},"documentType":{"type":"string","enum":["invoice","credit_note","self_billing","self_billing_credit_note"],"default":"invoice","example":"invoice","description":"Business document type. invoice is a supplier-issued invoice; credit_note corrects a supplier-issued invoice; self_billing is a buyer-issued invoice; self_billing_credit_note corrects a buyer-issued invoice. Defaults to invoice."},"document_type":{"type":"string","enum":["invoice","credit_note","self_billing","self_billing_credit_note"],"description":"Snake_case alias for documentType. If multiple aliases are sent, all non-empty values must match."},"docType":{"type":"string","enum":["invoice","credit_note","self_billing","self_billing_credit_note"],"description":"Compatibility alias for documentType. Do not send conflicting alias values."},"receiverPeppolId":{"type":"string","example":"0245:12345678","description":"Peppol participant ID in scheme:identifier form, for example 0245:2123456789. Required for invoice/credit_note and identifies the buyer. For self-billing it identifies the supplier/Peppol recipient, but supplierPeppolId is the clearer alias."},"supplierPeppolId":{"type":"string","example":"0245:2123038963","description":"Self-billing alias for the supplier/Peppol recipient in scheme:identifier form. Allowed only for self_billing and self_billing_credit_note; it is normalized into receiverPeppolId."},"invoiceNumber":{"type":"string","example":"FAK-2026-0001","description":"Invoice or credit-note number. If omitted or empty, ePošťák allocates the next number from the authenticated firm's numbering sequence."},"precedingInvoiceRef":{"type":"string","example":"FAK-2026-0001","description":"External original invoice number corrected by this credit note. Required for credit_note and self_billing_credit_note; emitted as UBL BillingReference."},"issueDate":{"type":"string","format":"date","example":"2026-04-01","description":"Issue date in YYYY-MM-DD format. If omitted, the current date in Europe/Bratislava is used."},"dueDate":{"type":"string","format":"date","example":"2026-04-15","description":"Payment due date in YYYY-MM-DD format. Optional."},"taxPointDate":{"type":"string","format":"date","example":"2026-04-01","description":"VAT tax point date (BT-7) in YYYY-MM-DD format. Kept separate from the actual delivery date."},"deliveryDate":{"type":"string","format":"date","example":"2026-03-31","description":"Actual delivery date for the whole document (BT-72) in YYYY-MM-DD format."},"documentDiscountPercent":{"type":"number","minimum":0,"maximum":100,"example":5,"description":"Document-level discount percentage represented as a Peppol BG-20 allowance. This is additional to any items[].discount."},"currency":{"type":"string","example":"EUR","default":"EUR","description":"ISO 4217 currency code. If omitted, the authenticated firm's default currency is used, falling back to EUR."},"note":{"type":"string","example":"Dakujeme za objednavku.","description":"Free-text invoice note. Use it for a human-readable exemption/reverse-charge reason or other information the receiver must see."},"iban":{"type":"string","example":"SK1234567890123456789012","description":"Payment IBAN. If omitted, the authenticated firm's saved IBAN is used when available."},"paymentMethod":{"type":"string","example":"bank_transfer","description":"Payment method. Accepted convenience aliases: bank_transfer=30, credit_transfer=30, sepa=58, card=48, cash=10, direct_debit=49. A direct UNCL4461 code such as 30 is also accepted. Omitted defaults to 30 in generated UBL."},"variableSymbol":{"type":"string","example":"20260001","description":"Variable symbol / payment reference included with payment means."},"buyerReference":{"type":"string","example":"PO-2026-99","description":"Buyer reference, purchase-order number, or internal procurement reference."},"receiverName":{"type":"string","example":"Zakaznik s.r.o.","description":"Counterparty legal/business name. Required for invoice/credit_note. For self-billing it identifies the supplier, but supplierName is the clearer alias."},"receiverIco":{"type":"string","example":"12345678","description":"Counterparty company registration number (IČO)."},"receiverDic":{"type":"string","example":"2020123456","description":"Counterparty tax identification number (DIČ)."},"receiverIcDph":{"type":"string","example":"SK2020123456","description":"Counterparty VAT identification number (IČ DPH). For self-billing it is also used to determine supplier-side VAT-payer treatment."},"receiverStreet":{"type":"string","example":"Hlavna 1","description":"Receiver street and number. Preferred over parsing receiverAddress."},"receiverCity":{"type":"string","example":"Bratislava","description":"Counterparty city."},"receiverPostalCode":{"type":"string","example":"81101","description":"Counterparty postal code."},"receiverAddress":{"type":"string","example":"Hlavna 1, Bratislava, 81101","description":"Single-line counterparty address. Prefer receiverStreet, receiverCity and receiverPostalCode when the ERP has split address fields."},"receiverCountry":{"type":"string","example":"SK","default":"SK","description":"Counterparty country as ISO 3166-1 alpha-2. Defaults to SK."},"supplierName":{"type":"string","example":"Dodavatel s.r.o.","description":"Self-billing alias for receiverName (supplier). Required for self_billing/self_billing_credit_note when receiverName is omitted."},"supplierIco":{"type":"string","example":"50123456","description":"Self-billing alias for receiverIco."},"supplierDic":{"type":"string","example":"2123038963","description":"Self-billing alias for receiverDic."},"supplierIcDph":{"type":"string","example":"SK2123038963","description":"Self-billing alias for receiverIcDph. Used for supplier-side VAT payer logic."},"supplierStreet":{"type":"string","example":"Priemyselna 8","description":"Self-billing alias for receiverStreet."},"supplierCity":{"type":"string","example":"Zilina","description":"Self-billing alias for receiverCity."},"supplierPostalCode":{"type":"string","example":"01001","description":"Self-billing alias for receiverPostalCode."},"supplierAddress":{"type":"string","example":"Priemyselna 8, Zilina, 01001","description":"Self-billing alias for receiverAddress."},"supplierCountry":{"type":"string","example":"SK","default":"SK","description":"Self-billing alias for receiverCountry."},"prepaidAmount":{"type":"number","minimum":0,"example":123,"description":"Amount paid in advance (BT-113). Emitted as LegalMonetaryTotal/PrepaidAmount and reduces PayableAmount. Do not combine with items[].lineType=advance_deduction."},"prepayments":{"type":"array","minItems":1,"description":"Structured settled prepayments on the final invoice. The API sums prepayments[].amountWithVat into prepaidAmount, reduces PayableAmount, and preserves advance/tax references in the UBL note. It does not create a separate UBL tax breakdown for the prepayment; tax subtotals still come from invoice lines. Do not combine with items[].lineType=advance_deduction.","items":{"$ref":"#/components/schemas/Prepayment"}},"items":{"type":"array","minItems":1,"maxItems":999,"description":"Billing lines. Between 1 and 999 entries are accepted.","items":{"$ref":"#/components/schemas/LineItem"}},"attachments":{"type":"array","maxItems":20,"description":"Invoice supporting documents (Peppol BG-24), embedded in UBL as base64 through AdditionalDocumentReference / EmbeddedDocumentBinaryObject. Maximum 20 files, 10 MB decoded per file, and 15 MB decoded total.","items":{"$ref":"#/components/schemas/DocumentAttachment"}}}},"SendDocumentXmlRequest":{"type":"object","required":["receiverPeppolId","xml"],"description":"XML mode — poskytnute UBL XML sa odosle priamo v JSON poli xml. Pouzite ho ako expert fallback pre hotovy Peppol UBL alebo specifika mimo JSON line-item mode.","properties":{"processId":{"type":"string","description":"Peppol process URN. Accepts the bare URN or the cenbii-procid-ubl:: prefixed form. For profile 02 use urn:peppol:bis:billing_with_response; it must match the UBL ProfileID."},"receiverPeppolId":{"type":"string","example":"0245:12345678"},"xml":{"type":"string","description":"Kompletne UBL XML (Invoice alebo CreditNote).","example":"<?xml version=\"1.0\" encoding=\"UTF-8\"?><Invoice>...</Invoice>"}}},"SendDocumentResponse":{"type":"object","properties":{"documentId":{"type":"string","example":"clx1234abcdef","description":"Interne ID dokumentu"},"submissionId":{"type":"string","example":"clx1234abcdef","description":"Storecove-style alias for documentId. Use this as the submission handle if your integration models sends as submissions."},"messageId":{"type":"string","example":"msg-uuid-here","description":"Peppol messageId"},"status":{"type":"string","example":"SENT","description":"Current document lifecycle status. The first successful call normally returns `SENT`; an HTTP 200 idempotent replay returns the latest persisted status such as `SENT`, `DELIVERED`, or `REJECTED`. `SENT_DB_PENDING` = HTTP 202 (delivered via Peppol but local DB write failed; reconciled by the post-send cron)."},"duplicate":{"type":"boolean","description":"True only for HTTP 200 idempotent replay responses.","example":true},"payloadSha256":{"type":"string","example":"a1b2c3d4e5f60718...","description":"Lowercase-hex SHA-256 of the canonical UBL XML bytes that were placed on the AS4 wire. Receivers can verify the payload they received off Peppol matches what we logged on send. Only present in `SENT` (201) responses; absent in `SENT_DB_PENDING` (202) because the DB persist that captures it failed."},"warning":{"type":"string","description":"Human-readable explanation when `status=SENT_DB_PENDING` — describes the partial-failure mode and what reconciliation will do.","example":"Document delivered via Peppol but local status update failed — will be reconciled automatically"},"links":{"$ref":"#/components/schemas/SendDocumentLinks"}}},"UblValidationError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","rule"],"properties":{"code":{"type":"string","enum":["UBL_VALIDATION_ERROR"]},"message":{"type":"string"},"rule":{"type":"string","enum":["BR-02","BR-05","BR-06","BR-11","BR-16","BT-1","PEPPOL-R008"]},"requestId":{"type":"string"}}}}},"BatchSendRequest":{"type":"object","required":["items"],"properties":{"items":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/BatchSendItem"}}}},"BatchSendResponse":{"type":"object","properties":{"total":{"type":"integer","example":50},"succeeded":{"type":"integer","example":48},"failed":{"type":"integer","example":2},"results":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","description":"0-based position in the input items[]"},"status":{"type":"integer","description":"HTTP status of the underlying single send (201, 422, 502, ...)"},"result":{"description":"Full response body from the underlying call (SendDocumentResponse or ErrorResponse)"}}}}}},"PreflightResponse":{"type":"object","description":"Pre-flight lookup. Three booleans use tri-state (true|false|null) — null means 'unable to determine' (e.g., SMP timeout, no doctype filter specified).","properties":{"receiverPeppolId":{"type":"string","example":"0245:12345678"},"recipientAcceptsDocumentType":{"type":"boolean","nullable":true,"description":"Tri-state: true = doctype in SMP, false = not advertised, null = no documentType probed or lookup inconclusive."},"validationPassed":{"type":"boolean","nullable":true,"description":"Tri-state: true = schematron clean, false = errors, null = skipped (no UBL payload to validate)."},"canSend":{"type":"boolean","nullable":true,"description":"Overall verdict. false blocks the send, null = caller should still attempt (non-blocking warning)."},"warnings":{"type":"array","items":{"type":"string"}},"errors":{"type":"array","items":{"type":"string"}}}},"InboxListResponse":{"type":"object","properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/DocumentResponse"}},"total":{"type":"integer","example":42},"limit":{"type":"integer","example":20},"offset":{"type":"integer","example":0},"nextCursor":{"type":"string","nullable":true,"description":"Opaque cursor to fetch the next page. null when no more results.","example":"eyJpZCI6ImNseDlhYmMxMjMifQ=="}}},"InboxDocumentDetailResponse":{"type":"object","description":"Inbox document detail. `document` and `payload` are siblings (payload is NOT nested inside document). `document` matches the normalized shape from `lib/api/format.ts#formatInvoice` — supplier/customer are nested PartyResponse objects (supplier.peppolId carries the original sender).","properties":{"document":{"$ref":"#/components/schemas/DocumentResponse"},"payload":{"type":"string","nullable":true,"description":"UBL XML content (null if not yet retrieved from storage). Starts with `<?xml...?>`."}}},"AcknowledgeResponse":{"type":"object","required":["documentId","status","clientAckedAt","acknowledgedAt","idempotent"],"properties":{"documentId":{"type":"string"},"status":{"type":"string","enum":["ACKNOWLEDGED"]},"clientAckedAt":{"type":"string","format":"date-time","description":"Cas prveho lokalneho potvrdenia spracovania. Pri idempotentnom opakovani sa nemeni."},"acknowledgedAt":{"type":"string","format":"date-time","deprecated":true,"description":"Spatne kompatibilny alias pola clientAckedAt."},"idempotent":{"type":"boolean","description":"True, ak uz bolo spracovanie dokumentu zaznamenane skor."}}},"CrossFirmInboxResponse":{"type":"object","properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/CrossFirmInboxDocument"}},"total":{"type":"integer","example":120},"limit":{"type":"integer","example":50},"offset":{"type":"integer","example":0}}},"OutboxListResponse":{"type":"object","properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/DocumentResponse"}},"total":{"type":"integer"},"offset":{"type":"integer"},"limit":{"type":"integer"}}},"DocumentResponse":{"type":"object","properties":{"process_id":{"type":"string","nullable":true,"description":"Canonical bare Peppol process URN. Historical null values mean the legacy profile 01."},"id":{"type":"string"},"number":{"type":"string","example":"FAK-2026-0001"},"status":{"type":"string","example":"received"},"direction":{"type":"string","enum":["inbound","outbound"]},"docType":{"type":"string","example":"invoice"},"issueDate":{"type":"string","format":"date-time"},"dueDate":{"type":"string","format":"date-time","nullable":true},"currency":{"type":"string","example":"EUR"},"supplier":{"$ref":"#/components/schemas/PartyResponse"},"customer":{"$ref":"#/components/schemas/PartyResponse"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/LineItemResponse"}},"totals":{"type":"object","properties":{"withoutVat":{"type":"number"},"vat":{"type":"number"},"withVat":{"type":"number"}}},"peppolMessageId":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"DocumentStatusResponse":{"type":"object","description":"Stav dokumentu z pohľadu volajúceho — `direction` rozlišuje, či ide o **inbound** riadok (prijímateľ) alebo **outbound** riadok (odosielateľ). To isté Peppol message ID môže existovať na oboch stranách (prijímateľ aj odosielateľ majú vlastný riadok), ale ich timestampy a stavy sú **nezávislé**:\n\n- `deliveredAt` a `acknowledgedAt` na **inbound** riadku nastavuje prijímateľ cez `POST /documents/{id}/mark` resp. `POST /documents/inbox/{id}/acknowledge`. Tieto signály sú **lokálne** — Peppol BIS Billing 3.0 pre ne nemá ekvivalentnú správu, takže sa neposielajú odosielateľovi.\n- `acknowledgedAt` na **outbound** riadku sa vyplní iba vtedy, keď cez Peppol AS4 dorazí Invoice Response (kódy AP / AB / RE / …) — to je sieťový signál vygenerovaný cez `POST /documents/{id}/respond`.\n- `deliveredAt` na **outbound** riadku sa nikdy nepropaguje z prijímateľa. Ak odosielateľ potrebuje vidieť, že prijímateľ doručil/spracoval dokument, prijímateľ musí volať `/respond` s vhodným kódom (`AP` = accepted, `IP` = in process, `RE` = rejected).","properties":{"id":{"type":"string"},"status":{"type":"string","example":"DELIVERED"},"documentType":{"type":"string","nullable":true,"example":"invoice"},"direction":{"type":"string","enum":["inbound","outbound"],"description":"`inbound` = my sme prijímateľ (faktúru sme dostali). `outbound` = my sme odosielateľ. Určuje sémantiku timestampov: kto čo nastavuje a kedy."},"senderPeppolId":{"type":"string","nullable":true},"receiverPeppolId":{"type":"string","nullable":true},"statusHistory":{"type":"array","items":{"$ref":"#/components/schemas/StatusHistoryEntry"}},"validationResult":{"nullable":true,"description":"`null` on success, or `{ errors: string[] }` when validation failed.","type":"object","properties":{"errors":{"type":"array","items":{"type":"string"}}}},"deliveredAt":{"type":"string","format":"date-time","nullable":true,"description":"Inbound: nastavené prijímateľom cez `/mark state=delivered`. Outbound: vždy `null` — Peppol nemá delivery callback."},"acknowledgedAt":{"type":"string","format":"date-time","nullable":true,"description":"Inbound: nastavené prijímateľom cez `/acknowledge` alebo `/mark state=processed`. Outbound: nastavené v okamihu, keď nám AS4 doručí prijímateľov Invoice Response (cez `/respond`) — pokrýva celú sieťovú latenciu, takže timestamp sa typicky líši od inbound `acknowledgedAt`."},"invoiceResponseStatus":{"type":"string","enum":["AB","IP","UQ","CA","RE","AP","PD"],"nullable":true,"description":"Buyer's last invoice response status (7 UBL-2005 codes)."},"peppolMessageId":{"type":"string","nullable":true,"description":"Identifikátor správy v Peppol/AS4. Rovnaká hodnota ako `as4MessageId` (alias)."},"as4MessageId":{"type":"string","nullable":true,"description":"Identifikátor AS4 správy. Rovnaká hodnota ako `peppolMessageId` — oba aliasy sú v odpovedi pre uľahčenie konzumácie (detail faktúry vracia `peppolMessageId`, AS4-orientovaní integrátori používajú `as4MessageId`)."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"DocumentEventsResponse":{"type":"object","properties":{"process_id":{"type":"string","nullable":true,"description":"Canonical bare Peppol process URN for this document."},"documentId":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/DocumentEvent"}},"pagination":{"type":"object","properties":{"limit":{"type":"integer","example":20},"nextCursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}}}}},"MarkRequest":{"type":"object","required":["state"],"properties":{"state":{"type":"string","enum":["delivered","processed","failed","read"],"description":"delivered = external channel confirmed physical delivery; processed = buyer's ERP consumed the document; failed = terminal failure (blocks retries); read = user opened it (sets `read_at`)."},"note":{"type":"string","description":"Optional audit note appended to statusHistory."}}},"MarkResponse":{"type":"object","properties":{"id":{"type":"string"},"state":{"type":"string","example":"delivered"},"status":{"type":"string","description":"Invoice status after transition"},"deliveredAt":{"type":"string","format":"date-time","nullable":true},"acknowledgedAt":{"type":"string","format":"date-time","nullable":true},"readAt":{"type":"string","format":"date-time","nullable":true}}},"DocumentEvidenceResponse":{"type":"object","properties":{"documentId":{"type":"string"},"as4Receipt":{"type":"object","nullable":true,"description":"AS4 receipt od pristupoveho bodu prijemcu"},"mlrDocument":{"type":"string","nullable":true,"description":"Message Level Response XML"},"invoiceResponse":{"type":"object","nullable":true,"description":"Invoice Response od prijemcu","properties":{"status":{"type":"string","enum":["AB","IP","UQ","CA","RE","AP","PD"],"nullable":true},"document":{"type":"string","description":"Invoice Response UBL XML"}}},"tdd":{"type":"object","nullable":true,"description":"Populated when the document was reported to FS SR as a Tax Data Document.","properties":{"reportedAt":{"type":"string","format":"date-time"},"reported":{"type":"boolean"}}},"sentAt":{"type":"string","format":"date-time","nullable":true},"deliveredAt":{"type":"string","format":"date-time","nullable":true}}},"InvoiceResponsesListResponse":{"type":"object","properties":{"documentId":{"type":"string"},"responses":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceResponseItem"}}}},"InvoiceRespondRequest":{"type":"object","required":["status"],"description":"Request body for POST /documents/{id}/respond. Field is `status` (not `responseCode`). 7 valid values mapping to UBL ApplicationResponse codes.","properties":{"status":{"type":"string","enum":["AB","IP","UQ","CA","RE","AP","PD"],"description":"AB=accepted_billing, IP=in_process, UQ=under_query, CA=conditionally_accepted, RE=rejected, AP=accepted, PD=paid"},"note":{"type":"string","maxLength":500,"example":"Faktura akceptovana","description":"Optional note, truncated to 500 characters."}}},"InvoiceRespondResponse":{"type":"object","description":"Returned with HTTP 200 when the AS4 dispatch succeeded, 202 when the response XML was persisted but dispatch failed and will be retried async.","properties":{"documentId":{"type":"string"},"responseStatus":{"type":"string","enum":["AB","IP","UQ","CA","RE","AP","PD"]},"respondedAt":{"type":"string","format":"date-time"},"peppolMessageId":{"type":"string","nullable":true},"dispatchStatus":{"type":"string","enum":["sent","failed_queued"]},"dispatchError":{"type":"string","description":"Populated only when dispatchStatus=failed_queued (HTTP 202)"}}},"CreateWebhookRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","example":"https://vas-system.sk/webhooks/epostak","description":"HTTPS URL (http rejected, private/loopback/metadata addresses rejected by SSRF filter)"},"events":{"type":"array","items":{"type":"string","enum":["document.created","document.sent","document.received","document.validated","document.delivered","document.rejected","document.response_received"]},"description":"Subscribed events. If omitted, subscribes to all 7.","example":["document.received","document.sent"]}}},"WebhookDetailResponse":{"allOf":[{"$ref":"#/components/schemas/WebhookResponse"},{"type":"object","properties":{"secret":{"type":"string","description":"HMAC-SHA256 signing secret (vrateny iba pri vytvoreni)","example":"a3f8...hex64chars"}}}]},"WebhookListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookResponse"}}}},"WebhookWithDeliveriesResponse":{"allOf":[{"$ref":"#/components/schemas/WebhookResponse"},{"type":"object","properties":{"deliveries":{"type":"array","description":"Poslednych 20 doruceni","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}]},"UpdateWebhookRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["document.created","document.sent","document.received","document.validated","document.delivered","document.rejected","document.response_received"]}},"isActive":{"type":"boolean"}}},"WebhookResponse":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"failedAttempts":{"type":"integer","description":"Consecutive failure counter. Webhooks auto-disable after 10 consecutive failures.","example":0},"createdAt":{"type":"string","format":"date-time"}}},"WebhookTestResponse":{"type":"object","properties":{"success":{"type":"boolean"},"statusCode":{"type":"integer","nullable":true,"example":200},"responseTime":{"type":"integer","description":"Elapsed milliseconds end-to-end.","example":142},"webhookId":{"type":"string","description":"Synthetic `whk_test_*` ID used in the delivery headers."},"event":{"type":"string","example":"document.sent"},"requested":{"type":"integer","description":"Requested synthetic webhook POST count.","example":30000},"sent":{"type":"integer","description":"Synthetic webhook POSTs attempted.","example":30000},"succeeded":{"type":"integer","description":"Receiver responses with 2xx status.","example":29980},"failed":{"type":"integer","description":"Non-2xx responses or request errors.","example":20},"concurrency":{"type":"integer","description":"Internal concurrent outbound request cap used by the test runner.","example":250},"statusCodes":{"type":"object","additionalProperties":{"type":"integer"},"description":"Counts grouped by receiver HTTP status code.","example":{"200":29980,"500":20}},"error":{"type":"string","nullable":true,"description":"Populated when success=false."}}},"DeliveriesResponse":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryDetail"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"WebhookDeliveryDetail":{"type":"object","properties":{"id":{"type":"string"},"webhookId":{"type":"string"},"event":{"type":"string"},"status":{"type":"string","enum":["PENDING","SUCCESS","FAILED","RETRYING"]},"attempts":{"type":"integer"},"responseStatus":{"type":"integer","nullable":true},"responseBody":{"type":"string","nullable":true,"description":"First 200 chars of the receiver's response body (or error message). **Only present when the request included `?includeResponseBody=true` or `?include=responseBody`.** Omitted by default to avoid leaking content from receivers that echo sensitive data."},"lastAttemptAt":{"type":"string","format":"date-time","nullable":true},"nextRetryAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"WebhookRotateSecretResponse":{"type":"object","properties":{"id":{"type":"string"},"secret":{"type":"string","description":"New 64-char hex HMAC secret. Shown once.","example":"a3f8...hex64chars"},"message":{"type":"string","example":"Secret rotated. Save it — it will not be shown again. The previous secret is now invalid."}}},"CrossFirmWebhookQueueResponse":{"type":"object","required":["items","has_more"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CrossFirmWebhookEvent"}},"has_more":{"type":"boolean","description":"True when more unacknowledged events exist beyond this page"}}},"BatchAckWebhookRequest":{"type":"object","required":["event_ids"],"properties":{"event_ids":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":1000,"example":["uuid-1","uuid-2"]}}},"BatchAckWebhookResponse":{"type":"object","properties":{"acknowledged":{"type":"integer","example":42}}},"SmpLookupResponse":{"type":"object","properties":{"peppolId":{"type":"string","example":"0245:12345678"},"name":{"type":"string","nullable":true,"example":"Moja firma s.r.o."},"country":{"type":"string","nullable":true,"example":"SK"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/SmpParticipantCapability"}}}},"ParticipantsBatchRequest":{"type":"object","required":["participants"],"properties":{"participants":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","required":["scheme","identifier"],"properties":{"scheme":{"type":"string","example":"0245"},"identifier":{"type":"string","example":"12345678"}}}}}},"ParticipantsBatchResponse":{"type":"object","properties":{"total":{"type":"integer","example":42},"found":{"type":"integer","example":38},"notFound":{"type":"integer","example":4},"results":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"participant":{"type":"object","properties":{"scheme":{"type":"string"},"identifier":{"type":"string"},"id":{"type":"string"}}},"found":{"type":"boolean"},"accessPoint":{"type":"object","nullable":true,"description":"Receiver's Peppol AP endpoint. null when found=false.","properties":{"url":{"type":"string","example":"https://ap.epostak.sk/as4"},"transportProfile":{"type":"string","example":"peppol-transport-as4-v2_0"}}},"internal":{"type":"boolean"},"supportedDocumentTypes":{"type":"array","items":{"type":"string"},"nullable":true},"source":{"type":"string","nullable":true},"error":{"type":"string","nullable":true,"description":"Invalid scheme/identifier format (per-item)"}}}}}},"CapabilitiesRequest":{"type":"object","required":["participant"],"properties":{"participant":{"type":"object","required":["scheme","identifier"],"properties":{"scheme":{"type":"string","example":"0245","description":"4-digit ISO 6523 ICD scheme (SK = 0245)"},"identifier":{"type":"string","example":"2122701339"}}},"documentType":{"type":"string","description":"BIS 3.0 document type ID. Defaults to Peppol BIS Billing 3.0 Invoice when omitted.","example":"urn:cen.eu:en16931:2017"},"documentTypes":{"type":"array","minItems":1,"maxItems":20,"description":"Optional batch probe. When supplied, each document type is checked with the same participant/processId and the response includes capabilities[] and matchedDocumentTypes[].","items":{"type":"string"}},"processId":{"type":"string","description":"Optional BIS 3.0 process ID filter."}}},"CapabilitiesResponse":{"type":"object","properties":{"found":{"type":"boolean"},"accepts":{"type":"boolean","description":"Receiver accepts the probed documentType/processId. Always `false` when `found=false`."},"reason":{"type":"string","description":"Populated when found=false.","example":"Participant not registered in Peppol network"},"participant":{"type":"object","properties":{"scheme":{"type":"string"},"identifier":{"type":"string"},"id":{"type":"string","example":"0245:2122701339"}}},"accessPoint":{"type":"object","nullable":true,"description":"Receiver's Peppol AP endpoint. null when found=false.","properties":{"url":{"type":"string","example":"https://ap.epostak.sk/as4"},"transportProfile":{"type":"string","example":"peppol-transport-as4-v2_0"}}},"internal":{"type":"boolean","description":"Receiver is hosted on this AP"},"supportedDocumentTypes":{"type":"array","items":{"type":"string"}},"matchedDocumentType":{"type":"string","nullable":true,"description":"The probed document type when accepted, otherwise `null`."},"matchedDocumentTypes":{"type":"array","description":"Document type URNs accepted among documentTypes[]. Present for batch probes.","items":{"type":"string"}},"capabilities":{"type":"array","description":"Per-document-type probe results. Present for batch probes.","items":{"$ref":"#/components/schemas/CapabilityCheckResult"}},"capability":{"$ref":"#/components/schemas/CapabilityCheckResult"},"source":{"type":"string","nullable":true,"description":"Lookup cache origin (e.g. `sml`, `cache`, `internal`)"}}},"PeppolDirectorySearchResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/PeppolDirectoryEntry"}},"total":{"type":"integer","example":42},"page":{"type":"integer","example":1},"page_size":{"type":"integer","example":20}}},"CompanyLookupResponse":{"type":"object","description":"Slovenská firma podľa IČO. Dáta pochádzajú z denného exportu Finančnej správy SR (`fs_tax_subjects` + `fs_vat_violations`). 200 odpoveď znamená, že IČO je v exporte FS — buď ako aktívny subjekt (`active: true`), alebo ako deaktivovaný (`active: false`, vyplnený `cancelled_at`). Skutočne neznáme IČO vracia 404.","properties":{"name":{"type":"string","example":"Moja firma s.r.o."},"tax_id_1":{"type":"string","description":"IČO (8 číslic, padded zľava nulami).","example":"12345678"},"tax_id_2":{"type":"string","nullable":true,"description":"DIČ.","example":"2020123456"},"tax_id_3":{"type":"string","nullable":true,"description":"IČ DPH (`SK<dic>` ak je platca).","example":"SK2020123456"},"address_street":{"type":"string","nullable":true},"address_city":{"type":"string","nullable":true},"address_zip":{"type":"string","nullable":true},"address_country":{"type":"string","example":"SK"},"legal_form":{"type":"string","nullable":true,"description":"Klasifikácia odvodená iba z názvu subjektu vo feede Finančnej správy (`NAZOV_DS`). Vracia sa len pri explicitnom signáli v názve, napr. `s.r.o.`, `a.s.`, `o.z.`, `združenie`, `pozemkové spoločenstvo`, `nadácia`; neznáme prípady sú `null`, nie hádaná `živnosť`.","enum":["s.r.o.","a.s.","j.s.a.","k.s.","v.o.s.","družstvo","š.p.","n.o.","n.f.","o.z.","združenie","pozemkové spoločenstvo","spoločenstvo vlastníkov","nadácia","cirkev","komora"]},"legal_form_source":{"type":"string","nullable":true,"description":"Zdroj klasifikácie právnej formy. `fs_name` znamená explicitný regex match v názve z Finančnej správy; `null` znamená, že právnu formu nevieme z FS dát určiť.","enum":["fs_name"]},"legal_form_status":{"type":"string","description":"`classified` keď `legal_form` vznikol z explicitného FS name matchu; `unknown` keď sa právna forma nedala spoľahlivo určiť z FS dát.","enum":["classified","unknown"]},"vat_reg_type":{"type":"string","nullable":true,"description":"§-paragraf zákona č. 222/2004 Z.z. o DPH, podľa ktorého je subjekt registrovaný. Pozri `vat_reg_type_description` pre slovenský popis.","enum":["§4","§4b","§5","§7","§7a"]},"vat_reg_type_description":{"type":"string","nullable":true,"description":"Slovenský popis hodnoty `vat_reg_type`."},"dph_reg_from":{"type":"string","format":"date","nullable":true,"description":"Dátum registrácie za platiteľa DPH (`PLAT_DPH_OD` z FS feedu)."},"is_vat_payer":{"type":"boolean","description":"Odvodený flag. `true` keď: subjekt je `active`, má `dph_reg_from` a žiadna ds_dphv deregistrácia neprekrýva registráciu. Pre presnú interpretáciu zákazníckeho stavu DPH stále preferujte vlastnú kontrolu nad `vat_violations` + `dph_reg_from`."},"active":{"type":"boolean","description":"`true` keď subjekt bol v poslednom dennom dumpe FS. `false` znamená že FS subjekt vyradila → typicky zaniknutá / zrušená firma.","default":true},"cancelled_at":{"type":"string","format":"date","nullable":true,"description":"Dátum, kedy bol subjekt naposledy videný v FS dumpe pred deaktiváciou. Vyplnené iba ak `active: false`."},"vat_violations":{"type":"array","description":"Históriai aktuálne sankcie DPH. `ds_dphv` = deregistrácia za porušenie zákona o DPH (historický KYC indikátor). `ds_dphz` = aktuálne sankcionovaný platca DPH (otvorený dlh / porušenie). Prázdne pole = subjekt v sankčných zoznamoch FS nie je.","items":{"type":"object","properties":{"source":{"type":"string","enum":["ds_dphv","ds_dphz"]},"year_violation":{"type":"integer","nullable":true},"deletion_date":{"type":"string","format":"date","nullable":true},"publication_date":{"type":"string","format":"date","nullable":true}}}}}},"WhiteLabelCustomerListResponse":{"type":"object","additionalProperties":false,"required":["customers","hasMore"],"properties":{"customers":{"type":"array","items":{"$ref":"#/components/schemas/WhiteLabelCustomer"}},"nextCursor":{"type":"string"},"hasMore":{"type":"boolean"}}},"WhiteLabelCustomerCreateRequest":{"type":"object","additionalProperties":false,"required":["customerRef","relationship","country","contactEmail","customerAuthorization"],"oneOf":[{"required":["companyId"]},{"required":["taxId"]},{"required":["vatId"]}],"properties":{"customerRef":{"type":"string","minLength":1,"maxLength":128,"description":"Stable customer identifier from the integrator system."},"relationship":{"type":"string","enum":["represented"]},"country":{"type":"string","pattern":"^[A-Z]{2}$","example":"SK"},"companyId":{"type":"string","maxLength":64,"description":"Company registration identifier; IČO for Slovak companies."},"taxId":{"type":"string","maxLength":64,"description":"Tax identifier; DIČ for Slovak companies."},"vatId":{"type":"string","maxLength":64,"description":"VAT identifier; IČ DPH for Slovak companies."},"contactEmail":{"type":"string","format":"email","maxLength":320},"returnUrl":{"type":"string","format":"uri","maxLength":2048,"description":"Optional HTTPS URL without embedded credentials."},"customerAuthorization":{"type":"object","additionalProperties":false,"required":["confirmed","evidenceReference"],"properties":{"confirmed":{"type":"boolean","enum":[true],"description":"Confirms that the integrator holds a separate customer mandate."},"evidenceReference":{"type":"string","minLength":1,"maxLength":255,"description":"Integrator-side reference to the auditable mandate evidence."}}}}},"WhiteLabelCustomer":{"type":"object","additionalProperties":false,"required":["id","firmId","customerRef","relationship","country","status","policy","version","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"Managed customer resource identifier."},"firmId":{"type":"string","format":"uuid","description":"Firm tenant identifier to use as X-Firm-Id on subsequent firm-scoped Enterprise API calls."},"customerRef":{"type":"string"},"relationship":{"type":"string","enum":["represented"]},"name":{"type":"string"},"country":{"type":"string","pattern":"^[A-Z]{2}$"},"companyId":{"type":"string"},"taxId":{"type":"string"},"vatId":{"type":"string"},"status":{"type":"string","enum":["action_required","activating","active","suspended","blocked"]},"activation":{"type":"object","required":["url","expiresAt"],"properties":{"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"}}},"nextAction":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"url":{"type":"string","format":"uri"}}},"policy":{"type":"object","additionalProperties":false,"required":["sendMode","ublHandling","ocrAutoSend","attachSourceFile","locale","version"],"properties":{"sendMode":{"type":"string","enum":["automatic","manual"]},"ublHandling":{"type":"string","enum":["strict","normalize"]},"ocrAutoSend":{"type":"boolean"},"attachSourceFile":{"type":"string","enum":["never","when_ocr","always"]},"locale":{"type":"string","enum":["sk","en"]},"version":{"type":"integer","minimum":1}}},"version":{"type":"integer","minimum":1},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WhiteLabelParticipantList":{"type":"object","additionalProperties":false,"required":["participants","nextCursor"],"properties":{"participants":{"type":"array","items":{"$ref":"#/components/schemas/WhiteLabelParticipant"}},"nextCursor":{"type":"string","nullable":true}}},"WhiteLabelParticipantRegistrationRequest":{"type":"object","additionalProperties":false,"required":["customerRef","dic","companyEmail","verificationToken"],"properties":{"customerRef":{"type":"string","minLength":1,"maxLength":128},"dic":{"type":"string","pattern":"^[0-9]{10}$"},"companyEmail":{"type":"string","format":"email","maxLength":320},"verificationToken":{"type":"string","minLength":1,"maxLength":8192,"writeOnly":true,"description":"Token received by the intermediary from the signed FS SR provider webhook. Never log it."}}},"WhiteLabelParticipantOperation":{"type":"object","additionalProperties":false,"required":["id","operationType","status","customerRef","dic","peppolId","legalName","companyEmail","firmId","participantId","reviewRequired","error","createdAt","completedAt"],"properties":{"id":{"type":"string","format":"uuid"},"operationType":{"type":"string","enum":["registration","migration_in","migration_out"]},"status":{"type":"string","enum":["processing","smp_succeeded","succeeded","rejected","manual_review","released"]},"customerRef":{"type":"string"},"dic":{"type":"string","pattern":"^[0-9]{10}$"},"peppolId":{"type":"string","example":"0245:2020123456"},"legalName":{"type":"string"},"companyEmail":{"type":"string","format":"email","nullable":true},"firmId":{"type":"string","format":"uuid","nullable":true},"participantId":{"type":"string","format":"uuid","nullable":true},"reviewRequired":{"type":"boolean"},"error":{"type":"object","nullable":true,"required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"WhiteLabelParticipantMigrationRequest":{"type":"object","additionalProperties":false,"required":["customerRef","dic","companyEmail","migrationCode"],"properties":{"customerRef":{"type":"string","minLength":1,"maxLength":128},"dic":{"type":"string","pattern":"^[0-9]{10}$"},"companyEmail":{"type":"string","format":"email","maxLength":320},"migrationCode":{"type":"string","minLength":1,"maxLength":4096,"writeOnly":true,"description":"SMP migration code from the current provider. Never log it."}}},"WhiteLabelParticipant":{"type":"object","additionalProperties":false,"required":["id","customerRef","firmId","operationId","legalName","ico","dic","icDph","peppolId","status","authorizationSource","endpointProfile","managedSince"],"properties":{"id":{"type":"string","format":"uuid"},"customerRef":{"type":"string"},"firmId":{"type":"string","format":"uuid"},"operationId":{"type":"string","format":"uuid"},"legalName":{"type":"string"},"ico":{"type":"string","nullable":true},"dic":{"type":"string"},"icDph":{"type":"string","nullable":true},"peppolId":{"type":"string"},"status":{"type":"string"},"authorizationSource":{"type":"string","enum":["fs_verification_token","smp_migration_code"]},"endpointProfile":{"type":"string","enum":["managed_by_epostak"],"description":"The SMP endpoint profile is selected by ePošťák for the environment and cannot be changed by the integrator."},"managedSince":{"type":"string","format":"date-time"}}},"WhiteLabelMigrationCodeResponse":{"type":"object","additionalProperties":false,"required":["operation","migrationCode"],"properties":{"operation":{"$ref":"#/components/schemas/WhiteLabelParticipantOperation"},"migrationCode":{"type":"string","nullable":true,"description":"Returned from SMP only while available. ePošťák does not store this value in readable form."}}},"FirmsListResponse":{"type":"object","properties":{"firms":{"type":"array","items":{"$ref":"#/components/schemas/FirmSummary"}}}},"FirmDetailResponse":{"allOf":[{"$ref":"#/components/schemas/FirmSummary"},{"type":"object","properties":{"dic":{"type":"string","nullable":true},"icDph":{"type":"string","nullable":true},"address":{"type":"object","properties":{"street":{"type":"string"},"city":{"type":"string"},"zip":{"type":"string"},"country":{"type":"string"}}},"peppolIdentifiers":{"type":"array","items":{"type":"object","properties":{"scheme":{"type":"string"},"identifier":{"type":"string"}}}},"createdAt":{"type":"string","format":"date-time"}}}]},"PeppolIdentifierResponse":{"type":"object","properties":{"peppolId":{"type":"string","example":"0245:12345678"},"scheme":{"type":"string","example":"0245"},"identifier":{"type":"string","example":"12345678"},"registeredAt":{"type":"string","format":"date-time"}}},"AssignFirmRequest":{"type":"object","anyOf":[{"required":["dic"]},{"required":["ico"]}],"properties":{"dic":{"type":"string","minLength":10,"maxLength":10,"pattern":"^\\d{10}$","example":"0000000001","description":"10-digit Slovak tax identifier (DIČ), preferred for PFS/SMP and Peppol 0245:DIČ"},"ico":{"type":"string","minLength":8,"maxLength":8,"pattern":"^\\d{8}$","example":"12345678","description":"8-digit company registration number (IČO), fallback for lookup/backward compatibility"}}},"AssignFirmResponse":{"type":"object","properties":{"firm":{"$ref":"#/components/schemas/FirmSummary"},"status":{"type":"string","example":"active"}}},"BatchAssignFirmsRequest":{"type":"object","anyOf":[{"required":["dics"]},{"required":["icos"]}],"x-totalMaxItems":50,"properties":{"dics":{"type":"array","items":{"type":"string","minLength":10,"maxLength":10,"pattern":"^\\d{10}$"},"minItems":1,"maxItems":50,"example":["0000000001","0000000002"],"description":"Preferred list of DIČ identifiers."},"icos":{"type":"array","items":{"type":"string","minLength":8,"maxLength":8,"pattern":"^\\d{8}$"},"minItems":1,"maxItems":50,"example":["12345678","87654321"],"description":"Fallback list of IČO identifiers for backward compatibility."}}},"BatchAssignFirmsResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/BatchAssignFirmsResultItem"}}}},"StatisticsResponse":{"type":"object","properties":{"period":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}}},"outbound":{"type":"object","properties":{"total":{"type":"integer","example":120},"delivered":{"type":"integer","example":115},"failed":{"type":"integer","example":5}}},"inbound":{"type":"object","properties":{"total":{"type":"integer","example":48},"acknowledged":{"type":"integer","example":40},"pending":{"type":"integer","example":8}}}}},"ReportingSubmissionsResponse":{"type":"object","required":["items","total","limit","offset"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ReportingSubmissionItem"}},"total":{"type":"integer","example":24},"limit":{"type":"integer","example":20},"offset":{"type":"integer","example":0}}},"ValidateResponse":{"type":"object","description":"3-layer validation report. Structure mirrors the internal `validateUBLXml()` return type.","properties":{"valid":{"type":"boolean"},"layers":{"type":"object","properties":{"xsd":{"type":"object","properties":{"passed":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}}}},"en16931":{"type":"object","properties":{"passed":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}}}},"peppol":{"type":"object","properties":{"passed":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}}}}}},"profile":{"type":"string","nullable":true,"description":"Detected BIS profile (Billing, SelfBilling, ...)"}}},"InboundImportRequest":{"type":"object","required":["xml"],"properties":{"xml":{"type":"string","format":"xml","description":"Raw UBL XML. Receiver identity must match the authenticated firm's Peppol ID: AccountingCustomerParty/EndpointID for a standard invoice, AccountingSupplierParty/EndpointID for self-billing."},"source":{"type":"string","example":"email","description":"Optional caller source label, for example email, sftp, manual or migration."},"messageId":{"type":"string","example":"legacy-ap-2026-0001","description":"Optional external audit message ID. Defaults to import:{documentId}. Idempotent replay uses Idempotency-Key, not messageId."},"idempotencyKey":{"type":"string","description":"Optional idempotency key stored on the imported document row. Reusing the same key with the same XML and metadata replays the original document; changing XML or metadata returns 422."},"documentTypeId":{"type":"string","description":"Optional override for the Peppol document type URN. Defaults from the parsed invoice type."},"processId":{"type":"string","description":"Optional override for the Peppol process URN. Defaults from the parsed invoice type."}}},"InboundImportResponse":{"type":"object","required":["documentId","submissionId","status","kind","source","links"],"properties":{"documentId":{"type":"string","format":"uuid"},"submissionId":{"type":"string","format":"uuid","description":"Alias for documentId, matching the outbound submission response shape."},"status":{"type":"string","enum":["RECEIVED"],"example":"RECEIVED"},"kind":{"type":"string","example":"invoice"},"source":{"type":"string","example":"api_import"},"links":{"$ref":"#/components/schemas/InboundImportLinks"}}},"InboundDocumentsListResponse":{"type":"object","required":["documents","next_cursor","has_more"],"properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/InboundDocument"}},"next_cursor":{"type":"string","nullable":true,"description":"Opaque base64url cursor (versioned, v=1). Pass as ?since= on the next request. NULL when no more pages."},"has_more":{"type":"boolean"}}},"InboundDocument":{"type":"object","required":["id","received_at","kind","sender","recipient","document_type","ubl_url","metadata","ack"],"properties":{"id":{"type":"string","format":"uuid"},"received_at":{"type":"string","format":"date-time","description":"When the document was received from Peppol (row insert time is sub-second after AS4 receive)"},"kind":{"type":"string","example":"invoice","description":"Peppol doctype key (invoice, credit_note, self_billing_invoice, etc.)"},"peppol_message_id":{"type":"string","nullable":true,"description":"AS4 Peppol message UUID"},"sender":{"$ref":"#/components/schemas/PeppolParty"},"recipient":{"$ref":"#/components/schemas/PeppolParty"},"document_type":{"type":"string","example":"BIS Billing 3.0 Invoice","description":"Human-readable document type label"},"document_type_id":{"type":"string","nullable":true,"description":"Full Peppol document type URN"},"ubl_url":{"type":"string","format":"uri","description":"Absolute URL of GET /inbound/documents/{id}/ubl"},"metadata":{"type":"object","description":"Whitelisted safe fields extracted from UBL: invoice_number, total_amount, currency, issue_date","additionalProperties":{"type":"string"}},"ack":{"type":"object","required":["acked_at","client_reference"],"properties":{"acked_at":{"type":"string","format":"date-time","nullable":true},"client_reference":{"type":"string","nullable":true,"maxLength":256}}}}},"InboundAckRequest":{"type":"object","properties":{"client_reference":{"type":"string","maxLength":256,"description":"Optional opaque reference stored on the document (your internal document ID, ERP reference, etc.). Latest-ack-wins: calling ack again with a new client_reference overwrites the previous one."}}},"OutboundDocumentsListResponse":{"type":"object","required":["documents","next_cursor","has_more"],"properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/OutboundDocument"}},"next_cursor":{"type":"string","nullable":true,"description":"Opaque union-cursor (u-prefixed base64url, v=1). Tracks last-emitted id per source table (Invoice + PeppolDocument). Pass as ?since=. NULL when no more pages."},"has_more":{"type":"boolean"}}},"OutboundDocument":{"type":"object","required":["id","kind","document_type","sender","recipient","created_at","transport_status","attempt_count","error","ubl_url","attempt_history","metadata"],"properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string","example":"invoice"},"document_type":{"type":"string","example":"BIS Billing 3.0 Invoice"},"document_type_id":{"type":"string","nullable":true},"sender":{"$ref":"#/components/schemas/PeppolParty"},"recipient":{"$ref":"#/components/schemas/PeppolParty"},"created_at":{"type":"string","format":"date-time"},"transport_status":{"type":"string","enum":["queued","sending","sent","delivered","failed","dead"],"description":"AS4 transport view, uniform across billing and non-billing outbound"},"business_status":{"type":"string","description":"Invoice lifecycle status. Present ONLY for Invoice-backed (billing) documents. Key is omitted for non-billing outbound.","example":"sent"},"attempt_count":{"type":"integer","description":"Number of AS4 send attempts so far"},"last_attempt_at":{"type":"string","format":"date-time","nullable":true},"error":{"type":"object","properties":{"message":{"type":"string","nullable":true}}},"peppol_message_id":{"type":"string","nullable":true},"sent_at":{"type":"string","format":"date-time","nullable":true,"description":"AS4-level send timestamp (billing only)"},"delivered_at":{"type":"string","format":"date-time","nullable":true,"description":"AS4 delivery (MDN) timestamp (billing only)"},"ubl_url":{"type":"string","format":"uri"},"attempt_history":{"type":"array","description":"Delivery attempts, newest first. Empty on list endpoint (populated on detail endpoint only).","items":{"$ref":"#/components/schemas/OutboundDocumentAttempt"}},"metadata":{"type":"object","description":"Business metadata (invoice_number, total_amount, currency, issue_date, due_date) — populated only for Invoice-backed rows.","additionalProperties":{"type":"string"}}}},"OutboundEventsListResponse":{"type":"object","required":["events","next_cursor","has_more"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/OutboundEvent"}},"next_cursor":{"type":"string","nullable":true,"description":"Opaque versioned cursor (v=1). Pass as ?since=."},"has_more":{"type":"boolean"}}},"ExtractResponse":{"type":"object","properties":{"extraction":{"type":"object","description":"Extrahovane data z dokumentu"},"direction":{"type":"string","enum":["inbound","outbound"],"description":"For issued invoice PDFs this is outbound. Standard invoices include send_payload instead of treating OCR as an immediate send."},"send_payload":{"type":"object","nullable":true,"description":"Draft JSON body for POST /api/v1/documents/send. Returned for outbound standard-invoice OCR; caller must review it, fill missing fields, and submit it separately. Null for outbound document types outside the JSON send flow."},"send_payload_missing_fields":{"type":"array","items":{"type":"string"},"description":"Fields the caller must fill before POST /api/v1/documents/send, commonly receiverPeppolId."},"send_ready":{"type":"boolean","description":"True when send_payload has the blocking fields needed by /documents/send; review is still required."},"ubl_xml":{"type":"string","description":"Vygenerovane UBL XML z extrahovanych dat. Present for inbound extraction; outbound standard invoices return send_payload for review instead."},"confidence":{"type":"string","enum":["high","medium","low"],"description":"Overall confidence bucket."},"confidence_scores":{"type":"object","description":"Compatibility projection of the document-level OCR confidence (0..1) onto commonly reviewed fields. These values are not independent per-field model scores. Fields: vendor_name, vendor_ico, invoice_number, issue_date, due_date, items, subtotal, vat_total, total, currency, iban, variable_symbol.","additionalProperties":{"type":"number"}},"needs_review":{"type":"boolean","description":"True when human review is still required. Correcting fields does not automatically clear this flag: it remains true while a blocking missing field, deferred or failed validation, low/medium OCR confidence, or high vendor-risk signal remains. Direct /payloads/extract outbound responses are always review-only; /payloads/review can clear that review only after explicit review_decision=approve and no non-bypassable blocker. Use missing_fields and next_action to decide what to do next."},"review_approved":{"type":"boolean","description":"Present on /payloads/review. True only when review_decision=approve was accepted after all non-bypassable blockers cleared."},"ocr_reused":{"type":"boolean","description":"Present on /payloads/review and always true, proving that the correction step reused the supplied extraction instead of invoking OCR again."},"applied_overrides":{"type":"array","items":{"type":"string"},"description":"Names of values from the fields object that were accepted and applied to this extraction. On /payloads/extract fields is multipart JSON; on /payloads/review it is a JSON object. Empty when no corrections were supplied.","example":["vendor_dic","vendor_ic_dph","iban"]},"missing_fields":{"type":"array","description":"Blocking fields that must still be completed. An empty list does not by itself guarantee needs_review=false because validation, confidence, or risk can still require review.","items":{"type":"object","required":["field","label","required","severity","reason","how_to_fix"],"properties":{"field":{"type":"string","example":"vendor_dic"},"label":{"type":"string","example":"DIČ dodávateľa"},"bt":{"type":"string","description":"Optional EN 16931 business-term identifier.","example":"BT-30"},"required":{"type":"boolean"},"severity":{"type":"string","enum":["blocking","review"]},"reason":{"type":"string"},"how_to_fix":{"type":"string"},"accepted_format":{"type":"string"}}}},"field_sources":{"type":"object","description":"Per-field provenance after OCR, firm-profile enrichment, directory lookup, inference, and API overrides.","additionalProperties":{"type":"object","required":["source"],"properties":{"source":{"type":"string","enum":["ocr","api_override","firm_profile","peppol_directory","inferred","missing"]},"value":{"description":"Resolved JSON value. Its type depends on the field and the value may be null when the source is missing."},"confidence":{"type":"number","minimum":0,"maximum":1}}}},"next_action":{"type":"object","required":["type","label","message"],"description":"The next safe integration step after extraction and any supplied corrections.","properties":{"type":{"type":"string","enum":["send_document","complete_fields","review_validation","retry_validation","review_risk","review_and_send"]},"label":{"type":"string"},"message":{"type":"string"},"endpoint":{"type":"string"},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"fields":{"type":"array","items":{"type":"string"}}}},"file_name":{"type":"string","example":"faktura-2026-001.pdf"}}},"SimpleErrorResponse":{"type":"object","description":"Compatibility non-canonical error shape used by a few multipart upload endpoints (e.g. `/extract`). Standard endpoints use `ErrorResponse`.","properties":{"error":{"type":"string","example":"file is required (multipart/form-data field: file)"}}},"ExtractErrorResponse":{"anyOf":[{"type":"object","description":"Structured error for /extract — Gemini extraction failure.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"EXTRACTION_FAILED"},"message":{"type":"string","example":"Extraction failed"},"details":{"type":"string","description":"Gemini error detail"}}}}},{"type":"object","description":"Compatibility plain-string error for /extract — UBL generation failure path.","properties":{"error":{"type":"string","example":"UBL generation failed"},"details":{"type":"string"},"extraction":{"type":"object","description":"Partial extraction payload (so caller can retry with manual edits)"}}}]},"PayloadReviewRequest":{"type":"object","required":["extraction"],"properties":{"extraction":{"type":"object","description":"The exact extraction object returned by /payloads/extract or by a previous /payloads/review response. Provider diagnostics and unknown fields are ignored.","additionalProperties":true},"fields":{"type":"object","description":"All human corrections in one object. Supported keys include supplier and buyer identity, dates, payment data, amounts, items and document_type.","additionalProperties":true,"example":{"buyer_dic":"2020987654","due_date":"2026-08-26","iban":"SK6807200002891987426353"}},"review_decision":{"type":"string","enum":["approve"],"description":"Explicit human approval after checking the corrected result. Approval cannot clear technical, tenant, validation or high-risk blockers."}}},"ParseResponse":{"type":"object","description":"Full normalized invoice payload. `invoice` contains the UBL body in ePostak's canonical JSON shape. `extras` holds BG-24 attachment descriptors, notes, and other UBL-specific fields. `allowances` lists document-level charges/allowances.","properties":{"invoice":{"type":"object","description":"Normalized invoice payload — see `/documents/parse` route implementation for the full field list."},"extras":{"type":"object"},"allowances":{"type":"array","items":{"type":"object"}}}},"ConvertDocumentRequest":{"type":"object","required":["input_format","output_format","document"],"properties":{"input_format":{"type":"string","enum":["json","ubl"],"description":"Format vstupneho dokumentu"},"output_format":{"type":"string","enum":["json","ubl"],"description":"Format vystupneho dokumentu"},"document":{"oneOf":[{"$ref":"#/components/schemas/SendDocumentJsonRequest"},{"type":"string"}],"description":"SendDocumentJsonRequest objekt (pre input_format=json) alebo UBL XML string (pre input_format=ubl)"}}},"ConvertDocumentResponse":{"type":"object","properties":{"output_format":{"type":"string","enum":["json","ubl"]},"document":{"description":"Vysledok konverzie — UBL XML string (pre output_format=ubl) alebo JSON objekt (pre output_format=json)"},"warnings":{"type":"array","items":{"type":"string"}}}},"ValidateDocumentResponse":{"type":"object","properties":{"valid":{"type":"boolean","example":true},"warnings":{"type":"array","items":{"type":"string"},"description":"Upozornenia (nie fatalne chyby)"},"ubl":{"type":"string","nullable":true,"description":"Vygenerovane UBL XML (len pri JSON mode)"}}},"EventsPullResponse":{"type":"object","required":["events","has_more"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookQueueEvent"},"description":"Unacknowledged events returned oldest-first. Acknowledge after local commit to remove them from the queue."},"has_more":{"type":"boolean","description":"True when more unacknowledged events exist beyond this page"}}},"Prepayment":{"type":"object","required":["amountWithVat"],"description":"One settled prepayment on a final invoice. amountWithVat is the only required field and contributes to BT-113 PrepaidAmount. All monetary fields must be finite non-negative numbers and are rounded to two decimals. References, settlement date and VAT details are preserved in the UBL note; it does not create a separate UBL tax breakdown.","properties":{"advanceInvoiceRef":{"type":"string","example":"ZAL-2026-0004","description":"Advance/prepayment invoice reference from the ERP."},"taxDocumentRef":{"type":"string","example":"DDP-2026-0022","description":"Tax document number for the received advance payment."},"settlementDate":{"type":"string","format":"date","example":"2026-02-23","description":"Settlement date in strict YYYY-MM-DD format."},"amountWithoutVat":{"type":"number","minimum":0,"example":1000,"description":"Settled amount without VAT."},"vatAmount":{"type":"number","minimum":0,"example":230,"description":"VAT amount from the settled prepayment."},"amountWithVat":{"type":"number","minimum":0,"example":1230,"description":"Settled amount including VAT. Required and summed into prepaidAmount."},"vatRate":{"type":"number","minimum":0,"example":23,"description":"Non-negative VAT rate of the prepayment. This is descriptive prepayment metadata and is preserved in the UBL note."},"vatCategoryCode":{"type":"string","enum":["S","Z","AE","E","K","G","O","L","M"],"example":"S","description":"Optional VAT category of the prepayment. Values are normalized to uppercase and preserved as prepayment metadata."}}},"LineItem":{"type":"object","description":"One JSON billing line. Required fields are description, quantity, unitPrice and vatRate. Standard lines require quantity > 0; advance_deduction lines require quantity < 0 and advanceInvoiceReference. Unknown advanced fields are not mapped into UBL.","required":["description","quantity","unitPrice","vatRate"],"properties":{"description":{"type":"string","minLength":1,"example":"Konzultacne sluzby","description":"Non-empty line name or description."},"quantity":{"type":"number","example":10,"description":"Quantity. Must be greater than zero for a standard line. Must be negative for lineType=advance_deduction; zero is never accepted."},"unit":{"type":"string","example":"HUR","default":"C62","description":"UN/ECE Rec 20 unit code. Use H87 for a piece; C62 is the generic one/unit code. Short aliases are also mapped: ks=H87, kus=H87, piece=H87, pcs=H87, jednotka=C62, unit=C62, one=C62, hod=HUR, den=DAY, mes=MON, kg=KGM, m=MTR, l=LTR, km=KTM. Omitted values default to C62."},"unitPrice":{"type":"number","minimum":0,"example":50,"description":"Net price per unit. Must be a finite non-negative number."},"vatRate":{"type":"number","enum":[0,5,10,19,20,23],"example":23,"description":"VAT rate in percent. Accepted values: 0, 5, 10, 19, 20, 23; this includes historical 20% for older/corrective documents. Z, AE, E, K, G and O categories require 0; S, L and M require a positive rate."},"vatCategoryCode":{"type":"string","enum":["S","Z","AE","E","K","G","O","L","M"],"example":"AE","description":"DPH kategoria BT-151 podla UNCL5305. Ak chyba, odvodi sa zo sadzby: vatRate > 0 = S, vatRate 0 = Z. Pre prenesenie danovej povinnosti pouzite AE."},"vatCategory":{"type":"string","enum":["S","Z","AE","E","K","G","O","L","M"],"example":"AE","description":"Alias for vatCategoryCode."},"vat_category":{"type":"string","enum":["S","Z","AE","E","K","G","O","L","M"],"example":"AE","description":"Snake_case alias for vatCategoryCode."},"taxTreatment":{"type":"string","enum":["standard","zero_rate","reverse_charge_domestic","exempt","intra_community_supply","export","outside_scope"],"example":"reverse_charge_domestic","description":"Higher-level ePostak tax treatment mapped to vatCategoryCode: standard=S, zero_rate=Z, reverse_charge_domestic=AE, exempt=E, intra_community_supply=K, export=G, outside_scope=O. Explicit vatCategoryCode wins when both are present."},"tax_treatment":{"type":"string","enum":["standard","zero_rate","reverse_charge_domestic","exempt","intra_community_supply","export","outside_scope"],"example":"reverse_charge_domestic","description":"Snake_case alias for taxTreatment."},"discount":{"type":"number","minimum":0,"maximum":100,"example":10,"description":"Line discount percentage from 0 to 100. Omitted means 0."},"deliveryDate":{"type":"string","example":"2026-04-01","description":"Line delivery date (BT-134). ISO timestamps are accepted by the route and emitted as date-only in UBL. When line delivery dates represent a summary invoice, they must stay within one calendar month and issueDate must be no later than the 15th day after that month ends."},"lineType":{"type":"string","enum":["standard","advance_deduction"],"default":"standard","example":"advance_deduction","description":"Line type. Use advance_deduction for a negative advance deduction line on the final invoice."},"advanceInvoiceReference":{"type":"string","example":"ZF-2026-001","description":"Advance invoice number. Required when lineType is advance_deduction. Emitted to UBL as AdditionalItemProperty named AdvanceInvoiceNumber."},"customsTariffCode":{"type":"string","pattern":"^\\d{4,10}$","example":"72044910","description":"Customs tariff / combined nomenclature code. Emitted as CommodityClassification/ItemClassificationCode listID=HS; KV DPH A2 uses the first 4 digits as TK."},"commodityClassificationCode":{"type":"string","example":"72044910","description":"Generic item classification code when customsTariffCode is not used. Send together with commodityClassificationListId when the list is not HS."},"commodityClassificationListId":{"type":"string","example":"HS","description":"Classification list identifier from UNTDID 7143. Defaults to HS for customsTariffCode."},"reverseChargeParagraphLetter":{"type":"string","example":"f","description":"Domestic §69(12) paragraph letter for reverse-charge evidence, for example f or g. Emitted as AdditionalItemProperty."},"controlStatementType":{"type":"string","enum":["IO","MT"],"example":"MT","description":"Slovak KV DPH A2 TD value."},"controlStatementQuantity":{"type":"number","minimum":0,"exclusiveMinimum":true,"example":1250,"description":"Positive Slovak KV DPH A2 Mn quantity. If omitted and the unit can be mapped, the absolute line quantity is used."},"controlStatementUnit":{"type":"string","enum":["kg","t","m","ks"],"example":"kg","description":"Slovak KV DPH A2 MJ unit."}}},"DocumentAttachment":{"type":"object","required":["fileName","mimeType","content"],"description":"Invoice attachment encoded as base64 without a data: prefix. The declared MIME type is checked against file magic bytes. Maximum decoded size is 10 MB per file and 15 MB across all attachments.","properties":{"fileName":{"type":"string","minLength":1,"maxLength":255,"example":"invoice-detail.pdf","description":"Non-empty attachment filename."},"mimeType":{"type":"string","enum":["application/pdf","image/png","image/jpeg","text/csv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.oasis.opendocument.spreadsheet"],"example":"application/pdf","description":"Allowed MIME types according to Peppol BR-CL-22. The decoded content must match this MIME type."},"content":{"type":"string","format":"byte","description":"Base64-encoded file content without a data: prefix. Must decode to a non-empty file and may be at most 10 MB after decoding.","example":"JVBERi0xLjQKJeLjz9MKMS..."},"description":{"type":"string","example":"Rozpis odpracovanych hodin","description":"Optional short attachment description shown as supporting-document metadata."}}},"SendDocumentLinks":{"type":"object","description":"Convenience links for the created outbound document submission.","properties":{"document":{"type":"string","example":"/api/v1/documents/clx1234abcdef"},"status":{"type":"string","example":"/api/v1/documents/clx1234abcdef/status"},"events":{"type":"string","example":"/api/v1/documents/clx1234abcdef/events"},"ubl":{"type":"string","example":"/api/v1/documents/clx1234abcdef/ubl"},"evidence":{"type":"string","example":"/api/v1/documents/clx1234abcdef/evidence"},"evidenceBundle":{"type":"string","example":"/api/v1/documents/clx1234abcdef/support-packet"}}},"BatchSendItem":{"type":"object","description":"Same shape as the POST /documents/send body (JSON or XML mode), plus an optional per-item idempotencyKey.","properties":{"idempotencyKey":{"type":"string","description":"Optional per-item idempotency key (propagated as `Idempotency-Key` header on the underlying single send)."}},"additionalProperties":true},"CrossFirmInboxDocument":{"type":"object","properties":{"firm_id":{"type":"string","format":"uuid"},"firm_name":{"type":"string","example":"Example s.r.o."},"id":{"type":"string","format":"uuid"},"number":{"type":"string","example":"FAK-2026-0001"},"status":{"type":"string","enum":["RECEIVED","ACKNOWLEDGED"]},"sender_peppol_id":{"type":"string","example":"0245:99887766"},"sender_name":{"type":"string","example":"Supplier s.r.o."},"amount":{"type":"number","example":1210},"currency":{"type":"string","example":"EUR"},"received_at":{"type":"string","format":"date-time"}}},"PartyResponse":{"type":"object","properties":{"name":{"type":"string","example":"Moja firma s.r.o."},"ico":{"type":"string","example":"12345678"},"dic":{"type":"string","example":"2020123456"},"icDph":{"type":"string","example":"SK2020123456"},"address":{"type":"object","properties":{"street":{"type":"string","example":"Hlavna 1"},"city":{"type":"string","example":"Bratislava"},"zip":{"type":"string","example":"81101"},"country":{"type":"string","example":"SK"}}},"peppolId":{"type":"string","example":"0245:12345678"}}},"LineItemResponse":{"type":"object","properties":{"description":{"type":"string"},"quantity":{"type":"number"},"unit":{"type":"string"},"unitPrice":{"type":"number"},"vatRate":{"type":"number"},"vatCategory":{"type":"string","example":"S"},"lineTotal":{"type":"number"}}},"StatusHistoryEntry":{"type":"object","properties":{"status":{"type":"string","example":"SENT"},"timestamp":{"type":"string","format":"date-time"},"detail":{"type":"string","nullable":true}}},"DocumentEvent":{"type":"object","properties":{"process_id":{"type":"string","nullable":true,"description":"Canonical bare Peppol process URN for this document."},"id":{"type":"string"},"eventType":{"type":"string","example":"document.sent","description":"One of: document.created, document.status_changed, document.approved, document.sent, document.send_failed, document.as4_delivered, document.mlr_received, document.response_received, document.response_sent, document.paid, document.fs_reported."},"actor":{"type":"string","enum":["system","user","api"]},"detail":{"type":"string","nullable":true},"meta":{"description":"Event-specific metadata (peppolMessageId, toStatus, approvedBy, ...)"},"occurredAt":{"type":"string","format":"date-time"}}},"InvoiceResponseItem":{"type":"object","properties":{"id":{"type":"string"},"responseCode":{"type":"string","enum":["AB","IP","UQ","CA","RE","AP","PD"],"description":"AB=Accepted Billing, IP=In Process, UQ=Under Query, CA=Conditionally Accepted, RE=Rejected, AP=Accepted, PD=Paid"},"note":{"type":"string","nullable":true},"senderPeppolId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"webhookId":{"type":"string","description":"Per-attempt delivery ID sent as X-Webhook-Id request header. Different on each retry attempt. Distinct from idempotency_key which is per-logical-event."},"event":{"type":"string","example":"document.received"},"status":{"type":"string","enum":["PENDING","SUCCESS","FAILED","RETRYING"],"example":"SUCCESS","description":"Delivery status (UPPERCASE enum)"},"attempts":{"type":"integer","example":1},"responseStatus":{"type":"integer","nullable":true,"example":200},"createdAt":{"type":"string","format":"date-time"},"idempotency_key":{"type":"string","format":"sha256-hex","description":"Deterministic SHA-256 hex identifying the logical delivery event (per PR #112). Stable across retry attempts — two attempts for the same logical event share the same idempotency_key. Distinct from webhook_id (X-Webhook-Id header), which is per-attempt."}}},"CrossFirmWebhookEvent":{"type":"object","properties":{"event_id":{"type":"string","format":"uuid"},"firm_id":{"type":"string","format":"uuid"},"event":{"type":"string","example":"document.received"},"payload":{"type":"object"},"created_at":{"type":"string","format":"date-time"}}},"SmpParticipantCapability":{"type":"object","properties":{"documentTypeId":{"type":"string"},"processId":{"type":"string"},"transportProfile":{"type":"string","example":"peppol-transport-as4-v2_0"}}},"CapabilityCheckResult":{"type":"object","properties":{"documentTypeId":{"type":"string"},"processId":{"type":"string"},"found":{"type":"boolean"},"accepts":{"type":"boolean"},"routingStatus":{"type":"string","nullable":true},"networkReady":{"type":"boolean"},"accessPoint":{"type":"object","nullable":true},"source":{"type":"string","nullable":true},"certificate":{"type":"object","nullable":true},"supportedDocumentTypes":{"type":"array","items":{"type":"string"}}}},"PeppolDirectoryEntry":{"type":"object","properties":{"peppolId":{"type":"string","example":"0245:12345678"},"name":{"type":"string","example":"Moja firma s.r.o."},"country":{"type":"string","example":"SK"},"registeredAt":{"type":"string","format":"date-time","nullable":true}}},"FirmSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Example s.r.o."},"ico":{"type":"string","example":"12345678"},"dic":{"type":"string","example":"0000000001","nullable":true},"peppol_id":{"type":"string","example":"0245:0000000001","nullable":true},"peppol_status":{"type":"string","enum":["ACTIVE","PENDING","NONE"],"example":"ACTIVE"}}},"BatchAssignFirmsResultItem":{"type":"object","properties":{"ico":{"type":"string","example":"12345678"},"dic":{"type":"string","example":"0000000001","nullable":true},"identifier":{"type":"string","example":"0000000001","nullable":true},"firm":{"$ref":"#/components/schemas/FirmSummary"},"status":{"type":"string","example":"active"},"error":{"type":"string","example":"not_found","nullable":true},"message":{"type":"string","example":"Firm not found","nullable":true},"reason":{"type":"string","enum":["inactive_link","interface_mismatch","invalid_relationship","relationship_not_authorized","insufficient_scope"],"description":"Why an existing firm link does not authorize the Enterprise API assignment."},"required_interface":{"type":"string","enum":["enterprise_api"]},"required_scopes":{"type":"array","items":{"type":"string"}}}},"ReportingSubmissionItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"report_type":{"type":"string","enum":["EUSR","TSR"]},"period":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}}},"status":{"type":"string","enum":["sent","failed","pending","submitting"]},"message_id":{"type":"string","nullable":true,"description":"Peppol AS4 message ID (null if not yet submitted)."},"submitted_at":{"type":"string","format":"date-time","nullable":true},"has_error":{"type":"boolean"}}},"InboundImportLinks":{"type":"object","properties":{"document":{"type":"string","example":"/api/v1/inbound/documents/8e4b8f0e-21d3-4d2a-9c2b-24a3f8a0c111"},"ubl":{"type":"string","example":"/api/v1/inbound/documents/8e4b8f0e-21d3-4d2a-9c2b-24a3f8a0c111/ubl"},"ack":{"type":"string","example":"/api/v1/inbound/documents/8e4b8f0e-21d3-4d2a-9c2b-24a3f8a0c111/ack"}}},"PeppolParty":{"type":"object","properties":{"peppol_id":{"type":"string","nullable":true,"example":"0245:2012345678"},"name":{"type":"string","nullable":true},"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code. Omitted (key absent) when the Peppol scheme is unknown.","example":"SK"}}},"OutboundDocumentAttempt":{"type":"object","properties":{"attempt":{"type":"integer"},"status":{"type":"string"},"http_status":{"type":"integer","nullable":true},"error_message":{"type":"string","nullable":true},"attempted_at":{"type":"string","format":"date-time"}}},"OutboundEvent":{"type":"object","required":["id","document_id","type","occurred_at"],"properties":{"id":{"type":"string","format":"uuid"},"document_id":{"type":"string","format":"uuid","description":"Invoice ID (billing-backed events only in v1)"},"type":{"type":"string","example":"document.delivered","description":"DocumentEvent.eventType value"},"actor":{"type":"string","nullable":true,"description":"Who triggered the event (system, api, user email)"},"detail":{"type":"string","nullable":true},"meta":{"type":"object","nullable":true,"description":"Event-specific metadata object"},"occurred_at":{"type":"string","format":"date-time"}}},"WebhookQueueEvent":{"type":"object","description":"Snake_case keys on `/webhook-queue/all`. The per-firm `/webhook-queue` route returns the same shape.","properties":{"event_id":{"type":"string","format":"uuid","example":"a3d2...-uuid"},"firm_id":{"type":"string","format":"uuid"},"event":{"type":"string","example":"document.received"},"payload":{"type":"object","description":"Event-specific payload"},"created_at":{"type":"string","format":"date-time"}}}},"headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests in the current window","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the rate-limit window resets","schema":{"type":"integer"}}},"parameters":{"WhiteLabelIdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique retry key for this command. Reuse the same key and identical body until a terminal result; never retry an unknown SMP result with a new key.","schema":{"type":"string","minLength":1,"maxLength":255}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"OAuth 2.0 client_credentials JWT access token (15 min TTL).\n\n**Obtain a token:** `POST /api/v1/auth/token` with the `client_id` shown with the key plus `client_secret` (the full `sk_live_*` or `sk_int_*` API key). Response contains `access_token` (JWT) and `refresh_token`.\n\n**Use the JWT:** `Authorization: Bearer eyJhbGciOiJSUzI1NiIs...`\n\n**Two key types:**\n- JWT minted from `sk_live_*` — direct firm access, no X-Firm-Id needed.\n- JWT minted from `sk_int_*` — requires `X-Firm-Id: <UUID>` header to target a specific assigned firm. For cross-firm endpoints (`/documents/inbox/all`, `/webhook-queue/all`, `/firms/assign`) X-Firm-Id is not required.\n\n**Direct API key bearer (Bearer sk_live_… or Bearer sk_int_…) is no longer accepted.**\n\nRate limit: 200 requests per minute per key."},"integratorBearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT access token minted from a `sk_int_*` integrator API key via `POST /api/v1/auth/token`. Cross-firm endpoints require no X-Firm-Id header."}}},"x-epostak-profile":"full","x-epostak-legacy-combined-openapi":"https://epostak.sk/api/openapi.enterprise.json"}