> For the complete documentation index, see [llms.txt](https://api.qvalia.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://api.qvalia.io/api-documentation/apis/transaction-api/message-level-status-apis.md).

# Message Level Status APIs

Operations related to MessageLevelStatus

## Get incoming message level status \[transaction-type: MessageLevelStatus]

> The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no "array" function for XML).\
> \
> With JSON, use the \`limit\` parameter to change the number of returned messages and combine it with \`offset\` to traverse through your available messages.\
> \
> To get new messages only, use the  \`"Read"\` endpoint instead!

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"limit":{"name":"limit","in":"query","required":false,"schema":{"type":"number","description":"How many messages to return in Array (XML is always one!)","default":3},"description":"How many messages to return in Array (XML is always one!)"},"offset":{"name":"offset","in":"query","required":false,"schema":{"type":"number","description":"Where to start index for using limit/offset listing","default":0},"description":"Where to start index for using limit/offset listing"},"includeRead":{"name":"includeRead","in":"query","required":false,"schema":{"type":"boolean","description":"If you are using the \"read\" enpoints, make it include previously read messages","default":false},"description":"If you are using the \"read\" enpoints, make it include previously read messages"},"integrationId":{"name":"integrationId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"Qvalia unique identifier for the transaction/message"},"documentId":{"name":"documentId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"The document identifier of teh message, e.g. Invoice number"},"from":{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form; any unambiguous date string the server can\nparse is accepted, but only `YYYY-MM-DD` is guaranteed to keep working.\nThe whole day is included."},"to":{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included."},"updatedAtFrom":{"name":"updatedAtFrom","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\n**NB!** If you send `updatedAtFrom` without `updatedAtTo`, `updatedAtTo`\ndefaults to **today** — the range is not open-ended. Send `updatedAtTo`\nexplicitly if you need a different end date."},"updatedAtTo":{"name":"updatedAtTo","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\nDefaults to **today** when `updatedAtFrom` is supplied without it."}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/transactionResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/transactionResponseXML"}}},"headers":{"integrationid":{"schema":{"type":"string"},"description":"Only included as header in XML!"}}},"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":"Human-readable reason the submission was rejected."},"metadata":{"type":"object","description":"","properties":{"integrationId":{"type":"string","format":"uuid","description":"The document this submission collided with. Present on a duplicate\nrejection, so you can reconcile the submission against the document\nalready stored without a follow-up `GET` — this is the same id the\noriginal, successful submission returned.\n\nRe-submit with `overwrite=true` if you intend to replace it. To avoid\nthe duplicate in the first place, send an `Idempotency-Key`."},"debug_error_message":{"type":"string","description":""},"debug_error_code":{"type":"integer","description":""}}}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"transactionResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"type":"object","description":"Each entry holds the document itself under a key named after the\ntransaction type of the endpoint you called — `Invoice` for\n`/invoices/...`, `CreditNote` for `/creditnotes/...`, and so on —\nalongside `integrationId`.","properties":{"integrationId":{"type":"string","description":"Qvalia unique identifier for the transaction/message"}},"additionalProperties":{"type":"object","description":"The document, keyed by its transaction type."}}}}},"transactionResponseXML":{"type":"object","properties":{"message-data-elements":{"type":"object"}},"xml":{"name":"{transaction-type}"}},"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/incoming":{"get":{"tags":["MessageLevelStatus APIs"],"summary":"Get incoming message level status [transaction-type: MessageLevelStatus]","description":"The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no \"array\" function for XML).\n\nWith JSON, use the `limit` parameter to change the number of returned messages and combine it with `offset` to traverse through your available messages.\n\nTo get new messages only, use the  `\"Read\"` endpoint instead!","operationId":"messagelevelstatus-apis/get-messagelevelstatus-incoming","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/offset"},{"$ref":"#/components/parameters/includeRead"},{"$ref":"#/components/parameters/integrationId"},{"$ref":"#/components/parameters/documentId"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAtFrom"},{"$ref":"#/components/parameters/updatedAtTo"}],"responses":{"200":{"$ref":"#/components/responses/200"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Create incoming message level status \[transaction-type: MessageLevelStatus]

> The request can be either JSON or XML. Each individual message must be POST'ed as an object, JSON Array is not suported!

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"overwrite":{"name":"overwrite","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"For POST requests, chose to overwrite upon a `409 Conflict` response to reprocess the message with the same document ID and receiver (i.e. send the same message again)"},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":8,"maxLength":255,"pattern":"^[\\w.:@+-]+$"},"description":"Optional. Send a unique value you generate per submission (a UUID is recommended!)\nand a repeat of the same request returns the original response, with the original\n`integrationId`, instead of creating a second document.\n\nThis is what makes a submission safe to retry after a timeout: if the connection\nbreaks after we accept the POST but before the response reaches you, repeating it\nwith the same key tells you whether the document was created, without a\nreconciling `GET`.\n\n- Same key, same body, request finished: the original response is replayed.\n- Same key, same body, original still in flight: `409`.\n- Same key, different body: `400`.\n- Key older than 24 hours: treated as new.\n\nA request that fails releases its key, so you can retry the same key after an\nerror. Keys are scoped to your account."}},"responses":{"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":"Human-readable reason the submission was rejected."},"metadata":{"type":"object","description":"","properties":{"integrationId":{"type":"string","format":"uuid","description":"The document this submission collided with. Present on a duplicate\nrejection, so you can reconcile the submission against the document\nalready stored without a follow-up `GET` — this is the same id the\noriginal, successful submission returned.\n\nRe-submit with `overwrite=true` if you intend to replace it. To avoid\nthe duplicate in the first place, send an `Idempotency-Key`."},"debug_error_message":{"type":"string","description":""},"debug_error_code":{"type":"integer","description":""}}}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"200-post":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/transactionPostResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/transactionPostResponseXML"}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"transactionPostResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"message":{"type":"string","description":"Confirmation message. Names the transaction type of the endpoint\nyou called, e.g. `Invoice 100-1000 sent`."},"integrationId":{"type":"string"}},"additionalProperties":{"type":"string","description":"The submitted document's own identifier, under a key named after the\ntransaction type of the endpoint you called — `invoice_id` for\n`/invoices/...`, `creditnote_id` for `/creditnotes/...`, and so on."}}},"xml":{"name":"success"}},"transactionPostResponseXML":{"type":"object","properties":{"message":{"type":"string","description":"Confirmation message. Names the transaction type of the endpoint you\ncalled, e.g. `Invoice 100-1000 sent`."},"integrationId":{"type":"string"}},"additionalProperties":{"type":"string","description":"The submitted document's own identifier, under a key named after the\ntransaction type of the endpoint you called, e.g. `invoice_id`."},"xml":{"name":"success"}},"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}},"ApplicationResponseJSON":{"type":"object","properties":{"ApplicationResponse":{"type":"object","description":"","properties":{}}}},"ApplicationResponse":{"type":"object","description":"","properties":{}}},"requestBodies":{"transactionPostApplicationResponse":{"description":"Request body","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResponseJSON"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/incoming":{"post":{"tags":["MessageLevelStatus APIs"],"summary":"Create incoming message level status [transaction-type: MessageLevelStatus]","description":"The request can be either JSON or XML. Each individual message must be POST'ed as an object, JSON Array is not suported!","operationId":"messagelevelstatus-apis/post-messagelevelstatus-incoming","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/overwrite"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"$ref":"#/components/responses/200-post"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}},"requestBody":{"$ref":"#/components/requestBodies/transactionPostApplicationResponse"}}}}}
```

## Read incoming message level status \[transaction-type: MessageLevelStatus]

> Through this endpoint you will get any unread (=previously fetched) message(s). After you have fetched through this request the message will be automatically marked as \`read\`\
> \
> The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no "array" function for XML).\
> \
> With JSON, use the \`limit\` parameter to change the number of returned messages and combine it with \`offset\` to traverse through your available messages.

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"limit":{"name":"limit","in":"query","required":false,"schema":{"type":"number","description":"How many messages to return in Array (XML is always one!)","default":3},"description":"How many messages to return in Array (XML is always one!)"},"offset":{"name":"offset","in":"query","required":false,"schema":{"type":"number","description":"Where to start index for using limit/offset listing","default":0},"description":"Where to start index for using limit/offset listing"},"includeRead":{"name":"includeRead","in":"query","required":false,"schema":{"type":"boolean","description":"If you are using the \"read\" enpoints, make it include previously read messages","default":false},"description":"If you are using the \"read\" enpoints, make it include previously read messages"},"markUnread":{"name":"markUnread","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Release previously read documents back to the unread pool: selects documents that\nHAVE been read, clears their read mark, and returns them. The next call to this\nendpoint will hand them out again.\n\nUse it to recover when a document was read but the hand-off downstream failed —\nthere is one read mark per document per account, not a per-consumer cursor, so\nwithout this a document is delivered exactly once and cannot be re-requested.\n\n**Must be scoped.** Combine it with at least one of `integrationId`, `documentId`,\n`from` or `updatedAtFrom`; an unscoped call is rejected with `400`, because it\nwould clear the account's entire read state and re-deliver its full history on the\nnext read. `limit` and `offset` do not count as scoping."},"integrationId":{"name":"integrationId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"Qvalia unique identifier for the transaction/message"},"documentId":{"name":"documentId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"The document identifier of teh message, e.g. Invoice number"},"from":{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form; any unambiguous date string the server can\nparse is accepted, but only `YYYY-MM-DD` is guaranteed to keep working.\nThe whole day is included."},"to":{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included."},"updatedAtFrom":{"name":"updatedAtFrom","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\n**NB!** If you send `updatedAtFrom` without `updatedAtTo`, `updatedAtTo`\ndefaults to **today** — the range is not open-ended. Send `updatedAtTo`\nexplicitly if you need a different end date."},"updatedAtTo":{"name":"updatedAtTo","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\nDefaults to **today** when `updatedAtFrom` is supplied without it."}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/transactionResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/transactionResponseXML"}}},"headers":{"integrationid":{"schema":{"type":"string"},"description":"Only included as header in XML!"}}},"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":"Human-readable reason the submission was rejected."},"metadata":{"type":"object","description":"","properties":{"integrationId":{"type":"string","format":"uuid","description":"The document this submission collided with. Present on a duplicate\nrejection, so you can reconcile the submission against the document\nalready stored without a follow-up `GET` — this is the same id the\noriginal, successful submission returned.\n\nRe-submit with `overwrite=true` if you intend to replace it. To avoid\nthe duplicate in the first place, send an `Idempotency-Key`."},"debug_error_message":{"type":"string","description":""},"debug_error_code":{"type":"integer","description":""}}}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"transactionResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"type":"object","description":"Each entry holds the document itself under a key named after the\ntransaction type of the endpoint you called — `Invoice` for\n`/invoices/...`, `CreditNote` for `/creditnotes/...`, and so on —\nalongside `integrationId`.","properties":{"integrationId":{"type":"string","description":"Qvalia unique identifier for the transaction/message"}},"additionalProperties":{"type":"object","description":"The document, keyed by its transaction type."}}}}},"transactionResponseXML":{"type":"object","properties":{"message-data-elements":{"type":"object"}},"xml":{"name":"{transaction-type}"}},"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/incoming/readmessagelevelstatus":{"get":{"tags":["MessageLevelStatus APIs"],"summary":"Read incoming message level status [transaction-type: MessageLevelStatus]","description":"Through this endpoint you will get any unread (=previously fetched) message(s). After you have fetched through this request the message will be automatically marked as `read`\n\nThe response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no \"array\" function for XML).\n\nWith JSON, use the `limit` parameter to change the number of returned messages and combine it with `offset` to traverse through your available messages.","operationId":"messagelevelstatus-apis/get-messagelevelstatus-incoming-read","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/offset"},{"$ref":"#/components/parameters/includeRead"},{"$ref":"#/components/parameters/markUnread"},{"$ref":"#/components/parameters/integrationId"},{"$ref":"#/components/parameters/documentId"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAtFrom"},{"$ref":"#/components/parameters/updatedAtTo"}],"responses":{"200":{"$ref":"#/components/responses/200"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get outgoing message level status \[transaction-type: MessageLevelStatus]

> The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no "array" function for XML).\
> \
> With JSON, use the \`limit\` parameter to change the number of returned messages and combine it with \`offset\` to traverse through your available messages.\
> \
> To get new messages only, use the  \`"Read"\` endpoint instead!

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"limit":{"name":"limit","in":"query","required":false,"schema":{"type":"number","description":"How many messages to return in Array (XML is always one!)","default":3},"description":"How many messages to return in Array (XML is always one!)"},"offset":{"name":"offset","in":"query","required":false,"schema":{"type":"number","description":"Where to start index for using limit/offset listing","default":0},"description":"Where to start index for using limit/offset listing"},"includeRead":{"name":"includeRead","in":"query","required":false,"schema":{"type":"boolean","description":"If you are using the \"read\" enpoints, make it include previously read messages","default":false},"description":"If you are using the \"read\" enpoints, make it include previously read messages"},"integrationId":{"name":"integrationId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"Qvalia unique identifier for the transaction/message"},"documentId":{"name":"documentId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"The document identifier of teh message, e.g. Invoice number"},"from":{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form; any unambiguous date string the server can\nparse is accepted, but only `YYYY-MM-DD` is guaranteed to keep working.\nThe whole day is included."},"to":{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included."},"updatedAtFrom":{"name":"updatedAtFrom","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\n**NB!** If you send `updatedAtFrom` without `updatedAtTo`, `updatedAtTo`\ndefaults to **today** — the range is not open-ended. Send `updatedAtTo`\nexplicitly if you need a different end date."},"updatedAtTo":{"name":"updatedAtTo","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\nDefaults to **today** when `updatedAtFrom` is supplied without it."}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/transactionResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/transactionResponseXML"}}},"headers":{"integrationid":{"schema":{"type":"string"},"description":"Only included as header in XML!"}}},"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":"Human-readable reason the submission was rejected."},"metadata":{"type":"object","description":"","properties":{"integrationId":{"type":"string","format":"uuid","description":"The document this submission collided with. Present on a duplicate\nrejection, so you can reconcile the submission against the document\nalready stored without a follow-up `GET` — this is the same id the\noriginal, successful submission returned.\n\nRe-submit with `overwrite=true` if you intend to replace it. To avoid\nthe duplicate in the first place, send an `Idempotency-Key`."},"debug_error_message":{"type":"string","description":""},"debug_error_code":{"type":"integer","description":""}}}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"transactionResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"type":"object","description":"Each entry holds the document itself under a key named after the\ntransaction type of the endpoint you called — `Invoice` for\n`/invoices/...`, `CreditNote` for `/creditnotes/...`, and so on —\nalongside `integrationId`.","properties":{"integrationId":{"type":"string","description":"Qvalia unique identifier for the transaction/message"}},"additionalProperties":{"type":"object","description":"The document, keyed by its transaction type."}}}}},"transactionResponseXML":{"type":"object","properties":{"message-data-elements":{"type":"object"}},"xml":{"name":"{transaction-type}"}},"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/outgoing":{"get":{"tags":["MessageLevelStatus APIs"],"summary":"Get outgoing message level status [transaction-type: MessageLevelStatus]","description":"The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no \"array\" function for XML).\n\nWith JSON, use the `limit` parameter to change the number of returned messages and combine it with `offset` to traverse through your available messages.\n\nTo get new messages only, use the  `\"Read\"` endpoint instead!","operationId":"messagelevelstatus-apis/get-messagelevelstatus-outgoing","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/offset"},{"$ref":"#/components/parameters/includeRead"},{"$ref":"#/components/parameters/integrationId"},{"$ref":"#/components/parameters/documentId"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAtFrom"},{"$ref":"#/components/parameters/updatedAtTo"}],"responses":{"200":{"$ref":"#/components/responses/200"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Create message level status \[transaction-type: MessageLevelStatus]

> The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no "array" function for XML).\
> \
> With JSON, use the \`limit\` parameter to change the number of returned messages and combine it with \`offset\` to traverse through your available messages.\
> \
> To get new messages only, use the  \`"Read"\` endpoint instead!

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"overwrite":{"name":"overwrite","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"For POST requests, chose to overwrite upon a `409 Conflict` response to reprocess the message with the same document ID and receiver (i.e. send the same message again)"},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":8,"maxLength":255,"pattern":"^[\\w.:@+-]+$"},"description":"Optional. Send a unique value you generate per submission (a UUID is recommended!)\nand a repeat of the same request returns the original response, with the original\n`integrationId`, instead of creating a second document.\n\nThis is what makes a submission safe to retry after a timeout: if the connection\nbreaks after we accept the POST but before the response reaches you, repeating it\nwith the same key tells you whether the document was created, without a\nreconciling `GET`.\n\n- Same key, same body, request finished: the original response is replayed.\n- Same key, same body, original still in flight: `409`.\n- Same key, different body: `400`.\n- Key older than 24 hours: treated as new.\n\nA request that fails releases its key, so you can retry the same key after an\nerror. Keys are scoped to your account."}},"responses":{"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":"Human-readable reason the submission was rejected."},"metadata":{"type":"object","description":"","properties":{"integrationId":{"type":"string","format":"uuid","description":"The document this submission collided with. Present on a duplicate\nrejection, so you can reconcile the submission against the document\nalready stored without a follow-up `GET` — this is the same id the\noriginal, successful submission returned.\n\nRe-submit with `overwrite=true` if you intend to replace it. To avoid\nthe duplicate in the first place, send an `Idempotency-Key`."},"debug_error_message":{"type":"string","description":""},"debug_error_code":{"type":"integer","description":""}}}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"200-post":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/transactionPostResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/transactionPostResponseXML"}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"transactionPostResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"message":{"type":"string","description":"Confirmation message. Names the transaction type of the endpoint\nyou called, e.g. `Invoice 100-1000 sent`."},"integrationId":{"type":"string"}},"additionalProperties":{"type":"string","description":"The submitted document's own identifier, under a key named after the\ntransaction type of the endpoint you called — `invoice_id` for\n`/invoices/...`, `creditnote_id` for `/creditnotes/...`, and so on."}}},"xml":{"name":"success"}},"transactionPostResponseXML":{"type":"object","properties":{"message":{"type":"string","description":"Confirmation message. Names the transaction type of the endpoint you\ncalled, e.g. `Invoice 100-1000 sent`."},"integrationId":{"type":"string"}},"additionalProperties":{"type":"string","description":"The submitted document's own identifier, under a key named after the\ntransaction type of the endpoint you called, e.g. `invoice_id`."},"xml":{"name":"success"}},"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}},"ApplicationResponseJSON":{"type":"object","properties":{"ApplicationResponse":{"type":"object","description":"","properties":{}}}},"ApplicationResponse":{"type":"object","description":"","properties":{}}},"requestBodies":{"transactionPostApplicationResponse":{"description":"Request body","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResponseJSON"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/outgoing":{"post":{"tags":["MessageLevelStatus APIs"],"summary":"Create message level status [transaction-type: MessageLevelStatus]","description":"The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no \"array\" function for XML).\n\nWith JSON, use the `limit` parameter to change the number of returned messages and combine it with `offset` to traverse through your available messages.\n\nTo get new messages only, use the  `\"Read\"` endpoint instead!","operationId":"messagelevelstatus-apis/post-messagelevelstatus-outgoing","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/overwrite"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"$ref":"#/components/responses/200-post"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}},"requestBody":{"$ref":"#/components/requestBodies/transactionPostApplicationResponse"}}}}}
```

## Read message level statuss \[transaction-type: MessageLevelStatus]

> Through this endpoint you will get any unread (=previously fetched) message(s). After you have fetched through this request the message will be automatically marked as \`read\`\
> \
> The response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no "array" function for XML).\
> \
> With JSON, use the \`limit\` parameter to change the number of returned messages and combine it with \`offset\` to traverse through your available messages.

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"limit":{"name":"limit","in":"query","required":false,"schema":{"type":"number","description":"How many messages to return in Array (XML is always one!)","default":3},"description":"How many messages to return in Array (XML is always one!)"},"offset":{"name":"offset","in":"query","required":false,"schema":{"type":"number","description":"Where to start index for using limit/offset listing","default":0},"description":"Where to start index for using limit/offset listing"},"includeRead":{"name":"includeRead","in":"query","required":false,"schema":{"type":"boolean","description":"If you are using the \"read\" enpoints, make it include previously read messages","default":false},"description":"If you are using the \"read\" enpoints, make it include previously read messages"},"markUnread":{"name":"markUnread","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Release previously read documents back to the unread pool: selects documents that\nHAVE been read, clears their read mark, and returns them. The next call to this\nendpoint will hand them out again.\n\nUse it to recover when a document was read but the hand-off downstream failed —\nthere is one read mark per document per account, not a per-consumer cursor, so\nwithout this a document is delivered exactly once and cannot be re-requested.\n\n**Must be scoped.** Combine it with at least one of `integrationId`, `documentId`,\n`from` or `updatedAtFrom`; an unscoped call is rejected with `400`, because it\nwould clear the account's entire read state and re-deliver its full history on the\nnext read. `limit` and `offset` do not count as scoping."},"integrationId":{"name":"integrationId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"Qvalia unique identifier for the transaction/message"},"documentId":{"name":"documentId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"The document identifier of teh message, e.g. Invoice number"},"from":{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form; any unambiguous date string the server can\nparse is accepted, but only `YYYY-MM-DD` is guaranteed to keep working.\nThe whole day is included."},"to":{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included."},"updatedAtFrom":{"name":"updatedAtFrom","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\n**NB!** If you send `updatedAtFrom` without `updatedAtTo`, `updatedAtTo`\ndefaults to **today** — the range is not open-ended. Send `updatedAtTo`\nexplicitly if you need a different end date."},"updatedAtTo":{"name":"updatedAtTo","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\nDefaults to **today** when `updatedAtFrom` is supplied without it."}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/transactionResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/transactionResponseXML"}}},"headers":{"integrationid":{"schema":{"type":"string"},"description":"Only included as header in XML!"}}},"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":"Human-readable reason the submission was rejected."},"metadata":{"type":"object","description":"","properties":{"integrationId":{"type":"string","format":"uuid","description":"The document this submission collided with. Present on a duplicate\nrejection, so you can reconcile the submission against the document\nalready stored without a follow-up `GET` — this is the same id the\noriginal, successful submission returned.\n\nRe-submit with `overwrite=true` if you intend to replace it. To avoid\nthe duplicate in the first place, send an `Idempotency-Key`."},"debug_error_message":{"type":"string","description":""},"debug_error_code":{"type":"integer","description":""}}}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"transactionResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"type":"object","description":"Each entry holds the document itself under a key named after the\ntransaction type of the endpoint you called — `Invoice` for\n`/invoices/...`, `CreditNote` for `/creditnotes/...`, and so on —\nalongside `integrationId`.","properties":{"integrationId":{"type":"string","description":"Qvalia unique identifier for the transaction/message"}},"additionalProperties":{"type":"object","description":"The document, keyed by its transaction type."}}}}},"transactionResponseXML":{"type":"object","properties":{"message-data-elements":{"type":"object"}},"xml":{"name":"{transaction-type}"}},"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/outgoing/readmessagelevelstatus":{"get":{"tags":["MessageLevelStatus APIs"],"summary":"Read message level statuss [transaction-type: MessageLevelStatus]","description":"Through this endpoint you will get any unread (=previously fetched) message(s). After you have fetched through this request the message will be automatically marked as `read`\n\nThe response, in JSON, will always include the three latest messages, per default. Using XML you always only get one (as there's no \"array\" function for XML).\n\nWith JSON, use the `limit` parameter to change the number of returned messages and combine it with `offset` to traverse through your available messages.","operationId":"messagelevelstatus-apis/get-messagelevelstatus-outgoing-read","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/offset"},{"$ref":"#/components/parameters/includeRead"},{"$ref":"#/components/parameters/markUnread"},{"$ref":"#/components/parameters/integrationId"},{"$ref":"#/components/parameters/documentId"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAtFrom"},{"$ref":"#/components/parameters/updatedAtTo"}],"responses":{"200":{"$ref":"#/components/responses/200"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get incoming message level status statuses \[transaction-type: MessageLevelStatus]

> Returns lightweight delivery/processing status metadata for the matching messages — the message \`uuid\`, the incoming \`readAt\` timestamp and a \`metadata\` object whose \`status\` reflects the latest message-log status — WITHOUT the heavy document payload.\
> \
> Uses the same query-string filters as the resource's GET on \`/incoming\` and \`/outgoing\`. By default only unread messages are returned; set \`includeRead=true\` to also include previously read messages.\
> \
> The response is always JSON (an array of status objects); there is no XML representation for this endpoint.

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"limit":{"name":"limit","in":"query","required":false,"schema":{"type":"number","description":"How many messages to return in Array (XML is always one!)","default":3},"description":"How many messages to return in Array (XML is always one!)"},"offset":{"name":"offset","in":"query","required":false,"schema":{"type":"number","description":"Where to start index for using limit/offset listing","default":0},"description":"Where to start index for using limit/offset listing"},"includeRead":{"name":"includeRead","in":"query","required":false,"schema":{"type":"boolean","description":"If you are using the \"read\" enpoints, make it include previously read messages","default":false},"description":"If you are using the \"read\" enpoints, make it include previously read messages"},"integrationId":{"name":"integrationId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"Qvalia unique identifier for the transaction/message"},"documentId":{"name":"documentId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"The document identifier of teh message, e.g. Invoice number"},"from":{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form; any unambiguous date string the server can\nparse is accepted, but only `YYYY-MM-DD` is guaranteed to keep working.\nThe whole day is included."},"to":{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included."},"updatedAtFrom":{"name":"updatedAtFrom","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\n**NB!** If you send `updatedAtFrom` without `updatedAtTo`, `updatedAtTo`\ndefaults to **today** — the range is not open-ended. Send `updatedAtTo`\nexplicitly if you need a different end date."},"updatedAtTo":{"name":"updatedAtTo","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\nDefaults to **today** when `updatedAtFrom` is supplied without it."}},"responses":{"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"statusResponse":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string","format":"uuid","description":"Qvalia unique identifier for the transaction/message"},"readAt":{"type":"string","format":"date-time","nullable":true,"description":"When the (incoming) message was marked as read, or `null` if unread/not applicable"},"metadata":{"type":"object","description":"Status metadata for the message. The `status` property reflects the latest message-log status.","properties":{"status":{"type":"string"}}}}}}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/incoming/status":{"get":{"tags":["MessageLevelStatus APIs"],"summary":"Get incoming message level status statuses [transaction-type: MessageLevelStatus]","description":"Returns lightweight delivery/processing status metadata for the matching messages — the message `uuid`, the incoming `readAt` timestamp and a `metadata` object whose `status` reflects the latest message-log status — WITHOUT the heavy document payload.\n\nUses the same query-string filters as the resource's GET on `/incoming` and `/outgoing`. By default only unread messages are returned; set `includeRead=true` to also include previously read messages.\n\nThe response is always JSON (an array of status objects); there is no XML representation for this endpoint.","operationId":"messagelevelstatus-apis/get-messagelevelstatus-incoming-status","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/offset"},{"$ref":"#/components/parameters/includeRead"},{"$ref":"#/components/parameters/integrationId"},{"$ref":"#/components/parameters/documentId"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAtFrom"},{"$ref":"#/components/parameters/updatedAtTo"}],"responses":{"200":{"$ref":"#/components/responses/statusResponse"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get outgoing message level status statuses \[transaction-type: MessageLevelStatus]

> Returns lightweight delivery/processing status metadata for the matching messages — the message \`uuid\`, the incoming \`readAt\` timestamp and a \`metadata\` object whose \`status\` reflects the latest message-log status — WITHOUT the heavy document payload.\
> \
> Uses the same query-string filters as the resource's GET on \`/incoming\` and \`/outgoing\`. By default only unread messages are returned; set \`includeRead=true\` to also include previously read messages.\
> \
> The response is always JSON (an array of status objects); there is no XML representation for this endpoint.

```json
{"openapi":"3.0.2","info":{"title":"Qvalia Transaction API","version":"1.0.0"},"tags":[{"name":"MessageLevelStatus APIs","description":"Operations related to MessageLevelStatus"}],"servers":[{"url":"https://api-test.qvalia.com"},{"url":"https://api.qvalia.com"}],"security":[{"api_key":[]},{"jwt":[]}],"components":{"securitySchemes":{"api_key":{"type":"apiKey","name":"Authorization","in":"header"},"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT-based authentication. The Authorization header must be set as:\nAuthorization: Bearer <token>\nObtain a token via POST /token/{accountRegNo} (see Authentication API).\n"}},"parameters":{"accountRegNo":{"name":"accountRegNo","in":"path","required":true,"schema":{"type":"string","description":"","default":""},"description":"Account registration number issued by Qvalia"},"limit":{"name":"limit","in":"query","required":false,"schema":{"type":"number","description":"How many messages to return in Array (XML is always one!)","default":3},"description":"How many messages to return in Array (XML is always one!)"},"offset":{"name":"offset","in":"query","required":false,"schema":{"type":"number","description":"Where to start index for using limit/offset listing","default":0},"description":"Where to start index for using limit/offset listing"},"includeRead":{"name":"includeRead","in":"query","required":false,"schema":{"type":"boolean","description":"If you are using the \"read\" enpoints, make it include previously read messages","default":false},"description":"If you are using the \"read\" enpoints, make it include previously read messages"},"integrationId":{"name":"integrationId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"Qvalia unique identifier for the transaction/message"},"documentId":{"name":"documentId","in":"query","required":false,"schema":{"type":"string","description":"","default":""},"description":"The document identifier of teh message, e.g. Invoice number"},"from":{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form; any unambiguous date string the server can\nparse is accepted, but only `YYYY-MM-DD` is guaranteed to keep working.\nThe whole day is included."},"to":{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on creation date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included."},"updatedAtFrom":{"name":"updatedAtFrom","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, from this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\n**NB!** If you send `updatedAtFrom` without `updatedAtTo`, `updatedAtTo`\ndefaults to **today** — the range is not open-ended. Send `updatedAtTo`\nexplicitly if you need a different end date."},"updatedAtTo":{"name":"updatedAtTo","in":"query","required":false,"schema":{"type":"string"},"description":"Filter on last-updated date, to this date inclusive. `YYYY-MM-DD` is the\ndocumented and recommended form. The whole day is included.\n\nDefaults to **today** when `updatedAtFrom` is supplied without it."}},"responses":{"204":{"description":"No Content. The request succeeded and there is no body to return."},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized. Returned when the API key or Bearer token is missing, malformed\nor not valid for the account in the URI.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden. The credentials are valid, but the account is not permitted to\nperform this action — typically because the required integration feature or\nscope is not enabled on the account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":""},"type":{"type":"string","description":""},"data":{"type":"string","description":""},"metadata":{"type":"object","description":"","properties":{"description":{"type":"string","description":""},"details":{"type":"object","description":"","properties":{}}}}}}}}},"500":{"description":"Internal Server Error. `metadata` is deliberately omitted on a 500 — no\ninternal detail is returned. Try again; if the problem persists contact\nhelp@qvalia.com.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"type":{"type":"string"},"data":{"type":"string"}}}}}},"statusResponse":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string","format":"uuid","description":"Qvalia unique identifier for the transaction/message"},"readAt":{"type":"string","format":"date-time","nullable":true,"description":"When the (incoming) message was marked as read, or `null` if unread/not applicable"},"metadata":{"type":"object","description":"Status metadata for the message. The `status` property reflects the latest message-log status.","properties":{"status":{"type":"string"}}}}}}}}},"TooManyRequests":{"description":"Too Many Requests. The account has exceeded its request budget, which is counted\nper account across all Qvalia APIs.\n\nRead `Retry-After` and wait at least that many seconds before retrying — retrying\nimmediately is simply rejected again. `RateLimit-Remaining` on every response tells\nyou how much of the budget is left, so a well-behaved client need not hit this at\nall. Contact [Qvalia Helpdesk](https://qvalia.com/help/) if your integration needs\na higher limit.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Every error returned by the Qvalia APIs uses this envelope. `type` is a\nstable machine-readable code — branch on it rather than on `data`, which is\na human-readable message whose wording may change.","properties":{"status":{"type":"string","description":"Always `error` on a failed request."},"type":{"type":"string","description":"Stable error code. One of `E_BAD_REQUEST` (400),\n`E_UNAUTHORIZED_CLIENT` / `E_CLIENT_UNSUCCESSFUL_AUTHENTICATION` (401),\n`E_MISSING_PERMISSION` (403), `E_MISSING` (404), `E_CONFLICT` (409),\n`E_VALIDATION` / `E_PEPPOL_PARTICIPANT_SMP_LOOKUP` (422),\n`E_RATE_LIMITED` (429), `E_NOT_IMPLEMENTED` (501) or\n`E_INTERNAL_PROXY_ERROR` (500)."},"data":{"type":"string","description":"Human-readable description of what went wrong."},"metadata":{"type":"object","description":"Additional detail about the failure. The shape varies by error type — a `429`\ncarries `limit` and `retryAfterSeconds`, a `409` carries the colliding\n`integrationId` — and it is omitted entirely on a `500`. Treat it as an open\nmap and read only the keys you need.","additionalProperties":true,"properties":{"debug_error_message":{"type":"string","description":"Longer explanation intended for a developer reading a log."},"debug_error_code":{"type":"integer","description":"Echoes the HTTP status code."}}}}}}},"paths":{"/transaction/{accountRegNo}/messagelevelstatus/outgoing/status":{"get":{"tags":["MessageLevelStatus APIs"],"summary":"Get outgoing message level status statuses [transaction-type: MessageLevelStatus]","description":"Returns lightweight delivery/processing status metadata for the matching messages — the message `uuid`, the incoming `readAt` timestamp and a `metadata` object whose `status` reflects the latest message-log status — WITHOUT the heavy document payload.\n\nUses the same query-string filters as the resource's GET on `/incoming` and `/outgoing`. By default only unread messages are returned; set `includeRead=true` to also include previously read messages.\n\nThe response is always JSON (an array of status objects); there is no XML representation for this endpoint.","operationId":"messagelevelstatus-apis/get-messagelevelstatus-outgoing-status","parameters":[{"$ref":"#/components/parameters/accountRegNo"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/offset"},{"$ref":"#/components/parameters/includeRead"},{"$ref":"#/components/parameters/integrationId"},{"$ref":"#/components/parameters/documentId"},{"$ref":"#/components/parameters/from"},{"$ref":"#/components/parameters/to"},{"$ref":"#/components/parameters/updatedAtFrom"},{"$ref":"#/components/parameters/updatedAtTo"}],"responses":{"200":{"$ref":"#/components/responses/statusResponse"},"204":{"$ref":"#/components/responses/204"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/500"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://api.qvalia.io/api-documentation/apis/transaction-api/message-level-status-apis.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
