{"openapi":"3.0.0","paths":{"/accounts/bootstrap":{"post":{"description":"Creates an account with a password and returns the initial machine API key. Intended for setup and controlled admin use.","operationId":"AccountsController_bootstrap","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapAccountDto"}}}},"responses":{"201":{"description":"Account created and initial API key returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapAccountResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Bootstrap has already been completed or the account conflicts with existing data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Bootstrap the first account","tags":["Accounts"]}},"/accounts/me":{"get":{"description":"Returns the authenticated account profile, webhook URLs, and API-key status.","operationId":"AccountsController_me","parameters":[],"responses":{"200":{"description":"Authenticated account profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"The authenticated account no longer exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get my account profile","tags":["Accounts"]},"patch":{"description":"Updates account identity fields, webhook delivery URLs, and invoice email preferences for the authenticated account.","operationId":"AccountsController_updateMe","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountDto"}}}},"responses":{"200":{"description":"Updated authenticated account profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Updated account identity conflicts with another account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Update my account profile","tags":["Accounts"]}},"/accounts/me/webhooks/test":{"post":{"description":"Delivers a sample webhook payload to the configured account endpoint for status or inbound-invoice events.","operationId":"AccountsController_testWebhook","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestWebhookDto"}}}},"responses":{"200":{"description":"Webhook test delivery result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestWebhookResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Send a test webhook","tags":["Accounts"]}},"/machine/accounts/me":{"get":{"description":"Machine-to-machine variant of account profile lookup. Authenticate with the `x-api-key` header.","operationId":"MachineAccountsController_getMe","parameters":[],"responses":{"200":{"description":"Account profile owned by the API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Get account profile with an API key","tags":["Accounts"]},"patch":{"description":"Machine-to-machine variant of account profile updates. Authenticate with the `x-api-key` header.","operationId":"MachineAccountsController_updateMe","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountDto"}}}},"responses":{"200":{"description":"Updated account profile owned by the API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Updated account identity conflicts with another account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Update account profile with an API key","tags":["Accounts"]}},"/auth/register":{"post":{"description":"Creates a new business account and returns the account profile plus a password setup URL when available.","operationId":"AuthController_register","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterAccountDto"}}}},"responses":{"201":{"description":"Account registered. In non-deployed environments, the setup URL is included for local testing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"An account with the same email, username, or VAT number already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Register an account","tags":["Authentication"]}},"/auth/password/setup":{"post":{"description":"Exchanges a setup token for a signed-in account session and stores the refresh token in an HTTP-only cookie.","operationId":"AuthController_setupPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordTokenDto"}}}},"responses":{"200":{"description":"Account session created with a bearer access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Password setup token is invalid, expired, or already consumed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Set the initial password","tags":["Authentication"]}},"/auth/password/forgot":{"post":{"description":"Starts the password reset flow for an account email address.","operationId":"AuthController_requestPasswordReset","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestPasswordResetDto"}}}},"responses":{"200":{"description":"Password reset request accepted. Unknown or inactive accounts still receive `ok: true`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequestResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Request a password reset","tags":["Authentication"]}},"/auth/password/reset":{"post":{"description":"Exchanges a reset token for a signed-in account session and stores the refresh token in an HTTP-only cookie.","operationId":"AuthController_resetPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordTokenDto"}}}},"responses":{"200":{"description":"Account session created with a bearer access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Password reset token is invalid, expired, or already consumed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Reset a password","tags":["Authentication"]}},"/auth/email/change":{"patch":{"description":"Checks the current password and sends a one-time confirmation link to the new email address. The current address remains active until confirmation.","operationId":"AuthController_requestEmailChange","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestEmailChangeDto"}}}},"responses":{"200":{"description":"Email change request accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailChangeRequestResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is invalid or the current password is incorrect.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"The new email address is already assigned to another account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Request an account email change","tags":["Authentication"]}},"/auth/email/change/confirm":{"post":{"description":"Consumes a one-time email verification token, updates the primary email and login username, and creates an authenticated session.","operationId":"AuthController_confirmEmailChange","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmEmailChangeDto"}}}},"responses":{"200":{"description":"Email updated and authenticated account session created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"The email confirmation link is invalid, expired, or already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"The new email address is already assigned to another account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Confirm an account email change","tags":["Authentication"]}},"/auth/login":{"post":{"description":"Authenticates an account with username and password, returning a bearer access token.","operationId":"AuthController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"200":{"description":"Account session created with a bearer access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Username or password is invalid, or the account is inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Log in","tags":["Authentication"]}},"/auth/refresh":{"post":{"description":"Uses the refresh token from the request body or the `fttel_refresh` cookie to issue a new access token.","operationId":"AuthController_refresh","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshDto"}}}},"responses":{"200":{"description":"Account session refreshed with a new bearer access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Refresh token is missing, invalid, expired, revoked, or already rotated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Refresh an account session","tags":["Authentication"]}},"/auth/logout":{"post":{"description":"Revokes the current refresh token when present and clears the account refresh cookie.","operationId":"AuthController_logout","parameters":[],"responses":{"200":{"description":"Logout completed and refresh cookie cleared.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Log out","tags":["Authentication"]}},"/auth/api-keys/rotate":{"post":{"description":"Creates a new `x-api-key` credential for machine-to-machine account invoice access.","operationId":"AuthController_rotateApiKey","parameters":[],"responses":{"200":{"description":"New machine API key. Store it securely; it is only returned once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Rotate the machine API key","tags":["Authentication"]}},"/provider/auth/bootstrap":{"post":{"description":"Creates the initial provider/operator user and returns a bearer access token. Intended for controlled setup use.","operationId":"ProviderController_bootstrap","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapProviderDto"}}}},"responses":{"201":{"description":"Provider user created and authenticated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderAuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Provider bootstrap has already been completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Bootstrap a provider user","tags":["Provider"]}},"/provider/auth/login":{"post":{"description":"Authenticates a provider/operator user and stores the refresh token in an HTTP-only cookie.","operationId":"ProviderController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderLoginDto"}}}},"responses":{"200":{"description":"Provider session created with a bearer access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderAuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Username or password is invalid, or the provider user is inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Log in as provider","tags":["Provider"]}},"/provider/auth/refresh":{"post":{"description":"Uses the request body refresh token or the `fttel_provider_refresh` cookie to issue a new provider access token.","operationId":"ProviderController_refresh","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderRefreshDto"}}}},"responses":{"200":{"description":"Provider session refreshed with a new bearer access token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderAuthSessionResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Refresh token is missing, invalid, expired, revoked, or already rotated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"Refresh a provider session","tags":["Provider"]}},"/provider/auth/logout":{"post":{"description":"Revokes the current provider refresh token when present and clears the provider refresh cookie.","operationId":"ProviderController_logout","parameters":[],"responses":{"200":{"description":"Provider logout completed and refresh cookie cleared.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderLogoutResponseDto"}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Log out provider","tags":["Provider"]}},"/provider/accounts":{"get":{"description":"Returns all client accounts visible to provider/operator users, with invoice counts and status summaries.","operationId":"ProviderController_listAccounts","parameters":[],"responses":{"200":{"description":"Client accounts visible to provider users.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProviderAccountSummaryDto"}}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List client accounts","tags":["Provider"]}},"/provider/accounts/{id}":{"get":{"description":"Returns account detail and aggregate invoice status counts for one client account.","operationId":"ProviderController_getAccount","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Client account detail and aggregate invoice status counts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderAccountDetailDto"}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Client account not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a client account","tags":["Provider"]}},"/provider/invoices":{"get":{"description":"Returns paginated invoices across client accounts, optionally filtered by account, direction, status, or counterparty VAT.","operationId":"ProviderController_listInvoices","parameters":[{"name":"accountId","required":false,"in":"query","description":"Filter invoices to one client account.","schema":{"example":"account_123","type":"string"}},{"name":"direction","required":false,"in":"query","description":"Filter by invoice direction.","schema":{"example":"OUTBOUND","type":"string","enum":["INBOUND","OUTBOUND"]}},{"name":"status","required":false,"in":"query","description":"Filter by invoice processing status.","schema":{"example":"SUBMITTED","type":"string","enum":["DRAFT","QUEUED","TAKEN_IN_CHARGE","PROCESSING_ERROR","SUBMITTED","SENT","DISCARDED","NOT_DELIVERED","DELIVERY_IMPOSSIBLE","DELIVERED","RECEIVED","ACCEPTED","REFUSED","REJECTED","DEADLINE_EXPIRED","FAILED"]}},{"name":"counterpartyVat","required":false,"in":"query","description":"Filter by customer or supplier VAT number.","schema":{"example":"12345678901","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of invoices to return.","schema":{"minimum":1,"maximum":100,"default":50,"example":50,"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Number of invoices to skip before returning results.","schema":{"minimum":0,"default":0,"example":0,"type":"number"}}],"responses":{"200":{"description":"Paginated client invoices matching the supplied filters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPaginatedInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List client invoices","tags":["Provider"]}},"/provider/invoice-exports":{"post":{"description":"Returns a provider-wide reusable export for an identical period when available; otherwise queues background generation of one outer ZIP containing a VAT-named ZIP per client.","operationId":"ProviderController_createInvoiceExport","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadProviderPeriodDto"}}}},"responses":{"200":{"description":"An unexpired completed export for the exact period was reused without queueing new work.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderInvoiceExportRequestResponseDto"}}}},"202":{"description":"Persistent export job accepted for background processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderInvoiceExportRequestResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"No downloadable invoice documents exist for the selected period.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Queue a provider invoice period export","tags":["Provider"]},"get":{"operationId":"ProviderController_listInvoiceExports","parameters":[],"responses":{"200":{"description":"The 20 most recent export jobs.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProviderInvoiceExportResponseDto"}}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List recent provider-wide invoice export jobs","tags":["Provider"]}},"/provider/invoice-exports/{id}":{"get":{"operationId":"ProviderController_getInvoiceExport","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderInvoiceExportResponseDto"}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice export not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the current state of an invoice export job","tags":["Provider"]}},"/provider/invoice-exports/{id}/download":{"get":{"operationId":"ProviderController_downloadInvoiceExport","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Completed ZIP-of-ZIPs archive stream.","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice export or its stored archive was not found.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Invoice export is not ready for download.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Download a completed provider invoice export","tags":["Provider"]}},"/provider/invoices/{id}":{"get":{"description":"Returns one client invoice with account summary, stored documents, and received SdI notifications.","operationId":"ProviderController_getInvoice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Client invoice detail visible to provider users.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderInvoiceResponseDto"}}}},"401":{"description":"Provider bearer token is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Client invoice not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a client invoice","tags":["Provider"]}},"/invoice-exports":{"get":{"operationId":"InvoicesController_listInvoiceExports","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AccountInvoiceExportResponseDto"}}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List my recent invoice export jobs","tags":["Invoices"]},"post":{"description":"Queues a persistent account-scoped ZIP export containing every non-discarded invoice matching the supplied filters, including its primary XML, metadata, and linked notification XML documents.","operationId":"InvoicesController_createInvoiceExport","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccountInvoiceExportDto"}}}},"responses":{"202":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInvoiceExportRequestResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Queue an export of my filtered invoices","tags":["Invoices"]}},"/invoice-exports/{id}":{"get":{"operationId":"InvoicesController_getInvoiceExport","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInvoiceExportResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice export not found for the authenticated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get one of my invoice export jobs","tags":["Invoices"]}},"/invoice-exports/{id}/download":{"get":{"operationId":"InvoicesController_downloadInvoiceExport","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/zip":{"schema":{"type":"string","format":"binary"}}},"description":""},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice export or stored archive not found for the authenticated account.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Download one of my completed invoice exports","tags":["Invoices"]}},"/invoices/outbound":{"post":{"description":"Accepts invoice XML or signed `.xml.p7m` content encoded as base64, stores it, and submits it to SdI for the authenticated account.","operationId":"InvoicesController_createOutbound","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOutboundInvoiceDto"}}}},"responses":{"201":{"description":"Invoice stored and submitted, or stored with a submission failure state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOutboundInvoiceResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Invoice sender VAT number is missing or does not match your account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Unable to allocate a unique SdI filename, please retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"422":{"description":"Invoice XML, signed payload extraction, or SdI filename generation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Submit an outbound invoice","tags":["Invoices"]}},"/invoices":{"get":{"description":"Returns paginated invoices owned by the authenticated account, optionally filtered by document date, direction, status, document type, origin, counterparty, or sender filename. Results are ordered by `sortBy` (default `issuedAt`) and `sortOrder` (default `desc`); ties break on `id` in the same direction.","operationId":"InvoicesController_list","parameters":[{"name":"direction","required":false,"in":"query","description":"Filter by invoice direction.","schema":{"example":"OUTBOUND","type":"string","enum":["INBOUND","OUTBOUND"]}},{"name":"status","required":false,"in":"query","description":"Filter by invoice processing status.","schema":{"example":"SUBMITTED","type":"string","enum":["DRAFT","QUEUED","TAKEN_IN_CHARGE","PROCESSING_ERROR","SUBMITTED","SENT","DISCARDED","NOT_DELIVERED","DELIVERY_IMPOSSIBLE","DELIVERED","RECEIVED","ACCEPTED","REFUSED","REJECTED","DEADLINE_EXPIRED","FAILED"]}},{"name":"counterpartyVat","required":false,"in":"query","description":"Filter by customer or supplier VAT number.","schema":{"example":"12345678901","type":"string"}},{"name":"senderFilename","required":false,"in":"query","description":"Filter by the original sender filename supplied before FttEl/SdI renaming.","schema":{"example":"invoice-example.xml","type":"string"}},{"name":"source","required":false,"in":"query","description":"Filter by invoice origin.","schema":{"example":"SDI","type":"string","enum":["SDI","HISTORICAL_IMPORT"]}},{"name":"documentType","required":false,"in":"query","description":"Filter by FatturaPA document type.","schema":{"example":"TD01","type":"string"}},{"name":"search","required":false,"in":"query","description":"Search invoice number, counterparty name, or counterparty VAT number.","schema":{"example":"Acme","type":"string"}},{"name":"issuedFrom","required":false,"in":"query","description":"Inclusive lower boundary for the invoice document date (issuedAt).","schema":{"example":"2026-01-01T00:00:00.000+01:00","type":"string"}},{"name":"issuedTo","required":false,"in":"query","description":"Inclusive upper boundary for the invoice document date (issuedAt).","schema":{"example":"2026-12-31T23:59:59.999+01:00","type":"string"}},{"name":"sortBy","required":false,"in":"query","description":"Field to sort results by.","schema":{"default":"issuedAt","example":"issuedAt","type":"string","enum":["issuedAt","receivedAt","createdAt","invoiceNumber","counterpartyName","totalAmount"]}},{"name":"sortOrder","required":false,"in":"query","description":"Sort direction: ascending (A-Z / oldest-first) or descending (Z-A / newest-first).","schema":{"default":"desc","example":"desc","type":"string","enum":["asc","desc"]}},{"name":"limit","required":false,"in":"query","description":"Maximum number of invoices to return.","schema":{"minimum":1,"maximum":100,"default":50,"example":50,"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Number of invoices to skip before returning results.","schema":{"minimum":0,"default":0,"example":0,"type":"number"}}],"responses":{"200":{"description":"Paginated invoices owned by the authenticated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List my invoices","tags":["Invoices"]}},"/invoices/financial-overview":{"get":{"description":"Returns account-level invoice aggregates for the dashboard without returning invoice records.","operationId":"InvoicesController_financialOverview","parameters":[],"responses":{"200":{"description":"Dashboard financial overview for invoices owned by the authenticated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinancialOverviewResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get invoice financial overview","tags":["Invoices"]}},"/invoices/{id}":{"get":{"description":"Returns one invoice, its stored documents, and any received SdI notifications for the authenticated account.","operationId":"InvoicesController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice detail for the authenticated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice not found for the authenticated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an invoice","tags":["Invoices"]},"delete":{"description":"Permanently deletes an invoice imported from an archive (source `HISTORICAL_IMPORT`), including its stored documents. Invoices received from or submitted to SdI cannot be deleted.","operationId":"InvoicesController_deleteImported","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"Imported invoice deleted."},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Only imported invoices can be deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice not found for the authenticated account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Delete an imported invoice","tags":["Invoices"]}},"/invoices/deletions":{"post":{"description":"Deletes the imported (source `HISTORICAL_IMPORT`) invoices among the supplied IDs, including their stored documents. Non-imported or unknown IDs are skipped.","operationId":"InvoicesController_deleteImportedBulk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteInvoicesDto"}}}},"responses":{"200":{"description":"Counts of deleted and skipped invoices.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Delete imported invoices in bulk","tags":["Invoices"]}},"/invoices/{id}/documents/{documentId}/download":{"get":{"description":"Streams a stored invoice document, such as uploaded XML, signed XML, inbound metadata, or notification payload content.","operationId":"InvoicesController_downloadDocument","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"documentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Binary document stream. The filename is provided in the `Content-Disposition` response header.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"The document belongs to another account.","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice or document not found.","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Download an invoice document","tags":["Invoices"]}},"/invoices/{id}/documents/{documentId}/xml":{"get":{"description":"Streams a stored invoice XML document as clean XML. For CAdES-signed (`.xml.p7m`) documents the signature envelope is removed and the extracted XML is returned.","operationId":"InvoicesController_getDocumentXml","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"documentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Unsigned invoice XML stream. The filename is provided in the `Content-Disposition` response header.","content":{"application/xml":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"The document belongs to another account.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice or document not found.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"422":{"description":"Document is not an invoice XML or the signed payload could not be extracted.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an invoice document as unsigned XML","tags":["Invoices"]}},"/invoices/{id}/documents/{documentId}/pdf":{"get":{"description":"Renders a stored invoice XML document with the FttEl invoice print template and returns an A4 PDF. For CAdES-signed (`.xml.p7m`) documents the signature envelope is removed before rendering.","operationId":"InvoicesController_getDocumentPdf","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"documentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Rendered invoice PDF stream. The filename is provided in the `Content-Disposition` header.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"The document belongs to another account.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice or document not found.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"422":{"description":"Document is not an invoice XML or the signed payload could not be extracted.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an invoice document as PDF","tags":["Invoices"]}},"/invoices/{id}/documents/{documentId}/preview":{"get":{"description":"Renders a stored invoice XML document as human-readable HTML using the FttEl invoice print template.","operationId":"InvoicesController_previewDocument","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"documentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Rendered invoice HTML.","content":{"text/html":{"schema":{"type":"string"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"text/html":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"The document belongs to another account.","content":{"text/html":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice or document not found.","content":{"text/html":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"422":{"description":"Document is not an invoice XML or the signed payload could not be extracted.","content":{"text/html":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Preview an invoice document as HTML","tags":["Invoices"]}},"/invoices/downloads":{"post":{"description":"Builds a ZIP archive containing the selected invoices and their stored documents for the authenticated account.","operationId":"InvoicesController_downloadInvoices","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadInvoicesDto"}}}},"responses":{"200":{"description":"ZIP archive stream. The filename is provided in the `Content-Disposition` response header.","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Requested invoices or downloadable documents were not found.","content":{"application/zip":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Download multiple invoices","tags":["Invoices"]}},"/invoices/import/inbound":{"post":{"description":"Imports previously received invoices exported from Agenzia delle Entrate (egov) as archival records. Upload a single ZIP archive containing the invoice files (`.XML` or signed `.xml.p7m`); `*_metaDato.xml` sidecars are ignored. All files are recorded with direction `INBOUND`; the transmission direction comes from this endpoint, not from the XML. Each invoice is stored as a historical record and is never re-transmitted to SdI. Duplicates (same direction, document type, counterparty, invoice number, and issue date) are skipped, so the same archive can be uploaded again safely.","operationId":"InvoicesController_importInbound","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"ZIP archive of egov invoice files."}}}}}},"responses":{"200":{"description":"Import summary with counts of imported, skipped, and failed invoice files.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportHistoricalInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Import received (inbound) invoices from a ZIP archive","tags":["Invoices"]}},"/invoices/import/outbound":{"post":{"description":"Imports previously issued invoices exported from Agenzia delle Entrate (egov) as archival records. Upload a single ZIP archive containing the invoice files (`.XML` or signed `.xml.p7m`); `*_metaDato.xml` sidecars are ignored. All files are recorded with direction `OUTBOUND`; the transmission direction comes from this endpoint, not from the XML. Each invoice is stored as a historical record and is never re-transmitted to SdI. Duplicates (same direction, document type, counterparty, invoice number, and issue date) are skipped, so the same archive can be uploaded again safely.","operationId":"InvoicesController_importOutbound","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"ZIP archive of egov invoice files."}}}}}},"responses":{"200":{"description":"Import summary with counts of imported, skipped, and failed invoice files.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportHistoricalInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Import sent (outbound) invoices from a ZIP archive","tags":["Invoices"]}},"/invoices/import":{"post":{"deprecated":true,"description":"Deprecated alias of `POST /invoices/import/inbound`. Prefer the direction-specific endpoints.","operationId":"InvoicesController_importHistorical","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"ZIP archive of egov invoice files."}}}}}},"responses":{"200":{"description":"Import summary with counts of imported, skipped, and failed invoice files.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportHistoricalInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Authentication is missing, invalid, expired, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Import received invoices from a ZIP archive (deprecated alias)","tags":["Invoices"]}},"/machine/invoices/import/inbound":{"post":{"description":"Machine-to-machine variant. Authenticate with the `x-api-key` header. Imports previously received invoices exported from Agenzia delle Entrate (egov) as archival records. Upload a single ZIP archive containing the invoice files (`.XML` or signed `.xml.p7m`); `*_metaDato.xml` sidecars are ignored. All files are recorded with direction `INBOUND`; the transmission direction comes from this endpoint, not from the XML. Each invoice is stored as a historical record and is never re-transmitted to SdI. Duplicates (same direction, document type, counterparty, invoice number, and issue date) are skipped, so the same archive can be uploaded again safely.","operationId":"InvoicesController_machineImportInbound","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"ZIP archive of egov invoice files."}}}}}},"responses":{"200":{"description":"Import summary with counts of imported, skipped, and failed invoice files.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportHistoricalInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Import received (inbound) invoices with an API key","tags":["Invoices"]}},"/machine/invoices/import/outbound":{"post":{"description":"Machine-to-machine variant. Authenticate with the `x-api-key` header. Imports previously issued invoices exported from Agenzia delle Entrate (egov) as archival records. Upload a single ZIP archive containing the invoice files (`.XML` or signed `.xml.p7m`); `*_metaDato.xml` sidecars are ignored. All files are recorded with direction `OUTBOUND`; the transmission direction comes from this endpoint, not from the XML. Each invoice is stored as a historical record and is never re-transmitted to SdI. Duplicates (same direction, document type, counterparty, invoice number, and issue date) are skipped, so the same archive can be uploaded again safely.","operationId":"InvoicesController_machineImportOutbound","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"ZIP archive of egov invoice files."}}}}}},"responses":{"200":{"description":"Import summary with counts of imported, skipped, and failed invoice files.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportHistoricalInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Import sent (outbound) invoices with an API key","tags":["Invoices"]}},"/machine/invoices/outbound":{"post":{"description":"Machine-to-machine variant of outbound invoice submission. Authenticate with the `x-api-key` header.","operationId":"InvoicesController_machineCreateOutbound","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOutboundInvoiceDto"}}}},"responses":{"201":{"description":"Invoice stored and submitted, or stored with a submission failure state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOutboundInvoiceResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Invoice sender VAT number is missing or does not match your account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Unable to allocate a unique SdI filename, please retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"422":{"description":"Invoice XML, signed payload extraction, or SdI filename generation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Submit an outbound invoice with an API key","tags":["Invoices"]}},"/machine/invoices":{"get":{"description":"Machine-to-machine variant of invoice listing. Authenticate with the `x-api-key` header. Supports the same filters as `/invoices`, including exact `senderFilename` matching. Also supports `sentFrom`/`sentTo` (createdAt range), `receivedFrom`/`receivedTo` (receivedAt range), and `issuedFrom`/`issuedTo` (issuedAt document-date range) date filters. Results are ordered by `sortBy` (default `issuedAt`) and `sortOrder` (default `desc`); ties break on `id` in the same direction. Results are paginated with `limit` (up to 500) and `offset`. Invoice documents are returned in `documents[]` with Base64 `xml` content. Related notification payloads are returned in `notifications[]` with Base64 `xml` content.","operationId":"InvoicesController_machineList","parameters":[{"name":"direction","required":false,"in":"query","description":"Filter by invoice direction.","schema":{"example":"OUTBOUND","type":"string","enum":["INBOUND","OUTBOUND"]}},{"name":"status","required":false,"in":"query","description":"Filter by invoice processing status.","schema":{"example":"SUBMITTED","type":"string","enum":["DRAFT","QUEUED","TAKEN_IN_CHARGE","PROCESSING_ERROR","SUBMITTED","SENT","DISCARDED","NOT_DELIVERED","DELIVERY_IMPOSSIBLE","DELIVERED","RECEIVED","ACCEPTED","REFUSED","REJECTED","DEADLINE_EXPIRED","FAILED"]}},{"name":"counterpartyVat","required":false,"in":"query","description":"Filter by customer or supplier VAT number.","schema":{"example":"12345678901","type":"string"}},{"name":"senderFilename","required":false,"in":"query","description":"Filter by the original sender filename supplied before FttEl/SdI renaming.","schema":{"example":"invoice-example.xml","type":"string"}},{"name":"source","required":false,"in":"query","description":"Filter by invoice origin.","schema":{"example":"SDI","type":"string","enum":["SDI","HISTORICAL_IMPORT"]}},{"name":"documentType","required":false,"in":"query","description":"Filter by FatturaPA document type.","schema":{"example":"TD01","type":"string"}},{"name":"search","required":false,"in":"query","description":"Search invoice number, counterparty name, or counterparty VAT number.","schema":{"example":"Acme","type":"string"}},{"name":"issuedFrom","required":false,"in":"query","description":"Inclusive lower boundary for the invoice document date (issuedAt).","schema":{"example":"2026-01-01T00:00:00.000+01:00","type":"string"}},{"name":"issuedTo","required":false,"in":"query","description":"Inclusive upper boundary for the invoice document date (issuedAt).","schema":{"example":"2026-12-31T23:59:59.999+01:00","type":"string"}},{"name":"sortBy","required":false,"in":"query","description":"Field to sort results by.","schema":{"default":"issuedAt","example":"issuedAt","type":"string","enum":["issuedAt","receivedAt","createdAt","invoiceNumber","counterpartyName","totalAmount"]}},{"name":"sortOrder","required":false,"in":"query","description":"Sort direction: ascending (A-Z / oldest-first) or descending (Z-A / newest-first).","schema":{"default":"desc","example":"desc","type":"string","enum":["asc","desc"]}},{"name":"limit","required":false,"in":"query","description":"Maximum number of invoices to return.","schema":{"minimum":1,"maximum":500,"default":50,"example":50,"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Number of invoices to skip before returning results.","schema":{"minimum":0,"default":0,"example":0,"type":"number"}},{"name":"sentFrom","required":false,"in":"query","description":"Inclusive lower boundary for the sending date (createdAt) as an ISO 8601 timestamp.","schema":{"example":"2026-01-01T00:00:00.000+01:00","type":"string"}},{"name":"sentTo","required":false,"in":"query","description":"Inclusive upper boundary for the sending date (createdAt) as an ISO 8601 timestamp.","schema":{"example":"2026-01-31T23:59:59.999+01:00","type":"string"}},{"name":"receivedFrom","required":false,"in":"query","description":"Inclusive lower boundary for the SdI receipt date (receivedAt) as an ISO 8601 timestamp.","schema":{"example":"2026-01-01T00:00:00.000+01:00","type":"string"}},{"name":"receivedTo","required":false,"in":"query","description":"Inclusive upper boundary for the SdI receipt date (receivedAt) as an ISO 8601 timestamp.","schema":{"example":"2026-01-31T23:59:59.999+01:00","type":"string"}}],"responses":{"200":{"description":"Paginated invoices owned by the API-key account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"List invoices with an API key","tags":["Invoices"]}},"/machine/invoices/{id}":{"get":{"description":"Machine-to-machine variant of invoice detail lookup. Authenticate with the `x-api-key` header. Invoice documents are returned in `documents[]` with Base64 `xml` content. Related notification payloads are returned in `notifications[]` with Base64 `xml` content.","operationId":"InvoicesController_machineGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice detail for the API-key account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponseDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice not found for the API-key account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Get an invoice with an API key","tags":["Invoices"]},"delete":{"description":"Machine-to-machine variant of imported-invoice deletion. Authenticate with the `x-api-key` header. Permanently deletes an invoice imported from an archive (source `HISTORICAL_IMPORT`), including its stored documents. Invoices received from or submitted to SdI cannot be deleted.","operationId":"InvoicesController_machineDeleteImported","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"Imported invoice deleted."},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Only imported invoices can be deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice not found for the API-key account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Delete an imported invoice with an API key","tags":["Invoices"]}},"/machine/invoices/{id}/documents/{documentId}/xml":{"get":{"description":"Machine-to-machine variant of unsigned XML retrieval. Authenticate with the `x-api-key` header. For CAdES-signed (`.xml.p7m`) documents the signature envelope is removed and the extracted XML is returned.","operationId":"InvoicesController_machineGetDocumentXml","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"documentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Unsigned invoice XML stream. The filename is provided in the `Content-Disposition` response header.","content":{"application/xml":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"The document belongs to another account.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice or document not found.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"422":{"description":"Document is not an invoice XML or the signed payload could not be extracted.","content":{"application/xml":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Get an invoice document as unsigned XML with an API key","tags":["Invoices"]}},"/machine/invoices/{id}/documents/{documentId}/pdf":{"get":{"description":"Machine-to-machine variant of invoice PDF rendering. Authenticate with the `x-api-key` header. Renders the stored invoice XML with the FttEl invoice print template and returns an A4 PDF. For CAdES-signed (`.xml.p7m`) documents the signature envelope is removed before rendering.","operationId":"InvoicesController_machineGetDocumentPdf","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"documentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Rendered invoice PDF stream. The filename is provided in the `Content-Disposition` response header.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"The document belongs to another account.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Invoice or document not found.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"422":{"description":"Document is not an invoice XML or the signed payload could not be extracted.","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Get an invoice document as PDF with an API key","tags":["Invoices"]}},"/machine/invoices/deletions":{"post":{"description":"Machine-to-machine variant of bulk imported-invoice deletion. Authenticate with the `x-api-key` header. Deletes the imported (source `HISTORICAL_IMPORT`) invoices among the supplied IDs, including their stored documents. Non-imported or unknown IDs are skipped.","operationId":"InvoicesController_machineDeleteImportedBulk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteInvoicesDto"}}}},"responses":{"200":{"description":"Counts of deleted and skipped invoices.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteInvoicesResponseDto"}}}},"400":{"description":"The request body, route parameters, or query parameters failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"api-key":[]}],"summary":"Delete imported invoices in bulk with an API key","tags":["Invoices"]}},"/health":{"get":{"description":"Reports application health, including database connectivity, for uptime and deployment checks.","operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":"The API and database are healthy.\n\nThe Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Check API health","tags":["Health"]}}},"info":{"title":"FttEl API","description":"REST API for FttEl account access, invoice submission, provider operations, and health checks.\nGuida per sviluppatori: [primo invio, fatture, webhook e prove](/docs/guida/).\n\nUse bearer authentication for interactive account and provider flows.\nUse the `x-api-key` header for machine-to-machine invoice endpoints under `/machine`.\nSOAP endpoints are not represented here; this documentation covers the HTTP REST surface.","version":"0.1.0","contact":{}},"tags":[{"name":"Accounts","description":"Account bootstrap, profile, and webhook configuration."},{"name":"Authentication","description":"Interactive account login, token refresh, password setup, and API-key rotation."},{"name":"Health","description":"Runtime health probes for infrastructure checks."},{"name":"Invoices","description":"Authenticated account invoice submission, lookup, and document downloads."},{"name":"Provider","description":"Provider/operator authentication plus cross-account invoice and client visibility."}],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"},"api-key":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"BootstrapAccountDto":{"type":"object","properties":{"email":{"type":"string","description":"Primary account email address.","example":"admin@example.com"},"password":{"type":"string","description":"Initial account password. Must be at least 12 characters.","example":"correct horse battery","minLength":12},"legalName":{"type":"string","description":"Registered business name.","example":"Example SRL"},"vatNumber":{"type":"string","description":"VAT number without country prefix.","example":"12345678901"},"countryCode":{"type":"string","default":"IT","description":"ISO 3166-1 alpha-2 country code.","example":"IT"},"fiscalCode":{"type":"string","description":"Optional Italian fiscal code when it differs from the VAT number.","example":"RSSMRA80A01H501U"}},"required":["email","password","legalName","vatNumber"]},"BootstrapAccountResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Created account identifier.","example":"account_123"},"username":{"type":"string","description":"Login username for the account.","example":"admin@example.com"},"email":{"type":"string","description":"Primary account email address.","example":"admin@example.com"},"legalName":{"type":"string","description":"Registered business name.","example":"Example SRL"},"vatNumber":{"type":"string","description":"VAT number without country prefix.","example":"12345678901"},"apiKey":{"type":"string","description":"Initial machine credential. Store it securely; later rotations only return the new key once.","example":"fttel_00000000000000000000000000000000"}},"required":["id","username","email","legalName","vatNumber","apiKey"]},"ErrorResponseDto":{"type":"object","properties":{"statusCode":{"type":"number","description":"HTTP status code.","example":400},"message":{"description":"Error details returned by NestJS or validation.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"example":"Validation failed"},"error":{"type":"string","description":"HTTP error label.","example":"Bad Request"}},"required":["statusCode","message"]},"AccountProfileDto":{"type":"object","properties":{"id":{"type":"string","description":"Account identifier.","example":"account_123"},"username":{"type":"string","description":"Login username for the account.","example":"admin@example.com"},"email":{"type":"string","description":"Primary account email address.","example":"admin@example.com"},"legalName":{"type":"string","description":"Registered business name.","example":"Example SRL"},"vatNumber":{"type":"string","description":"VAT number without country prefix.","example":"12345678901"},"countryCode":{"type":"string","description":"ISO 3166-1 alpha-2 country code.","example":"IT"},"fiscalCode":{"type":"string","description":"Fiscal code when it differs from the VAT number.","example":"RSSMRA80A01H501U","nullable":true},"invoiceStatusWebhookUrl":{"type":"string","description":"Webhook URL called after invoice status updates.","example":"https://example.com/webhooks/invoice-status","nullable":true},"inboundInvoiceWebhookUrl":{"type":"string","description":"Webhook URL called after new inbound invoices are received.","example":"https://example.com/webhooks/inbound-invoices","nullable":true},"inboundInvoiceEmailEnabled":{"type":"boolean","description":"Whether email is sent when a new inbound invoice is received.","example":true},"outboundNotificationEmailEnabled":{"type":"boolean","description":"Whether email is sent for SdI notifications about outbound invoices.","example":true},"hasApiKey":{"type":"boolean","description":"Whether the account currently has a machine API key.","example":true},"apiKeyRotatedAt":{"format":"date-time","type":"string","description":"When the machine API key was last rotated.","nullable":true},"isActive":{"type":"boolean","description":"Whether account access is active.","example":true},"createdAt":{"format":"date-time","type":"string","description":"Account creation timestamp."},"updatedAt":{"format":"date-time","type":"string","description":"Account last update timestamp."}},"required":["id","username","email","legalName","vatNumber","countryCode","inboundInvoiceEmailEnabled","outboundNotificationEmailEnabled","hasApiKey","isActive","createdAt","updatedAt"]},"UpdateAccountDto":{"type":"object","properties":{"legalName":{"type":"string","description":"Registered business name.","example":"Example SRL"},"vatNumber":{"type":"string","description":"VAT number without country prefix.","example":"12345678901"},"countryCode":{"type":"string","description":"ISO 3166-1 alpha-2 country code.","example":"IT"},"fiscalCode":{"type":"string","description":"Optional Italian fiscal code when it differs from the VAT number.","example":"RSSMRA80A01H501U"},"invoiceStatusWebhookUrl":{"type":"string","description":"Webhook URL called after invoice status updates. Send an empty string to disable.","example":"https://example.com/webhooks/invoice-status"},"inboundInvoiceWebhookUrl":{"type":"string","description":"Webhook URL called after a new inbound invoice is received. Send an empty string to disable.","example":"https://example.com/webhooks/inbound-invoices"},"inboundInvoiceEmailEnabled":{"type":"boolean","description":"Enable or disable email when a new inbound invoice is received.","example":true},"outboundNotificationEmailEnabled":{"type":"boolean","description":"Enable or disable email for SdI notifications about outbound invoices.","example":true}}},"TestWebhookDto":{"type":"object","properties":{"kind":{"type":"string","enum":["invoiceStatus","inboundInvoice"],"description":"Webhook event type to test.","example":"invoiceStatus"},"scenario":{"type":"string","enum":["deliveryReceipt","deliveryFailure","rejection","outcomeAccepted","outcomeRefused","deadlineExpiry","transmissionCertification"],"description":"Invoice status scenario to simulate when `kind` is `invoiceStatus`. Defaults to delivery receipt.","example":"rejection"}},"required":["kind"]},"TestWebhookResponseDto":{"type":"object","properties":{"kind":{"type":"string","description":"Webhook event type that was tested.","enum":["invoiceStatus","inboundInvoice"],"example":"invoiceStatus"},"scenario":{"type":"string","description":"Invoice status scenario tested. Null for inbound-invoice webhook tests.","enum":["deliveryReceipt","deliveryFailure","rejection","outcomeAccepted","outcomeRefused","deadlineExpiry","transmissionCertification"],"nullable":true,"example":"rejection"},"url":{"type":"string","description":"Configured webhook URL used for the test delivery.","example":"https://example.com/webhooks/invoice-status"},"ok":{"type":"boolean","description":"Whether the webhook responded with a successful HTTP status.","example":true},"statusCode":{"type":"number","description":"HTTP status code returned by the webhook endpoint.","example":200,"nullable":true},"statusText":{"type":"string","description":"HTTP status text returned by the webhook endpoint.","example":"OK","nullable":true},"responseBody":{"type":"string","description":"Truncated response body returned by the webhook endpoint, when available.","example":"{\"received\":true}","nullable":true},"error":{"type":"string","description":"Delivery error message when the webhook test fails before or during the HTTP request.","example":"Connection refused","nullable":true},"durationMs":{"type":"number","description":"Webhook delivery duration in milliseconds.","example":128}},"required":["kind","url","ok","durationMs"]},"RegisterAccountDto":{"type":"object","properties":{"email":{"type":"string","description":"Primary account email address. Setup and reset emails are sent here.","example":"admin@example.com"},"legalName":{"type":"string","description":"Registered business name.","example":"Example SRL"},"vatNumber":{"type":"string","description":"VAT number without country prefix.","example":"12345678901"},"countryCode":{"type":"string","default":"IT","description":"ISO 3166-1 alpha-2 country code.","example":"IT"},"fiscalCode":{"type":"string","description":"Optional Italian fiscal code when it differs from the VAT number.","example":"RSSMRA80A01H501U"}},"required":["email","legalName","vatNumber"]},"RegisterResponseDto":{"type":"object","properties":{"account":{"description":"Registered account profile.","allOf":[{"$ref":"#/components/schemas/AccountProfileDto"}]},"setupUrl":{"type":"string","description":"Password setup URL returned only in non-deployed environments.","example":"http://localhost:5173/set-password?token=password-token"}},"required":["account"]},"PasswordTokenDto":{"type":"object","properties":{"token":{"type":"string","description":"One-time password setup or reset token.","example":"password-token"},"password":{"type":"string","description":"New account password. Must be at least 12 characters.","example":"correct horse battery","minLength":12}},"required":["token","password"]},"AuthSessionResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"Bearer token for authenticated REST requests.","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"account":{"description":"Authenticated account profile.","allOf":[{"$ref":"#/components/schemas/AccountProfileDto"}]}},"required":["accessToken","account"]},"RequestPasswordResetDto":{"type":"object","properties":{"email":{"type":"string","description":"Account email address that should receive reset instructions.","example":"admin@example.com"}},"required":["email"]},"PasswordResetRequestResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"Always true when the request is accepted.","example":true},"resetUrl":{"type":"string","description":"Password reset URL returned only in non-deployed environments.","example":"http://localhost:5173/reset-password?token=password-token"}},"required":["ok"]},"RequestEmailChangeDto":{"type":"object","properties":{"email":{"type":"string","description":"New primary account email address. The address also becomes the account username after confirmation.","example":"owner@example.com","maxLength":254},"currentPassword":{"type":"string","description":"Current account password, required to request this sensitive change.","example":"correct horse battery","writeOnly":true}},"required":["email","currentPassword"]},"EmailChangeRequestResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"True when the email change request was accepted.","example":true},"email":{"type":"string","description":"New email address awaiting confirmation.","example":"owner@example.com"},"verificationUrl":{"type":"string","description":"Email confirmation URL returned only in non-deployed environments.","example":"http://localhost:5173/confirm-email?token=email-change-token"}},"required":["ok","email"]},"ConfirmEmailChangeDto":{"type":"object","properties":{"token":{"type":"string","description":"One-time email change verification token.","example":"email-change-token"}},"required":["token"]},"LoginDto":{"type":"object","properties":{"username":{"type":"string","description":"Account username.","example":"admin@example.com"},"password":{"type":"string","description":"Account password.","example":"correct horse battery","minLength":12}},"required":["username","password"]},"RefreshDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Refresh token. Optional when the `fttel_refresh` HTTP-only cookie is present.","example":"refresh-token"}}},"LogoutResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"True when logout handling completed.","example":true}},"required":["ok"]},"ApiKeyResponseDto":{"type":"object","properties":{"apiKey":{"type":"string","description":"New machine API key. It is only returned once.","example":"fttel_00000000000000000000000000000000"}},"required":["apiKey"]},"BootstrapProviderDto":{"type":"object","properties":{"email":{"type":"string","description":"Initial provider email address.","example":"provider@example.com"},"password":{"type":"string","description":"Initial provider password. Must be at least 12 characters.","example":"correct horse battery","minLength":12}},"required":["email","password"]},"ProviderUserResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Provider user identifier.","example":"provider_123"},"username":{"type":"string","description":"Provider login username.","example":"provider@example.com"},"email":{"type":"string","description":"Provider email address.","example":"provider@example.com"},"role":{"type":"string","description":"Provider role.","example":"ADMIN"},"isActive":{"type":"boolean","description":"Whether the provider user can authenticate.","example":true}},"required":["id","username","email","role","isActive"]},"ProviderAuthSessionResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"Bearer token for provider REST requests.","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"provider":{"description":"Authenticated provider user.","allOf":[{"$ref":"#/components/schemas/ProviderUserResponseDto"}]}},"required":["accessToken","provider"]},"ProviderLoginDto":{"type":"object","properties":{"username":{"type":"string","description":"Provider username.","example":"provider@example.com"},"password":{"type":"string","description":"Provider password.","example":"correct horse battery","minLength":12}},"required":["username","password"]},"ProviderRefreshDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Provider refresh token. Optional when the `fttel_provider_refresh` HTTP-only cookie is present.","example":"provider-refresh-token"}}},"ProviderLogoutResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"True when logout handling completed.","example":true}},"required":["ok"]},"ProviderStatusCountDto":{"type":"object","properties":{"status":{"type":"string","description":"Invoice status value.","example":"SUBMITTED"},"count":{"type":"number","description":"Number of invoices currently in this status.","example":12}},"required":["status","count"]},"ProviderAccountSummaryDto":{"type":"object","properties":{"id":{"type":"string","description":"Client account identifier.","example":"account_123"},"legalName":{"type":"string","description":"Registered business name.","example":"Example SRL"},"email":{"type":"string","description":"Primary client account email address.","example":"admin@example.com"},"vatNumber":{"type":"string","description":"Client VAT number without country prefix.","example":"12345678901"},"countryCode":{"type":"string","description":"ISO 3166-1 alpha-2 country code.","example":"IT"},"fiscalCode":{"type":"string","description":"Client fiscal code when it differs from the VAT number.","example":"RSSMRA80A01H501U","nullable":true},"isActive":{"type":"boolean","description":"Whether the client account is active.","example":true},"invoiceCount":{"type":"number","description":"Total invoice count for the client account.","example":42},"notificationCount":{"type":"number","description":"Total notification count for the client account.","example":18},"documentCount":{"type":"number","description":"Total stored document count for the client account.","example":64},"statusCounts":{"description":"Invoice counts grouped by status.","type":"array","items":{"$ref":"#/components/schemas/ProviderStatusCountDto"}},"createdAt":{"format":"date-time","type":"string","description":"Client account creation timestamp."},"updatedAt":{"format":"date-time","type":"string","description":"Client account last update timestamp."}},"required":["id","legalName","email","vatNumber","countryCode","isActive","invoiceCount","notificationCount","documentCount","statusCounts","createdAt","updatedAt"]},"ProviderAccountDetailDto":{"type":"object","properties":{"id":{"type":"string","description":"Client account identifier.","example":"account_123"},"legalName":{"type":"string","description":"Registered business name.","example":"Example SRL"},"email":{"type":"string","description":"Primary client account email address.","example":"admin@example.com"},"vatNumber":{"type":"string","description":"Client VAT number without country prefix.","example":"12345678901"},"countryCode":{"type":"string","description":"ISO 3166-1 alpha-2 country code.","example":"IT"},"fiscalCode":{"type":"string","description":"Client fiscal code when it differs from the VAT number.","example":"RSSMRA80A01H501U","nullable":true},"isActive":{"type":"boolean","description":"Whether the client account is active.","example":true},"invoiceCount":{"type":"number","description":"Total invoice count for the client account.","example":42},"notificationCount":{"type":"number","description":"Total notification count for the client account.","example":18},"documentCount":{"type":"number","description":"Total stored document count for the client account.","example":64},"statusCounts":{"description":"Invoice counts grouped by status.","type":"array","items":{"$ref":"#/components/schemas/ProviderStatusCountDto"}},"createdAt":{"format":"date-time","type":"string","description":"Client account creation timestamp."},"updatedAt":{"format":"date-time","type":"string","description":"Client account last update timestamp."}},"required":["id","legalName","email","vatNumber","countryCode","isActive","invoiceCount","notificationCount","documentCount","statusCounts","createdAt","updatedAt"]},"StoredDocumentResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Stored document identifier.","example":"document_123"},"accountId":{"type":"string","description":"Owning account identifier when the document is account-scoped.","example":"account_123","nullable":true},"invoiceId":{"type":"string","description":"Related invoice identifier when the document is invoice-scoped.","example":"invoice_123","nullable":true},"kind":{"type":"string","description":"Document kind, such as invoice XML, SdI metadata, signed XML, or notification payload.","example":"XML_INVOICE"},"filename":{"type":"string","description":"Download filename exposed by the API.","example":"invoice-example.xml"},"signatureState":{"type":"string","description":"Detected signature state for the stored document.","example":"SIGNED_XML"},"contentType":{"type":"string","description":"Stored document media type.","example":"application/xml"},"sha256":{"type":"string","description":"SHA-256 hash of the stored document content.","example":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"},"createdAt":{"format":"date-time","type":"string","description":"Document storage timestamp."},"xml":{"type":"string","description":"Base64-encoded stored document content. Populated automatically by machine invoice endpoints.","example":"PD94bWwgdmVyc2lvbj0iMS4wIj8+"}},"required":["id","kind","filename","signatureState","contentType","sha256","createdAt"]},"NotificationResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Notification identifier.","example":"notification_123"},"kind":{"type":"string","description":"Normalized notification kind received from SdI.","example":"DELIVERY_RECEIPT"},"filename":{"type":"string","description":"Transport filename from the notification payload or SOAP message.","example":"IT12345678901A2026_00001.xml","nullable":true},"sdiIdentifier":{"type":"string","description":"SdI identifier referenced by the notification.","example":"123456789","nullable":true},"statusSnapshot":{"type":"string","description":"Invoice status after applying the notification.","example":"DELIVERED","nullable":true},"receivedAt":{"format":"date-time","type":"string","description":"Notification receipt timestamp."},"xml":{"type":"string","description":"Base64-encoded notification payload content. Populated automatically by machine invoice endpoints when available.","example":"PE5vdGlmaWNhU2NhcnRvIC8+"},"messageTitle":{"type":"string","description":"Human-readable notification title for UI display.","example":"Invoice delivered by SdI"},"messageBody":{"type":"string","description":"Human-readable notification summary for UI display.","example":"SdI confirmed delivery. The invoice status is now delivered."},"messageDetails":{"description":"Additional parsed notification details, including SdI codes, notes, and message identifiers.","example":["SdI identifier: 123456789","Message ID: ABC123"],"type":"array","items":{"type":"string"}}},"required":["id","kind","receivedAt","messageTitle","messageBody","messageDetails"]},"ProviderInvoiceResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Invoice identifier.","example":"invoice_123"},"account":{"description":"Client account that owns the invoice.","allOf":[{"$ref":"#/components/schemas/ProviderAccountSummaryDto"}]},"direction":{"type":"string","description":"Invoice direction relative to the client account.","example":"OUTBOUND"},"status":{"type":"string","description":"Current invoice processing status.","example":"SUBMITTED"},"filename":{"type":"string","description":"API-generated or received transport filename.","example":"IT12345678901A2026_00001.xml"},"senderFilename":{"type":"string","description":"Original filename supplied by the client account for outbound uploads.","example":"invoice-example.xml","nullable":true},"invoiceNumber":{"type":"string","description":"Invoice number parsed from the XML payload.","example":"2026-001","nullable":true},"sdiIdentifier":{"type":"string","description":"SdI identifier assigned by Sistema di Interscambio.","example":"123456789","nullable":true},"counterpartyVat":{"type":"string","description":"Counterparty VAT number parsed from the invoice payload.","example":"10987654321","nullable":true},"counterpartyFiscal":{"type":"string","description":"Counterparty fiscal code parsed from the invoice payload.","example":"RSSMRA80A01H501U","nullable":true},"counterpartyName":{"type":"string","description":"Counterparty legal name (Denominazione) parsed from the invoice payload.","example":"Example SRL","nullable":true},"totalAmount":{"type":"string","description":"Invoice total amount as a decimal string.","example":"122.00","nullable":true},"issuedAt":{"format":"date-time","type":"string","description":"Required invoice issue date parsed from the FatturaPA Data field."},"receivedAt":{"format":"date-time","type":"string","description":"Inbound invoice receipt timestamp.","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"Invoice record creation timestamp."},"updatedAt":{"format":"date-time","type":"string","description":"Invoice record last update timestamp."},"documents":{"description":"Stored documents related to the invoice.","type":"array","items":{"$ref":"#/components/schemas/StoredDocumentResponseDto"}},"notifications":{"description":"SdI notifications received for the invoice.","type":"array","items":{"$ref":"#/components/schemas/NotificationResponseDto"}}},"required":["id","account","direction","status","filename","issuedAt","createdAt","updatedAt","documents","notifications"]},"ProviderPaginatedInvoicesResponseDto":{"type":"object","properties":{"items":{"description":"Page of provider-visible invoices.","type":"array","items":{"$ref":"#/components/schemas/ProviderInvoiceResponseDto"}},"total":{"type":"number","description":"Total invoices matching the filters.","example":120},"limit":{"type":"number","description":"Maximum number of invoices requested for this page.","example":50},"offset":{"type":"number","description":"Number of invoices skipped before this page.","example":0},"hasMore":{"type":"boolean","description":"Whether another page is available after this one.","example":true}},"required":["items","total","limit","offset","hasMore"]},"DownloadProviderPeriodDto":{"type":"object","properties":{"createdFrom":{"type":"string","description":"Inclusive lower createdAt boundary as an ISO 8601 timestamp.","example":"2026-01-01T00:00:00.000+01:00"},"createdTo":{"type":"string","description":"Inclusive upper createdAt boundary as an ISO 8601 timestamp.","example":"2026-03-31T23:59:59.999+02:00"}},"required":["createdFrom","createdTo"]},"ProviderInvoiceExportRequestResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Persistent export job identifier.","example":"cm123export"},"status":{"type":"string","description":"Current background export state.","enum":["QUEUED","PROCESSING","READY","FAILED","EXPIRED"],"example":"PROCESSING"},"createdFrom":{"format":"date-time","type":"string","description":"Inclusive lower invoice createdAt boundary."},"createdTo":{"format":"date-time","type":"string","description":"Inclusive upper invoice createdAt boundary."},"filename":{"type":"string","description":"Filename used when the completed archive is downloaded."},"sizeBytes":{"type":"string","description":"Completed archive size in bytes, represented as a decimal string.","example":"1073741824","nullable":true},"totalInvoices":{"type":"number","description":"Number of eligible invoices in the export.","example":15000},"processedInvoices":{"type":"number","description":"Number of invoices processed so far.","example":4200},"errorMessage":{"type":"string","description":"Safe failure reason when generation did not complete.","nullable":true},"startedAt":{"format":"date-time","type":"string","description":"Timestamp when a worker first claimed the job.","nullable":true},"completedAt":{"format":"date-time","type":"string","description":"Timestamp when generation completed or failed.","nullable":true},"expiresAt":{"format":"date-time","type":"string","description":"Timestamp after which the stored archive is removed.","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"Export request creation timestamp."},"updatedAt":{"format":"date-time","type":"string","description":"Export job last update timestamp."},"reused":{"type":"boolean","description":"Whether an existing queued, processing, or ready period export was reused.","example":true}},"required":["id","status","createdFrom","createdTo","filename","totalInvoices","processedInvoices","createdAt","updatedAt","reused"]},"ProviderInvoiceExportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Persistent export job identifier.","example":"cm123export"},"status":{"type":"string","description":"Current background export state.","enum":["QUEUED","PROCESSING","READY","FAILED","EXPIRED"],"example":"PROCESSING"},"createdFrom":{"format":"date-time","type":"string","description":"Inclusive lower invoice createdAt boundary."},"createdTo":{"format":"date-time","type":"string","description":"Inclusive upper invoice createdAt boundary."},"filename":{"type":"string","description":"Filename used when the completed archive is downloaded."},"sizeBytes":{"type":"string","description":"Completed archive size in bytes, represented as a decimal string.","example":"1073741824","nullable":true},"totalInvoices":{"type":"number","description":"Number of eligible invoices in the export.","example":15000},"processedInvoices":{"type":"number","description":"Number of invoices processed so far.","example":4200},"errorMessage":{"type":"string","description":"Safe failure reason when generation did not complete.","nullable":true},"startedAt":{"format":"date-time","type":"string","description":"Timestamp when a worker first claimed the job.","nullable":true},"completedAt":{"format":"date-time","type":"string","description":"Timestamp when generation completed or failed.","nullable":true},"expiresAt":{"format":"date-time","type":"string","description":"Timestamp after which the stored archive is removed.","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"Export request creation timestamp."},"updatedAt":{"format":"date-time","type":"string","description":"Export job last update timestamp."}},"required":["id","status","createdFrom","createdTo","filename","totalInvoices","processedInvoices","createdAt","updatedAt"]},"AccountInvoiceExportFiltersDto":{"type":"object","properties":{"direction":{"type":"string","enum":["INBOUND","OUTBOUND"]},"status":{"type":"string","enum":["DRAFT","QUEUED","TAKEN_IN_CHARGE","PROCESSING_ERROR","SUBMITTED","SENT","DISCARDED","NOT_DELIVERED","DELIVERY_IMPOSSIBLE","DELIVERED","RECEIVED","ACCEPTED","REFUSED","REJECTED","DEADLINE_EXPIRED","FAILED"]},"source":{"type":"string","enum":["SDI","HISTORICAL_IMPORT"]},"documentType":{"type":"string"},"search":{"type":"string"},"counterpartyVat":{"type":"string"},"senderFilename":{"type":"string"},"issuedFrom":{"format":"date-time","type":"string"},"issuedTo":{"format":"date-time","type":"string"}}},"AccountInvoiceExportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Persistent account export job identifier."},"status":{"type":"string","enum":["QUEUED","PROCESSING","READY","FAILED","EXPIRED"]},"filters":{"$ref":"#/components/schemas/AccountInvoiceExportFiltersDto"},"filename":{"type":"string","description":"Filename used when the completed archive is downloaded."},"sizeBytes":{"type":"string","nullable":true,"example":"1048576"},"totalInvoices":{"type":"number","example":120},"processedInvoices":{"type":"number","example":45},"errorMessage":{"type":"string","nullable":true},"startedAt":{"format":"date-time","type":"string","nullable":true},"completedAt":{"format":"date-time","type":"string","nullable":true},"expiresAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","status","filters","filename","totalInvoices","processedInvoices","createdAt","updatedAt"]},"CreateAccountInvoiceExportDto":{"type":"object","properties":{"direction":{"type":"string","enum":["INBOUND","OUTBOUND"],"description":"Filter by invoice direction.","example":"OUTBOUND"},"status":{"type":"string","enum":["DRAFT","QUEUED","TAKEN_IN_CHARGE","PROCESSING_ERROR","SUBMITTED","SENT","DISCARDED","NOT_DELIVERED","DELIVERY_IMPOSSIBLE","DELIVERED","RECEIVED","ACCEPTED","REFUSED","REJECTED","DEADLINE_EXPIRED","FAILED"],"description":"Filter by invoice processing status.","example":"SUBMITTED"},"counterpartyVat":{"type":"string","description":"Filter by customer or supplier VAT number.","example":"12345678901"},"senderFilename":{"type":"string","description":"Filter by the original sender filename supplied before FttEl/SdI renaming.","example":"invoice-example.xml"},"source":{"type":"string","enum":["SDI","HISTORICAL_IMPORT"],"description":"Filter by invoice origin.","example":"SDI"},"documentType":{"type":"string","description":"Filter by FatturaPA document type.","example":"TD01"},"search":{"type":"string","description":"Search invoice number, counterparty name, or counterparty VAT number.","example":"Acme"},"issuedFrom":{"type":"string","description":"Inclusive lower boundary for the invoice document date (issuedAt).","example":"2026-01-01T00:00:00.000+01:00"},"issuedTo":{"type":"string","description":"Inclusive upper boundary for the invoice document date (issuedAt).","example":"2026-12-31T23:59:59.999+01:00"}}},"AccountInvoiceExportRequestResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Persistent account export job identifier."},"status":{"type":"string","enum":["QUEUED","PROCESSING","READY","FAILED","EXPIRED"]},"filters":{"$ref":"#/components/schemas/AccountInvoiceExportFiltersDto"},"filename":{"type":"string","description":"Filename used when the completed archive is downloaded."},"sizeBytes":{"type":"string","nullable":true,"example":"1048576"},"totalInvoices":{"type":"number","example":120},"processedInvoices":{"type":"number","example":45},"errorMessage":{"type":"string","nullable":true},"startedAt":{"format":"date-time","type":"string","nullable":true},"completedAt":{"format":"date-time","type":"string","nullable":true},"expiresAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"reused":{"type":"boolean","description":"Whether an existing reusable export was returned."}},"required":["id","status","filters","filename","totalInvoices","processedInvoices","createdAt","updatedAt","reused"]},"CreateOutboundInvoiceDto":{"type":"object","properties":{"filename":{"type":"string","description":"Original uploaded invoice filename. SdI submission filename is generated by the API.","example":"invoice-example.xml"},"xmlBase64":{"type":"string","description":"Invoice XML or signed XML CAdES (`.xml.p7m`) encoded as base64.","example":"PD94bWwgdmVyc2lvbj0iMS4wIj8+"}},"required":["filename","xmlBase64"]},"CreateOutboundInvoiceResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Created invoice identifier.","example":"invoice_123"},"filename":{"type":"string","description":"SdI-compliant filename generated for submission.","example":"IT12345678901A2026_00001.xml"},"status":{"type":"string","description":"Invoice status after creation/submission handling.","example":"SUBMITTED"},"sdiIdentifier":{"type":"string","description":"SdI identifier when submission was accepted by SdI.","example":"123456789","nullable":true},"error":{"type":"string","description":"Submission error message when the invoice was stored but SdI submission failed.","example":"SdI service unavailable","nullable":true}},"required":["id","filename","status"]},"InvoiceResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Invoice identifier.","example":"invoice_123"},"accountId":{"type":"string","description":"Owning account identifier.","example":"account_123"},"direction":{"type":"string","description":"Invoice direction relative to the account.","example":"OUTBOUND"},"status":{"type":"string","description":"Current invoice processing status.","example":"SUBMITTED"},"source":{"type":"string","description":"Origin of the invoice record. `HISTORICAL_IMPORT` invoices were imported from an archive and can be deleted.","example":"SDI"},"filename":{"type":"string","description":"API-generated or received transport filename.","example":"IT12345678901A2026_00001.xml"},"senderFilename":{"type":"string","description":"Original filename supplied by the account for outbound uploads.","example":"invoice-example.xml","nullable":true},"documentType":{"type":"string","description":"FatturaPA document type (`TipoDocumento`) parsed from the XML, e.g. TD01 or TD17 for an autofattura.","example":"TD01","nullable":true},"invoiceNumber":{"type":"string","description":"Invoice number parsed from the XML payload.","example":"2026-001","nullable":true},"sdiIdentifier":{"type":"string","description":"SdI identifier assigned by Sistema di Interscambio.","example":"123456789","nullable":true},"counterpartyVat":{"type":"string","description":"Counterparty VAT number parsed from the invoice payload.","example":"10987654321","nullable":true},"counterpartyFiscal":{"type":"string","description":"Counterparty fiscal code parsed from the invoice payload.","example":"RSSMRA80A01H501U","nullable":true},"counterpartyName":{"type":"string","description":"Counterparty legal name (Denominazione) parsed from the invoice payload.","example":"Example SRL","nullable":true},"totalAmount":{"type":"string","description":"Invoice total amount as a decimal string.","example":"122.00","nullable":true},"issuedAt":{"format":"date-time","type":"string","description":"Required invoice issue date parsed from the FatturaPA Data field."},"receivedAt":{"format":"date-time","type":"string","description":"Inbound invoice receipt timestamp.","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"Invoice record creation timestamp."},"updatedAt":{"format":"date-time","type":"string","description":"Invoice record last update timestamp."},"documents":{"description":"Stored documents related to the invoice.","type":"array","items":{"$ref":"#/components/schemas/StoredDocumentResponseDto"}},"notifications":{"description":"SdI notifications received for the invoice.","type":"array","items":{"$ref":"#/components/schemas/NotificationResponseDto"}}},"required":["id","accountId","direction","status","source","filename","issuedAt","createdAt","updatedAt","documents","notifications"]},"PaginatedInvoicesResponseDto":{"type":"object","properties":{"items":{"description":"Page of invoices owned by the authenticated account.","type":"array","items":{"$ref":"#/components/schemas/InvoiceResponseDto"}},"total":{"type":"number","description":"Total invoices matching the filters.","example":120},"limit":{"type":"number","description":"Maximum number of invoices requested for this page.","example":50},"offset":{"type":"number","description":"Number of invoices skipped before this page.","example":0},"hasMore":{"type":"boolean","description":"Whether another page is available after this one.","example":true}},"required":["items","total","limit","offset","hasMore"]},"FinancialOverviewMonthDto":{"type":"object","properties":{"key":{"type":"string","description":"Month key in YYYY-MM format.","example":"2026-06"},"label":{"type":"string","description":"Compact month label for dashboard display.","example":"Jun 26"},"expenses":{"type":"number","description":"Inbound invoice amount total for the month.","example":1200},"revenue":{"type":"number","description":"Outbound invoice amount total for the month.","example":2400}},"required":["key","label","expenses","revenue"]},"FinancialOverviewCounterpartyDto":{"type":"object","properties":{"label":{"type":"string","description":"Counterparty display name (denominazione or nome cognome), falling back to VAT/fiscal code.","example":"Acme S.r.l."},"sublabel":{"type":"string","description":"Secondary label with the counterparty VAT number or fiscal code, when a name is shown.","example":"IT12345678901","nullable":true},"amount":{"type":"number","description":"Total inbound invoice amount for this counterparty.","example":1200},"count":{"type":"number","description":"Number of inbound invoices with tracked amounts for this counterparty.","example":3}},"required":["label","sublabel","amount","count"]},"FinancialOverviewStatusDto":{"type":"object","properties":{"status":{"type":"string","description":"Invoice status value.","example":"RECEIVED"},"amount":{"type":"number","description":"Total tracked invoice amount in this status.","example":1200},"count":{"type":"number","description":"Number of invoices with tracked amounts in this status.","example":3}},"required":["status","amount","count"]},"FinancialOverviewResponseDto":{"type":"object","properties":{"totalExpenses":{"type":"number","description":"Total inbound invoice amount.","example":1200},"totalRevenue":{"type":"number","description":"Total outbound invoice amount.","example":2400},"netBalance":{"type":"number","description":"Outbound revenue minus inbound expenses.","example":1200},"totalTrackedAmount":{"type":"number","description":"Total tracked amount across inbound and outbound invoices.","example":3600},"inboundCount":{"type":"number","description":"Number of inbound invoices.","example":12},"outboundCount":{"type":"number","description":"Number of outbound invoices.","example":9},"neutralCount":{"type":"number","description":"Number of autofatture / reverse-charge invoices excluded from expense and revenue totals.","example":3},"neutralAmount":{"type":"number","description":"Tracked amount of autofatture / reverse-charge invoices, excluded from expense and revenue totals.","example":500},"needsAttentionCount":{"type":"number","description":"Number of invoices in warning or error statuses.","example":2},"needsAttentionAmount":{"type":"number","description":"Tracked amount in warning or error statuses.","example":300},"missingAmountCount":{"type":"number","description":"Number of invoices without a total amount.","example":1},"notifications":{"type":"number","description":"Number of notifications attached to account invoices.","example":4},"monthly":{"description":"Last six invoice months with tracked expense and revenue totals.","type":"array","items":{"$ref":"#/components/schemas/FinancialOverviewMonthDto"}},"topExpenseCounterparties":{"description":"Top inbound counterparties by tracked expense amount.","type":"array","items":{"$ref":"#/components/schemas/FinancialOverviewCounterpartyDto"}},"statusBreakdown":{"description":"Tracked invoice amount by status.","type":"array","items":{"$ref":"#/components/schemas/FinancialOverviewStatusDto"}}},"required":["totalExpenses","totalRevenue","netBalance","totalTrackedAmount","inboundCount","outboundCount","neutralCount","neutralAmount","needsAttentionCount","needsAttentionAmount","missingAmountCount","notifications","monthly","topExpenseCounterparties","statusBreakdown"]},"DeleteInvoicesDto":{"type":"object","properties":{"invoiceIds":{"description":"Invoice IDs to delete. Only imported (HISTORICAL_IMPORT) invoices are removed; others are skipped.","example":["invoice_123","invoice_456"],"type":"array","items":{"type":"string"}}},"required":["invoiceIds"]},"DeleteInvoicesResponseDto":{"type":"object","properties":{"deleted":{"type":"number","description":"Number of imported invoices deleted.","example":3},"skipped":{"type":"number","description":"Number of requested invoices skipped because they are not imported or were not found.","example":1}},"required":["deleted","skipped"]},"DownloadInvoicesDto":{"type":"object","properties":{"invoiceIds":{"description":"Invoice IDs to include in the generated ZIP archive.","example":["invoice_123","invoice_456"],"type":"array","items":{"type":"string"}}},"required":["invoiceIds"]},"ImportHistoricalInvoiceIssueDto":{"type":"object","properties":{"filename":{"type":"string","description":"Name of the invoice file inside the archive.","example":"IT00488410010_kRtw7.xml.p7m"},"reason":{"type":"string","description":"Human-readable reason the file was skipped or failed.","example":"An invoice with the same counterparty, number, and date already exists."}},"required":["filename","reason"]},"ImportHistoricalInvoicesResponseDto":{"type":"object","properties":{"totalFiles":{"type":"number","description":"Number of invoice files detected in the archive (metadata sidecars excluded).","example":6},"imported":{"type":"number","description":"Number of invoices newly imported as historical records.","example":4},"skipped":{"description":"Invoices skipped because they already exist for the account.","type":"array","items":{"$ref":"#/components/schemas/ImportHistoricalInvoiceIssueDto"}},"failed":{"description":"Invoice files that could not be imported, with the reason for each.","type":"array","items":{"$ref":"#/components/schemas/ImportHistoricalInvoiceIssueDto"}}},"required":["totalFiles","imported","skipped","failed"]}}}}