Skip to main content
Version: 1.0.1

Kazakhstan E-Invoice


How to get “API Key” from Portal ?​

To obtain the API key to be used in the request body of the login endpoint, navigate to Settings > ERP Management > API Management in the Portal and use the "Generate" button.

Login and Authorization Configuration​

Technical Details​

PropertyValue
Endpoint/auth/login
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationNone (Initial access)

Request Body (JSON)​

The following fields are used to define login criteria:

FieldTypeDescription
apiKeyStringA unique key assigned specifically to the user for portal access, verifying the system identity. (it is explained in previous section “How to get API Key from portal”)
emailStringThe registered email address in the system belonging to the authorized user performing the operation.

Response Details​

Upon a successful request, a 200 OK code is returned with the following details:

FieldTypeDescription
jwt—The secure session token that must be used as a 'R-Auth' API Key in all subsequent API calls.
expirationDateDateTimeIndicates the exact time the session key will expire; the ERP system can use this data to manage automatic re-login processes.

The JWT token successfully obtained during the authentication step (auth/login) acts as a key to access the secure endpoints of the APIs. After the first successful login, the JWT token obtained from the response of a successful login is used as the R-Auth value in the authorization section of other queries. This configuration ensures that every data exchange between the ERP and the portal occurs over an authenticated and secure channel.

Using the R-Auth Header in Requests​

PropertyValue
KeyEnter R-Auth in the Key field.
Value{{apiKey}} or {{jwt}} (Copy the jwt string returned from the login endpoint.)
Header SettingNavigate to the "Headers" tab of the request to be sent.

1. Introduction​

This guide is structured to allow development teams to incorporate portal features into their business workflows with minimum effort and maximum compliance.

⚠️ Availability (October 2026): The following are available on the stage environment and are not yet on production: SNT, AVR and VWH documents on send-document-async (Section 4), the AVR endpoints under /api/sap/awp and /api/awp (AVR section), the KGD registration number of an AVR, and the status credit described below. The AVR PDF (AVR section, 4. Download AVR PDF) is not yet on stage either. Production availability will be announced separately.

Status credit (KGD status updates)​

Every new status that KGD reports for a Kazakhstan document costs one credit, taken from the same plan as the document credit and charged on top of it. This applies to ESF, SNT, AVR and virtual warehouse (VWH UForm and ZVT) documents, in both directions.

  • The same status is charged once per document: a document that goes CREATED → DELIVERED → CREATED pays for CREATED once.
  • The first status read after an upload is charged too.
  • Statuses are charged whether Docnova reads them on its own schedule or one of the status endpoints below asks KGD.
  • Companies that are exempt are not charged; their statuses are still recorded.

When the company has no credit left:

  • Docnova stops asking KGD about that company's documents and resumes on its own once credit is added. Pending documents are not marked as failed.
  • The endpoints that ask KGD for a status answer HTTP 400 with errorType LIFECYCLE_CREDIT_EXHAUSTED without calling KGD: /esf/get-invoice-status-list-by-id, /esf/unread-invoices (only when there are unread invoices to ask about), /snt/query-snt-status-by-id, /snt/query-status-by-regnum, /esf/awp/query-status-by-id, /kz/vwh/internal/uform/{id}/status, /kz/vwh/internal/uform/details/{id} and /kz/vwh/internal/zvt/regnum. Send the same request again after credit is added.
  • Status responses gain two fields: statusSyncPaused (true) and statusSyncPausedReason. Both are omitted when updates are not paused; no existing field changes. They appear in additionalData of Section 8 (Document Status), at the top level of Section 9 and Section 10, and at the top level of the AVR responses (/api/sap/awp/create, GET /api/awp/{id}).
{
"statusSyncPaused": true,
"statusSyncPausedReason": "Kazakhstan document status updates are paused: the company has no credits left. Add credits to resume."
}

2. Authentication POST​

Purpose of Use: This endpoint is utilized by ERP systems to obtain the session key (JWT Token) required to establish a secure connection and initiate data exchange with the docnova portal.

An enterprise ERP system must trigger this endpoint to receive a valid authentication token before performing actions such as transmitting invoices or querying compliance reports via the portal. The acquired token is then provided in the "Authorization" header for all subsequent API requests. This mechanism ensures that data traffic between the ERP and the portal is conducted via a secure, time-bound key rather than transmitting sensitive user credentials for every transaction.

Endpoint Information​

PropertyValue
URL/auth/login
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationNot required (public endpoint)

Example Request​

curl --location 'https://api-stage.docnova.ai/auth/login' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--data-raw '{
"apiKey": "{{your_api_key}}",
"email": "user@example.com"
}'

Request Parameters​

FieldTypeRequiredDescription
emailStringOptionalUser's registered email address
apiKeyStringYesObtained from the portal, via the settings > ERP Management > API Management menu.

Responses​


200 - Login Successful​

Full Response (AccountInfo)

{
"id": "a1b2c3d4-e5f6-7890-abcd-...",
"superAdmin": false,
"companies": [
{
"id": "60ccd1a7-5348-47b2-9ef6-...",
"name": "Example Company LLP",
"taxNumber": "123456789012",
"vatNumber": "123456789012",
"email": "info@example.com",
"website": "https://www.example.com",
"address": "Kabanbay Batyr Ave 15",
"city": "Astana",
"state": "Astana",
"country": "KZ",
"postalCode": "010000",
"phoneNumber": "+7 7172 123456",
"credit": 1000,
"userCount": 5,
"portalType": "KZ",
"mailLanguage": "RU",
"currencyCode": "KZT",
"sftp": false,
"isSubCompany": false,
"featureAllowed": true,
"participants": []
}
],
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expirationDate": "2026-01-30T10:30:00.000Z",
"refreshToken": "refresh-token-string",
"refreshTokenExpiration": "2026-02-28T10:30:00.000Z",
"user": {
"id": "user-uuid",
"email": "user@example.com",
"firstName": "Aidar",
"lastName": "Nurlanov",
"phoneNumber": "+7 701 1234567",
"photoUrl": "https://example.com/photo.jpg",
"mailLang": "RU",
"isSuperAdmin": false,
"lastLoginTime": "2026-01-29T10:30:00",
"featureAllowed": true
},
"mfaEnabled": false,
"mfaType": null,
"secretImageUri": null,
"lastCompanyId": "60ccd1a7-5348-47b2-9ef6-...",
"requiresRecaptchaV2": false,
"message": null,
"active": true,
"isAppLogin": false
}

Basic Response (JwtBasicResponse)​

{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expirationDate": "2026-01-30T10:30:00.000Z"
}

Response Fields​


Account Information Fields​

FieldTypeDescription
idStringUser unique identifier
superAdminBooleanWhether user has super admin privileges
companiesArray<AuthorizedCompany>List of companies user is authorized to access
jwtStringJWT access token. Used in R-Auth header for API requests
expirationDateDateTimeJWT token expiration date
refreshTokenStringRefresh token for obtaining new access tokens
refreshTokenExpirationDateTimeRefresh token expiration date
userObjectUser detail information
mfaEnabledBooleanWhether multi factor authentication is enabled
mfaTypeEnumMFA type (GOOGLE, WHATSAPP)
secretImageUriStringGoogle Authenticator QR code URI
lastCompanyIdStringLast selected company ID
requiresRecaptchaV2BooleanWhether reCAPTCHA v2 verification is required
messageStringStatus message (e.g., "MFA required")
activeBooleanWhether user account is active
isAppLoginBooleanWhether this is a mobile app login

Parameter Values Reference Table​

currentCountry Values (Relevant to Kazakhstan)​

ValueDescription
KZKazakhstan
GLOBALGlobal (default, used before a company has selected a country)

Shared enum: currentCountry is a platform-wide field shared by every country the portal operates in; only KZ is relevant to a Kazakhstan company.

Company Information Fields​

FieldTypeDescription
idStringCompany unique identifier
nameStringCompany name
taxNumberStringTax number
vatNumberStringVAT number
emailStringCompany email address
websiteStringCompany website
addressStringAddress
cityStringCity
stateStringState or Region
countryEnumCountry code
postalCodeStringPostal code
phoneNumberStringPhone number
faxNumberStringFax number
creditIntegerAvailable credit
userCountIntegerTotal user count
portalTypeEnumPortal type
mailLanguageEnumEmail language
currencyCodeStringCurrency code
sftpBooleanWhether SFTP integration is active
isSubCompanyBooleanWhether it's a sub company
featureAllowedBooleanWhether feature access is granted
participantsArrayPeppol participant information

User Information Fields​

FieldTypeDescription
idStringUser unique identifier
emailStringUser email address
firstNameStringUser first name
lastNameStringUser last name
phoneNumberStringUser phone number
photoUrlStringUser photo URL
mailLangEnumUser email language
isSuperAdminBooleanWhether user has super admin privileges
lastLoginTimeDateTimeLast login time
featureAllowedBooleanWhether feature access is granted

Enum Values Reference Table​

mfaType Values​

ValueDescription
GOOGLEGoogle Authenticator verification
WHATSAPPWhatsApp verification

portalType Values (Relevant to Kazakhstan)​

ValueDescription
KZKazakhstan portal
DEFAULTDefault portal (used when no country-specific portal applies)

mailLanguage Values (Relevant to Kazakhstan)​

ValueDescription
KKKazakh
RURussian
ENEnglish

Shared enum: mailLanguage also accepts the platform's other supported languages (DE, ES, FR, IT, MS, NL, PL, RO, TR), but a Kazakhstan company only needs KK, RU or EN — these are also the three languages the ESF PDF stylesheet (Section 7) can render.

200 - Login Successful​

Basic Response (JwtBasicResponse)

{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expirationDate": "2026-01-30T10:30:00.000Z"
}

401 - Unauthorized​

{
"timestamp": "2026-01-29T10:30:00.000Z",
"status": 401,
"error": "Unauthorized",
"message": "Invalid email or password"
}

403 - MFA Required​

{
"id": "user-uuid",
"mfaEnabled": true,
"mfaType": "GOOGLE",
"message": "MFA verification required",
"jwt": null
}

429 - Too Many Requests​

{
"timestamp": "2026-01-29T10:30:00.000Z",
"status": 429,
"error": "Too Many Requests",
"message": "Too many failed login attempts. Please try again later.",
"requiresRecaptchaV2": true
}

3. Send Document (Synchronous) POST​

Purpose of Use: The POST /invoice/send-document endpoint is the legacy synchronous ERP submission path. For Kazakhstan it accepts a Base64-encoded ESF V2 XML document, recognizes it, creates the shared invoice record, submits it to the ESF service and returns the result — all within a single HTTP call. This is currently the only country that calls this legacy endpoint; every other integration uses the asynchronous equivalents below.

⚠️ Note: Because the ESF submission (signing + SOAP upload) happens inline, this call can take longer than send-document-async. For high-volume ERPs, prefer the asynchronous endpoint and poll /invoice/document-status/{trackingId} instead.

Endpoint Information​

PropertyValue
URL/invoice/send-document
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/send-document' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"compId": "79499e36-6d45-4c7d-bc52-...",
"base64Document": "<BASE64_ENCODED_ESF_V2_XML>",
"receiverEmails": ["buyer@example.kz"],
"mailTemplateId": null,
"validationVersion": null
}'

Request Parameters​

FieldTypeRequiredDescription
compIdString (UUID)YesThe company the document is filed against. The authenticated user must belong to this company.
base64DocumentString (Base64)Yes*Base64-encoded ESF V2 XML. Required unless base64Pdf is supplied instead (ZUGFeRD-style PDF intake; not used for KZ ESF).
base64PdfString (Base64)NoNot applicable to Kazakhstan ESF submissions — present for ZUGFeRD-family countries only.
receiverEmailsArray<String>NoRecipient email addresses for the generated invoice notification.
mailTemplateIdStringNoCustom email template identifier.
validationVersionStringNoNot used for Kazakhstan; relevant to France only.

Responses​

200 - Processing Result​

⚠️ Note: This endpoint always answers with HTTP 200, even on failure — check the message/errors fields to determine the real outcome.

{
"uuid": "b34afc0b-4f5d-4670-910c-...",
"trackingId": "dd240417-5896-4577-ae51-...",
"message": null,
"peppolSendingResult": null,
"invoiceNumber": "00900023888",
"errors": [],
"target": null,
"additionalData": {
"kgdInvoiceId": 22116203282,
"esfStatus": "KZ_CREATED"
},
"processing": null
}

Response Field Descriptions​

FieldTypeDescription
uuidUUID | nullShared invoice identifier. Null when the document could not be saved.
trackingIdUUIDIdentifier of the document-processing record created for this call.
messageString | null"ERROR" when the submission failed; null on success.
peppolSendingResultString (Enum) | nullNot populated for Kazakhstan (Peppol-only field).
invoiceNumberString | nullInvoice number extracted from the ESF XML.
errorsArray<String>List of error messages. Empty on success.
targetString (Enum) | nullNot populated for Kazakhstan.
additionalDataObject | nullKZ-specific metadata: kgdInvoiceId (the provider's numeric invoice id) and esfStatus (see the ESF status table in Section 10 — Get Document Status by Document ID).
processingBoolean | nulltrue when the ESF result could not be confirmed yet and is being reconciled with the provider; the official outcome is neither accepted nor rejected. Null for every other outcome.

403 - Forbidden​

Returned when the authenticated user does not belong to the company identified by compId.

401 - Unauthorized​

Returned when the R-Auth header is missing, invalid, or expired.

4. Send Document Async POST​

Purpose of Use: This endpoint lets an ERP system hand a Kazakhstan document to Docnova for submission to KGD (IS ESF) without waiting for KGD. It accepts every Kazakhstan document type: the ESF invoice (invoiceType), the SNT waybill and the AVR (waybillType), and the six virtual warehouse U-Forms (warehouseDocumentType).

The ERP sends the KGD XML document itself, Base64-encoded (or uploads it first and sends its documentKey). Signing is performed server-side with the company's registered KGD certificate, so the ERP does not handle certificates. The call returns at once with a trackingId and status PENDING; Docnova then signs the document, uploads it to KGD and records the result. Read the result with Section 8 (Document Status) — see "Results by document type" there.

A trackingId reaches KGD at most once: if the queue delivers the same message again, the document is not uploaded a second time. To send again, make a new request.

Endpoint Information​

PropertyValue
URL/invoice/send-document-async
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationJWT Token (R-Auth header) or API Key

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/send-document-async' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {{jwt_token}}' \
--data-raw '{
"apiKey": "{{user_api_key}}",
"base64Document": "{{base64_encoded_xml}}",
"businessType": "B2B",
"compId": "{{company_uuid}}",
"invoiceType": "KZ_ESF_V2"
}'

SNT (waybill):

curl --location 'https://api-stage.docnova.ai/invoice/send-document-async' \
--header 'Content-Type: application/json' \
--header 'R-Auth: {{jwt_token}}' \
--data-raw '{
"compId": "{{company_uuid}}",
"waybillType": "KZ_SNT",
"base64Document": "{{base64_encoded_snt_xml}}"
}'

AVR (act of completed works):

curl --location 'https://api-stage.docnova.ai/invoice/send-document-async' \
--header 'Content-Type: application/json' \
--header 'R-Auth: {{jwt_token}}' \
--data-raw '{
"compId": "{{company_uuid}}",
"waybillType": "KZ_AWP",
"base64Document": "{{base64_encoded_awp_v1_xml}}",
"senderSignerName": "Генеральный директор"
}'

Virtual warehouse U-Form:

curl --location 'https://api-stage.docnova.ai/invoice/send-document-async' \
--header 'Content-Type: application/json' \
--header 'R-Auth: {{jwt_token}}' \
--data-raw '{
"compId": "{{company_uuid}}",
"warehouseDocumentType": "MOVEMENT",
"base64Document": "{{base64_encoded_uform_xml}}"
}'

Request Parameters​

FieldTypeRequiredDescription
compIdString (UUID)Conditional*Company unique identifier. Required if apiKey is not provided.
apiKeyStringConditional*API key. Required if compId is not provided.
base64DocumentStringConditional**The KGD XML document (ESF, SNT, AVR or U-Form), UTF-8, Base64-encoded. A PDF is refused: only the XML can be signed and filed with KGD.
documentKeyStringConditional**The key returned by Section 6 (Presigned Upload) after the XML was uploaded there. The same key cannot be submitted again within 10 minutes (HTTP 429).
invoiceTypeEnumConditional***KZ_ESF_V2 for an ESF invoice.
waybillTypeEnumConditional***KZ_SNT for an SNT, KZ_AWP for an AVR.
warehouseDocumentTypeEnumConditional***The virtual warehouse U-Form type (see the table below).
senderSignerNameStringAVR onlyThe position of the person who signs the AVR on the sender side (e.g. Генеральный директор). Required when waybillType is KZ_AWP; ignored otherwise.
businessTypeEnumNoBusiness model type (B2B, B2C, B2G).

Note:

  • (*) At least one of compId or apiKey must be provided.
  • (**) One of base64Document or documentKey must be provided.
  • (***) Exactly one of invoiceType, waybillType or warehouseDocumentType must be provided. A request that declares two of them is refused with HTTP 400.
  • One SNT, one AVR or one U-Form per request.
  • An AVR goes through the same checks, duplicate-number check, credit, signing and KGD upload as POST /api/sap/awp/create (AVR section); its XML rules are described there.

businessType Values​

ValueDescription
B2BBusiness to Business
B2CBusiness to Consumer
B2GBusiness to Government

invoiceType Values (Relevant to Kazakhstan)​

ValueGroupDescription
KZ_ESF_V2KazakhstanKazakhstan ESF v2 — the only value a Kazakhstan company should send.

Shared enum: invoiceType also accepts every other country's format codes (XRechnung, ZUGFeRD, Factur-X, KSeF, etc.) since this endpoint is shared across the whole platform — they are not applicable to a Kazakhstan company and are omitted here.

waybillType Values (Relevant to Kazakhstan)​

ValueDescription
KZ_SNTSNT (сопроводительная накладная на товары) — one SNT XML per request. Signed with the company's newest KGD certificate.
KZ_AWPAVR (акт выполненных работ), AwpV1 XML. senderSignerName is required.

warehouseDocumentType Values​

ValueDescription
BALANCEOpening balance U-Form
MANUFACTUREManufacture U-Form
MOVEMENTMovement U-Form
WRITE_OFFWrite-off U-Form
BALANCE_CORRECTIONBalance correction U-Form
DETAILINGDetailing U-Form

Responses​

200 - Successful Response​

{
"trackingId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "PENDING",
"message": "Document queued for processing"
}

Response Fields​

FieldTypeDescription
trackingIdUUIDUnique process tracking identifier. This ID can be used to query the processing status.
statusEnumCurrent status of the process.
messageStringDescriptive message about the status.

status Values​

ValueDescription
PENDINGProcess queued, not yet started
PROCESSINGProcess in progress
COMPLETEDProcess completed successfully
FAILEDProcess failed
SENDING_FAILEDSending failed
PERMANENT_FAILEDPermanent failure, will not be retried

400 - Bad Request​

{
"trackingId": null,
"status": "FAILED",
"message": "Either invoiceType or waybillType must be provided"
}

An AVR (waybillType = KZ_AWP) without senderSignerName is refused before anything is queued; no tracking record is created:

{
"errorType": "MISSING_SENDER_SIGNER_NAME",
"errorMessage": "senderSignerName (position of the signer) is required"
}

401 - Unauthorized​

{
"timestamp": "2026-01-29T10:30:00.000Z",
"status": 401,
"error": "Unauthorized",
"message": "Invalid or expired token"
}

500 - Internal Server Error​

{
"trackingId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "FAILED",
"message": "An unexpected error occurred"
}

5. Send Document Async (JSON) POST​

Purpose of Use: The POST /invoice/send-document-async-json endpoint accepts invoice data as a structured JSON object (ublDto) instead of a pre-built XML file — this is the platform's shared cross-country JSON invoice model. For Kazakhstan, the platform converts that JSON into ESF V2 XML — applying the KZ invoice type code and KZ-specific extensions — and submits it through the same KazakhstanInvoiceService used by every other creation channel.

Endpoint Information​

PropertyValue
URL/invoice/send-document-async-json
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/send-document-async-json' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"ublDto": {
"companyId": "79499e36-6d45-4c7d-bc52-...",
"invoiceType": "KZ_ESF_V2"
},
"apiKey": null,
"receiverEmails": ["buyer@example.kz"],
"senderEmail": null,
"mailTemplateId": null,
"businessType": "B2B",
"validationVersion": null,
"method": null
}'

Request Parameters​

FieldTypeRequiredDescription
ublDtoObjectYesThe invoice payload as a structured JSON object. companyId inside it is required unless apiKey is supplied at the top level.
apiKeyStringNo*Resolves the company when ublDto.companyId is omitted. One of the two is required.
receiverEmailsArray<String>NoRecipient email addresses for the generated invoice notification.
senderEmailStringNoOverrides the sender address used on the notification email.
mailTemplateIdStringNoCustom email template identifier.
businessTypeString (Enum)NoB2B, B2C, or B2G. Declared out-of-band; not carried by the XML element set.
validationVersionStringNoNot used for Kazakhstan; relevant to France only.
methodString (Enum)NoSend-channel selection for Peppol/XRechnung/ZUGFeRD countries (via peppol, via email). Not applicable to Kazakhstan ESF delivery.

Responses​

200 - Document Accepted for Processing​

{
"trackingId": "dd240417-5896-4577-ae51-...",
"status": "PENDING",
"message": null
}
FieldTypeDescription
trackingIdUUIDPoll with Section 8 (Document Status) or Section 9 (Get Invoice/Document Status) to follow progress.
statusString (Enum)Initial queue status — see the DocumentProcessStatus table in Section 8.
messageString | nullPopulated only if the request is rejected synchronously.

400 - Bad Request​

Returned when neither apiKey nor ublDto.companyId is present, or when the JSON payload fails KZ ESF validation (e.g. missing mandatory invoice type code).

403 - Forbidden​

Returned when the authenticated user does not belong to the resolved company.

6. Presigned Upload for ESF XML POST​

Purpose of Use: The POST /invoice/presign-upload endpoint returns a short-lived, company-scoped presigned S3 URL so an ERP can upload a large ESF V2 XML document directly to storage, bypassing the request body size limits of send-document-async. The returned key is then passed back as documentKey on send-document-async.

Kazakhstan-specific behavior: ZUGFeRD-family countries receive two upload slots (PDF + XML), because their flow merges a visual PDF with structured XML. Kazakhstan ESF has no PDF half — the ESF submission is the XML — so dataType: "KZ_ESF_V2" returns exactly one slot, for the XML, and places it directly under the document prefix rather than the pre-process prefix used by the merge flow.

Endpoint Information​

PropertyValue
URL/invoice/presign-upload
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)
Rate Limit2 requests / company, refilling 1 every minute

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/presign-upload' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"dataType": "KZ_ESF_V2",
"compId": "79499e36-6d45-4c7d-bc52-...",
"apiKey": null
}'

Request Parameters​

FieldTypeRequiredDescription
dataTypeString (Enum)YesMust be KZ_ESF_V2 for Kazakhstan. Other accepted values (ZUGFERD, Factur-X variants) return two slots instead of one.
compIdString (UUID)No*Company to scope the upload to. One of compId / apiKey is required.
apiKeyStringNo*Resolves the company when compId is omitted.

Responses​

200 - Presigned URL Generated​

{
"uploads": [
{
"fileType": "XML",
"key": "tmp/document/79499e36-6d45-4c7d-bc52-.../a1b2c3d4.xml",
"uploadUrl": "https://<bucket>.s3.amazonaws.com/tmp/document/...?X-Amz-Signature=..."
}
]
}
FieldTypeDescription
uploadsArray<Object>One slot for KZ, two for ZUGFeRD-family types.
uploads[].fileTypeString (Enum)XML for Kazakhstan.
uploads[].keyStringThe S3 object key. Pass this value as documentKey on send-document-async once the upload completes.
uploads[].uploadUrlStringPresigned PUT URL, valid for 15 minutes. Upload the raw XML bytes directly to this URL.

400 - Bad Request​

Returned when dataType is not one of KZ_ESF_V2, ZUGFERD, or a Factur-X type.

429 - Too Many Requests​

Returned when a company has already made 2 presign requests within the current refill window (1 token refilled per minute).

7. Generate PDF POST​

Purpose of Use: This API endpoint generates a human-readable PDF from Kazakhstan ESF (ЭСФ) invoice XML (type: KZ_ESF_V2). The Base64-encoded ESF XML is transformed into HTML by the dedicated Kazakhstan ESF XSLT template, which renders the ESF document itself rather than a UBL conversion. The HTML is then converted into a PDF with iText 7. Bundled Unicode fonts make Cyrillic and Kazakh characters render correctly. The XML is not embedded in the PDF. The PDF is a visual copy only; the legally binding document is the ESF filed with the KGD through IS ESF. Supplying country (KZ) with vatNumber (BIN/IIN), or companyId, matches the company and renders the labels in its language setting (Kazakh, Russian or English). Without a match, the labels default to English. Designed for visualizing, printing and archiving ESF invoices in ERP integrations.

Endpoint Information​

PropertyValue
URL/invoice/generate/pdf
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthenticationR-Auth header (JWT Bearer Token)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/generate/pdf' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJNTU0iLCJzdWIiOiJwNjR9.IpGPX...' \
--data '{
"base64XML": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KC...",
"country": "KZ",
"type": "KZ_ESF_V2",
"vatNumber": "123456789012"
}'

Request Parameters​

Field NameTypeRequiredDescription
base64XMLStringYesBase64-encoded ESF V2 XML.
typeEnum (DataType)YesInvoice format type — KZ_ESF_V2 for Kazakhstan.
countryEnum (Country)NoKZ for Kazakhstan. When used together with vatNumber, company matching is performed to add logo and language settings to the PDF.
vatNumberStringNoBIN/IIN of the invoicing company. When used together with country, it matches against the company record in the system.

Valid Values for type Parameter​

ValueDescriptionXSLT Group
KZ_ESF_V2Kazakhstan ESF v2 format — the only value a Kazakhstan company should send.KZ_ESF_V2

Shared enum: type also accepts every other country's format codes (XRechnung, ZUGFeRD, Factur-X, KSeF, etc.), each rendered by its own XSLT group — they are not applicable to a Kazakhstan company and are omitted here.

country Parameter​

Country CodeCountryPDF Language
KZKazakhstanKazakh (KK)
Any other value, or omitted—English (EN)

Note: The PDF stylesheet for KZ_ESF_V2 renders in Kazakh, Russian or English depending on the matched company's mailLanguage (Section 2) — passing country: "KZ" only decides whether company matching (logo, language) is attempted at all.

Responses​

200 - Successful Response​

PropertyValue
HTTP Status200
Content-Typeapplication/octet-stream
BodyBinary PDF data (byte array)
%PDF-1.7
%����
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
/Names 21 0 R
/Metadata 27 0 R
>>
endobj
5 0 obj
<<

400 - Bad Request​

Trigger Condition: When the XML data is invalid, Base64 cannot be decoded, XSLT transformation fails, or any error occurs during iText PDF generation.

{
"errorMessage": "PDF convert error: [detail message]",
"errorType": "PDF_CONVERT_ERROR",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}

Possible Detail Messages:

  • PDF convert error: PDF conversion failed due to an unexpected error — XSLT template not found or unexpected error during HTML-to-PDF conversion
  • PDF convert error: Illegal base64 character — The base64XML field is not in valid Base64 format
  • PDF convert error: [XSLT transformation error]` — XML structure does not match the expected format

400 - Bad Request — Invalid Parameter​

Trigger Condition: When an invalid enum value is sent for the type field or required fields are missing.

{
"errorMessage": "Invalid argument! Argument: type",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}

400 - Bad Request — Invalid PDF Type​

Trigger Condition: When the submitted type value is an unsupported format for PDF conversion.

{
"errorMessage": "Invalid PDF type",
"errorType": "INVALID_PDF_TYPE",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}

400 - Bad Request — Empty XML Data​

Trigger Condition: When the base64XML field is sent as null or empty.

{
"errorMessage": "Data XML cannot be NULL!",
"errorType": "NULL_DATA_XML",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}

401 - Unauthorized​

Trigger Condition: When the R-Auth header is missing, the JWT token has expired, or an invalid token is provided.

{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 401,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}

500 - Internal Server Error​

Trigger Condition: When an unexpected server error occurs (XSLT file cannot be loaded, insufficient memory, etc.).

{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 500,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}

Error Codes and Response Details​

The following errors are specific to this endpoint. All error responses follow the ExceptionResponse format:

Error Response Structure​

Field NameTypeDescription
errorMessageStringDetailed description of the error
errorTypeStringError type identifier
errorTitleStringHTTP status name (BAD_REQUEST, INTERNAL_SERVER_ERROR, etc.)
errorIdStringCorrelation ID (for log tracing)
statusIntegerHTTP status code (400, 500, etc.)
timestampString (ISO 8601)Time when the error occurred
pathStringRequested URL path

8. Document Status GET​

Purpose of Use: The GET /invoice/document-status/{trackingId} endpoint is used to query the processing status of documents (invoices, waybills, etc.) that were submitted asynchronously.

When a document is submitted through any of the send-document-async, send-document-async-json, send-by-file-async, or send-portal-new-async endpoints, the system immediately returns a trackingId and begins processing the document in the background.

Polling stops when the status becomes COMPLETED or FAILED.

Endpoint Information​

PropertyValue
URL/invoice/document-status/{trackingId}
MethodGET
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/document-status/{trackingId}' \ 

--header 'Accept: */*' \

--header 'R-Auth: {JWT_TOKEN}'
}'

Request Parameters​

Path Parameters​

FieldTypeRequiredDescription
trackingIdUUIDYesThe tracking identifier returned from an asynchronous document submission. This is the trackingId value included in the response of send-document-async, send-document-async-json, send-by-file-async, or send-portal-new-async endpoints.

Header Parameters​

FieldTypeRequiredDescription
R-AuthString (JWT)YesUser authentication token. A JWT signed with the HS512 algorithm. The payload carries userId, companyId, authorities, and userType information.
AcceptStringNoResponse media type. Default: /

Responses​

200 - Successful Response​

{
"trackingId": "dd240417-5896-4577-ae51-...",
"companyId": "79499e36-6d45-4c7d-bc52-...",
"direction": "OUTGOING",
"documentType": "KZ_ESF_V2",
"waybillType": null,
"source": "ERP",
"target": null,
"status": "COMPLETED",
"filename": null,
"invoiceNumber": "00900023888",
"documentId": "b34afc0b-4f5d-4670-910c-...",
"sendingResult": null,
"errorType": null,
"createdAt": "2026-09-16T07:25:50",
"statusUpdatedAt": "2026-09-16T07:26:00",
"completedAt": "2026-09-16T07:26:05",
"errors": null,
"additionalData": {
"kgdInvoiceId": 22116203282...,
"esfStatus": "KZ_CREATED"
}
}

Success Response Field Descriptions​

FieldTypeDescription
trackingIdUUIDUnique tracking identifier for the document processing
companyIdUUIDUnique identifier of the company the document belongs to
directionString (Enum)Document direction: INCOMING or OUTGOING
documentTypeString (Enum)Document format — KZ_ESF_V2 for Kazakhstan
waybillTypeString (Enum)Waybill type. Only populated for waybill operations
sourceString (Enum)Source platform the document was submitted from (e.g., ERP, PORTAL)
targetString (Enum) | nullTarget platform for the document
statusString (Enum)Current processing status: PENDING, PROCESSING, COMPLETED, FAILED, SENDING_FAILED, PERMANENT_FAILED
filenameStringName of the processed file
invoiceNumberString | nullInvoice number assigned to the document. Populated when processing completes
documentIdUUID | nullUnique system identifier of the created document. Populated when processing completes
sendingResultString | nullSending result (e.g., SUCCESS). Populated when processing completes
errorTypeString (Enum) | nullError category when an error occurs. Null for successful operations
errorsObject | nullError details. Variable type: can be List<ValidationError>, List<String>, or String
additionalDataObjectKZ-specific additional metadata. For an ESF: kgdInvoiceId (the provider's numeric invoice id) and esfStatus (the raw ESF status, see Section 10). For SNT, AVR and U-Form keys see "Results by document type" below. Carries statusSyncPaused / statusSyncPausedReason while status updates are paused (see Status credit in the Introduction).
createdAtDateTimeTimestamp when the processing record was created (ISO 8601)
statusUpdatedAtDateTimeTimestamp when the status was last updated (ISO 8601)
completedAtDateTime | nullTimestamp when processing completed. Null while processing is ongoing

Parameter Value Reference​

DocumentProcessStatus — Possible Status Values​

ValueDescription
PENDINGDocument is queued, processing has not started yet
PROCESSINGDocument is actively being processed (conversion, validation, sending, etc.)
COMPLETEDDocument processing completed successfully
FAILEDAn error occurred during document processing (may be retried)
SENDING_FAILEDDocument was created but failed during the sending phase
PERMANENT_FAILEDDocument processing permanently failed (will not be retried)

DocumentType — Document Direction​

ValueDescription
INCOMINGIncoming document
OUTGOINGOutgoing document

DataType — Document Format (Relevant to Kazakhstan)​

ValueDescription
KZ_ESF_V2Kazakhstan ESF v2 format — the only value a Kazakhstan company will see here.

Shared enum: documentType also carries every other country's format codes (XRechnung, ZUGFeRD, Peppol BIS, KSeF, etc.) since this field is shared across the whole platform — not applicable to Kazakhstan.

WaybillDataType — Waybill Type (Relevant to Kazakhstan)​

ValueDescription
KZ_SNTSNT sent with waybillType = KZ_SNT
KZ_AWPAVR sent with waybillType = KZ_AWP

A U-Form sent with warehouseDocumentType has neither documentType nor waybillType set.

Results by document type​

DocumentdocumentIdinvoiceNumberadditionalData
ESF (KZ_ESF_V2)Docnova invoice idESF numberkgdInvoiceId, esfStatus
SNT (KZ_SNT)null — no Docnova SNT record is keptSNT numberkgdSntId (KGD's SNT id; use it on the /snt/* endpoints)
AVR (KZ_AWP)Docnova AVR record id (the id of GET /api/awp/{id})AVR numberkgdAwpId, awpStatus, and kgdRegistrationNumber once KGD has given one
U-Form (warehouseDocumentType)Docnova U-Form id (the id of /kz/vwh/internal/uform/{id})U-Form numberkgdRegistrationNumber once KGD has given one

On FAILED, errors carries KGD's or Docnova's message (for an AVR the same text the AVR section lists as errorMessage; the errorType code is not returned separately here).

⚠️ KGD_OUTCOME_UNKNOWN: When an SNT or AVR ends FAILED and the first entry of errors is KGD_OUTCOME_UNKNOWN, Docnova could not learn KGD's answer and the document may already be registered at KGD. Do not resend it (an AVR must not be resent under a new number); contact Docnova. A resend of the same AVR number is refused with DUPLICATE_AWP.

Sections 9 and 10 read the Docnova invoice record, so they apply to ESF invoices only. Follow SNT, AVR and U-Form submissions with this endpoint; after completion, follow an AVR with GET /api/awp/{id} and a U-Form with the VWH UForm endpoints.

ErrorType — Error Types Specific to This Endpoint​

ValueMessage
INVOICE_PROCESS_NOT_FOUNDTracking ID not found
VALIDATION_FAILEDValidation failed!
INVOICE_NULL_COULD_NOT_SAVEInvoice is NULL and/or could not be saved!
INVOICE_CREATION_FAILEDInvoice creation failed!
INVOICE_SENDING_FAILEDInvoice sending failed: {details}

404 - Not Found​

Returned when the provided trackingId does not exist in the database.
Response Body: null (body is empty)

DetailDescription
HTTP Status404 Not Found
Response Bodynull (body is empty)
TriggerNo DocumentProcessEntity record matches the given trackingId in the database
Internal Error TypeINVOICE_PROCESS_NOT_FOUND — "Tracking ID not found"
ResolutionVerify the trackingId value is correct. Use the value returned in the response of the async submission endpoint

401 - Unauthorized ​

Returned when the R-Auth header is missing, contains an invalid JWT token, or the token has expired.

{
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource"
}
DetailDescription
HTTP Status401 Unauthorized
TriggerJWT token is missing, malformed, expired, or signature verification failed
ResolutionSend a valid, non-expired JWT token in the R-Auth header

500 - Internal Server Error​

Returned when an unexpected server error occurs during the status query.
Response Body: null (body is empty)

DetailDescription
HTTP Status500 Internal Server Error
Response Bodynull (body is empty)
TriggerDatabase connection failure, entity conversion error, or other unexpected runtime exceptions
ResolutionCheck server logs. Contact the support team if the issue persists

Status-Based Response Examples​

PENDING — Queued for Processing​


{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": null,
"documentType": "KZ_ESF_V2",
"status": "PENDING",
"documentId": null,
"invoiceNumber": null,
"sendingResult": null,
"errorType": null,
"errors": null,
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:00",
"completedAt": null
}

PROCESSING — Currently Processing​

{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "KZ_ESF_V2",
"status": "PROCESSING",
"documentId": "f47ac10b-58cc-4372-a567-...",
"invoiceNumber": "00900023888",
"sendingResult": null,
"errorType": null,
"errors": null,
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:20",
"completedAt": null
}

FAILED — Processing Failed (Validation Error)​


{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": null,
"documentType": "KZ_ESF_V2",
"status": "FAILED",
"documentId": null,
"invoiceNumber": null,
"sendingResult": null,
"errorType": "VALIDATION_FAILED",
"errors": [
{
"field": "invoiceNumber",
"message": "Invoice number is required"
},
{
"field": "issueDate",
"message": "Issue date format is invalid"
}
],
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:15",
"completedAt": "2025-06-15T10:30:15"

}

FAILED — Processing Failed (General Error)​

{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "KZ_ESF_V2",
"status": "FAILED",
"documentId": null,
"invoiceNumber": null,
"sendingResult": null,
"errorType": "INVOICE_NULL_COULD_NOT_SAVE",
"errors": [
"Invoice is NULL and/or could not be saved! XML parsing error at line 42"
],
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:12",
"completedAt": "2025-06-15T10:30:12"
}

SENDING_FAILED — Sending Failed​

{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "KZ_ESF_V2",
"status": "SENDING_FAILED",
"documentId": "f47ac10b-58cc-4372-a567-...",
"invoiceNumber": "00900023888",
"sendingResult": null,
"errorType": "INVOICE_SENDING_FAILED",
"errors": [
"Invoice sending failed: ESF (IS ESF) service unreachable"
],
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:31:00",
"completedAt": "2025-06-15T10:31:00"
}

COMPLETED — With KZ-Specific Metadata​

{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "KZ_ESF_V2",
"status": "COMPLETED",
"documentId": "f47ac10b-58cc-4372-a567-...",
"invoiceNumber": "00900023888",
"sendingResult": "SUCCESS",
"errorType": null,
"errors": null,
"additionalData": {
"kgdInvoiceId": 22116203282,
"esfStatus": "KZ_CREATED"
},
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:31:30",
"completedAt": "2025-06-15T10:31:30"

}

9. Get Invoice/Document Status GET​

Purpose of Use: This endpoint is used to query the real-time processing status of an invoice/document by using the trackingId returned from an asynchronous document submission request.

After an invoice or document is submitted through an async flow, the first response may only contain a trackingId. This endpoint allows the client to follow the internal processing lifecycle of that document, including whether it is queued, processing, failed, or completed.

Once a documentId has been assigned to the document, this endpoint also returns invoice-level status information such as invoiceStatus and invoiceStatusDate. If the document has not yet been assigned a final documentId, those fields may be null, and only the process-level status fields should be used.

The request requires that the authenticated user in the R-Auth JWT has authority over the queried companyId.


Endpoint Information​

PropertyValue
URL/invoice/get-document-status-by-tracking
MethodGET
Content-TypeNone — query parameters only, no request body
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth: {{jwt_token}}

Example Request​

curl -X GET 'https://api-stage.docnova.ai/invoice/get-document-status-by-tracking?companyId={{company_uuid}}&trackingId={{tracking_uuid}}' \
-H 'accept: */*' \
-H 'R-Auth: {{jwt_token}}'

Request Parameters​

FieldTypeRequiredDescription
companyIdString (UUID)YesUnique identifier of the company that the queried tracking record belongs to. The requesting user must hold a role in this company.
trackingIdString (UUID)YesThe tracking identifier returned in the response of the document's asynchronous submission request. The document status is looked up via this identifier.

Notes

  • The R-Auth header is mandatory.
  • The user in the JWT must have a role in the company matching companyId.
  • If trackingId is not associated with companyId, for example when trying to access a record belonging to another company, a 401 Unauthorized response is returned.
  • If the tracking process is found but no documentId has been assigned yet, only the process-level status fields are returned.

Responses​


200 - Successful Response​

{
"trackingId": "{{tracking_uuid}}",
"documentId": "{{document_uuid}}",
"invoiceStatus": "KZ_DELIVERED",
"invoiceStatusDate": "2026-01-15T12:00:00",
"processStatus": "COMPLETED",
"processStatusUpdatedAt": "2026-01-15T12:00:00"
}

Description: Request succeeded. If the document has not yet been assigned a documentId, the documentId, invoiceStatus, and invoiceStatusDate fields are null, and only processStatus / processStatusUpdatedAt are meaningful.

Response Fields​

FieldTypeDescription
trackingIdString (UUID)Echoes the trackingId sent in the request. Always populated.
documentIdString (UUID)Populated once the document is assigned a final ID. null if the document has not yet been assigned.
invoiceStatusString (Enum)Populated once documentId is assigned. Contains the invoice's country/channel-specific final status. null if documentId is not yet assigned.
invoiceStatusDateString (ISO 8601)Timestamp of the last update to invoiceStatus. null if documentId is not yet assigned.
processStatusString (Enum)Status of the document's own processing pipeline. Always populated, even before documentId is assigned.
processStatusUpdatedAtString (ISO 8601)Timestamp of the last update to processStatus. Always populated.
statusSyncPausedBooleantrue while KGD status updates for the document are paused because the company has no credit left (see Status credit in the Introduction). Omitted otherwise.
statusSyncPausedReasonStringWhy updates are paused. Omitted together with statusSyncPaused.

Parameter Values Reference Table​

processStatus Values​
ValueDescription
PENDINGProcess has not started yet; queued.
PROCESSINGDocument is currently being processed.
FAILEDProcessing failed; may be retried.
SENDING_FAILEDAn error occurred during the sending stage.
PERMANENT_FAILEDPermanent failure; will not be retried.
COMPLETEDProcess completed successfully.
invoiceStatus Values (Relevant to Kazakhstan)​

For a Kazakhstan ESF invoice, invoiceStatus is always one of the KZ_* values listed in Section 10's status table — the same shared InvoiceStatus enum, scoped to Kazakhstan.

ValueDescription
CREATEDGeneric: invoice/document has been created (used before a country-specific status is assigned).
CANCELEDGeneric: canceled.
DELETEDGeneric: deleted.
CREDIT_BLOCKEDGeneric: payment blocked due to credit limit.

Shared enum: invoiceStatus also carries statuses specific to other countries' formats and channels (ZUGFeRD, KSeF, Peppol AS4, OCR pipeline, etc.) — not applicable to Kazakhstan.

All error responses share the following structure:

{
"errorMessage": "<human-readable message>",
"errorType": "<error type key>",
"errorTitle": "<HTTP status name>",
"status": 400,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/get-document-status-by-tracking"
}

400 - Bad Request​

Tracking ID Not Found

{
"errorMessage": "Tracking ID not found",
"errorType": "INVOICE_PROCESS_NOT_FOUND",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/get-document-status-by-tracking"
}

Description: An ApiError(INVOICE_PROCESS_NOT_FOUND) is thrown when the trackingId is not found in the database.

Note: Although Swagger annotation documents this case as 404, the code currently calls withStatus() on this exception, so RestExceptionHandler returns the default 400 Bad Request.

401 - Unauthorized​

{
"errorMessage": "User is not authorized for this operation",
"errorType": "AUTHORIZATION_FAILED",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/get-document-status-by-tracking"
}

Trigger: The user in the R-Auth JWT has no role or authority in the given companyId, or the trackingId belongs to a different company than the given companyId.

500 - Internal Server Error​

{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"status": 500,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/get-document-status-by-tracking"
}

Trigger: An unexpected server-side error occurs.

This may happen because of a database connectivity issue, an unhandled exception, or another server-side runtime error.

10. Get Document Status GET​

Purpose of Use: The GET /invoice/get-document-status/{documentId} endpoint returns the current shared InvoiceStatus of a document that already has a document ID (i.e. processing has completed and an invoice record exists). For Kazakhstan, the returned status is one of the KZ_* values mapped from the ESF status (see table below).

Endpoint Information​

PropertyValue
URL/invoice/get-document-status/{documentId}
MethodGET
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/get-document-status/b34afc0b-4f5d-4670-910c-...' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

Path Parameters​

FieldTypeRequiredDescription
documentIdUUIDYesThe shared invoice identifier (the uuid/documentId returned by a creation or status endpoint).

Responses​

200 - Successful Response​

{
"status": "KZ_DELIVERED",
"statusDate": "2026-09-16T07:26:05"
}
FieldTypeDescription
statusString (Enum)Shared InvoiceStatus. For Kazakhstan, one of the KZ_* values below.
statusDateDateTimeTimestamp of the last confirmed status change (ISO 8601).
statusSyncPausedBooleantrue while KGD status updates for the document are paused because the company has no credit left (see Status credit in the Introduction). Omitted otherwise.
statusSyncPausedReasonStringWhy updates are paused. Omitted together with statusSyncPaused.

InvoiceStatus — Kazakhstan ESF Values​

ESF StatusShared InvoiceStatus
IN_QUEUEKZ_IN_QUEUE
IN_PROCESSINGKZ_IN_PROCESSING
CREATEDKZ_CREATED
DELIVEREDKZ_DELIVERED
CANCELEDKZ_CANCELED
CANCELED_BY_OGDKZ_CANCELED_BY_OGD
CANCELED_BY_SNT_DECLINEKZ_CANCELED_BY_SNT_DECLINE
CANCELED_BY_SNT_REVOKEKZ_CANCELED_BY_SNT_REVOKE
REVOKEDKZ_REVOKED
IMPORTEDKZ_IMPORTED
DRAFTKZ_DRAFT
FAILEDKZ_FAILED
DELETEDKZ_DELETED
DECLINEDKZ_DECLINED
SEND_TO_ISGOKZ_SENT_TO_ISGO
WAIT_BIOMETRICS_VERIFICATIONKZ_WAIT_BIOMETRICS_VERIFICATION
FAILED_BIOMETRICS_VERIFICATIONKZ_FAILED_BIOMETRICS_VERIFICATION
DELETED_BIOMETRICS_VERIFICATIONKZ_DELETED_BIOMETRICS_VERIFICATION
WAITING_CUSTOMER_CONFIRMATIONKZ_WAITING_CUSTOMER_CONFIRMATION
WAITING_CUSTOMER_REVOKE_CONFIRMATIONKZ_WAITING_CUSTOMER_REVOKE_CONFIRMATION

Local-only states: Three additional values are not official ESF statuses — they describe the local submission's own lifecycle: KZ_SUBMISSION_PENDING (reserved, not yet sent), KZ_SUBMISSION_FAILED (failed before reaching ESF), and KZ_RECONCILIATION_REQUIRED (the provider's answer is unknown and is being reconciled). A document in KZ_DELIVERED is not necessarily in its final state — it can still move to a CANCELED/REVOKED family status later; poll Section 9 (Get Invoice/Document Status) for the fully reconciled view when in doubt.

11. Search Document with Filter POST​

Purpose of Use: The POST /invoice/search-documents endpoint is used to search for invoices and documents belonging to a specific company using various filtering criteria.

This API enables users to list documents associated with their company by applying filters such as date range, document direction (incoming or outgoing), invoice status, and document format (KZ_ESF_V2 for Kazakhstan). Results are returned with pagination support, and each page includes the total document count, tax exclusive total amount, and tax inclusive total amount.

Endpoint Information​

PropertyValue
URL/invoice/search-documents
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

{ 
curl --location 'https://<BASE_URL>/invoice/search-documents' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: <JWT_TOKEN>' \
--data '{
"companyId": "<COMPANY_UUID>",
"documentType": "OUTGOING",
"endDate": "2026-01-31",
"page": 0,
"size": 10,
"startDate": "2026-01-01",
"status": "KZ_DELIVERED",
"type": "KZ_ESF_V2"
}'
}

Request Parameters​

FieldTypeRequiredDescription
companyIdUUIDYesUnique identifier of the company to search documents for
documentTypeString (Enum)NoDocument direction filter. Used to filter incoming or outgoing documents
statusString (Enum)NoInvoice status filter. Returns invoices in a specific status
typeString (Enum)NoDocument format type filter. Filters by invoice format
startDateString (ISO Date)NoSearch start date. Format: YYYY-MM-DD
endDateString (ISO Date)NoSearch end date. Format: YYYY-MM-DD
tinStringNoTax Identification Number filter
uitStringNoUIT identifier filter
referenceDocumentStringNoSearch by reference document number
pageIntegerNoPage number (0-based). Default: 0
sizeIntegerNoNumber of records per page. Default: 50

Parameter Values​

documentType Values​

ValueDescription
INCOMINGIncoming documents (invoices sent by suppliers)
OUTGOINGOutgoing documents (invoices sent to customers)

type Values (Relevant to Kazakhstan)​

ValueGroupDescription
KZ_ESF_V2KZ_ESF_V2Kazakhstan ESF v2 format — the only value a Kazakhstan company should send.

⚠️ Note: On this endpoint, the type filter only actively filters for the ZUGFeRD-family values (XRechnung, ZUGFeRD, Factur-X) — passing type: "KZ_ESF_V2" here does not filter results. To restrict a search to ESF invoices, rely on companyId (a Kazakhstan company only has KZ_ESF_V2 invoices) or filter client-side on the returned type field.

status Values (Relevant to Kazakhstan)​

CategoryValueDescription
GeneralCREATEDInvoice created
PENDINGAwaiting processing
CANCELEDCancelled
DELETEDDeleted
SENT_VIA_EMAILSent via email
CREDIT_BLOCKEDPayment blocked due to credit limit (returns masked data)
Kazakhstan ESFKZ_CREATED, KZ_DELIVERED, KZ_CANCELED, …Any of the KZ_* values in Section 10's status table

Shared enum: status also carries statuses specific to other countries' formats and channels (ZUGFeRD, Peppol AS4, OCR pipeline, Romania ANAF, Poland KSeF, Malaysia LHDNM, Egypt ETA, Croatia eRacun, Denmark Nemhandel) — not applicable to Kazakhstan.

Responses​

200 - Successful Response​

{ 
"totalCount": 2,
"netTotal": 15000.00,
"total": 16800.00,
"invoiceList": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-...",
"companyId": "60ccd1a7-5348-47b2-9ef6-...",
"userId": "user-uuid",
"customerName": "Buyer LLP",
"supplierName": "Example Company LLP",
"supplierId": "supplier-uuid",
"supplierVat": "123456789012",
"status": "KZ_DELIVERED",
"invoiceNumber": "00900023888",
"taxExclusiveAmount": 15000.00,
"taxInclusiveAmount": 16800.00,
"lineExtensionAmount": 15000.00,
"payableAmount": 16800.00,
"allowanceTotalAmount": 0.00,
"currency": "KZT",
"createdTime": "2026-01-15T10:30:00",
"localCreatedTime": "2026-01-15T16:30:00",
"issueDate": "2026-01-15",
"deliveryDate": "2026-01-20",
"dueDate": "2026-02-15",
"supplierCountryCode": "KZ",
"supplierEndpoint": null,
"customerId": "customer-uuid",
"customerVat": "987654321098",
"customerEndpoint": null,
"customerCountryCode": "KZ",
"typeCode": "380",
"documentType": "OUTGOING",
"errorMessage": null,
"lastUpdatedTime": "2026-01-15T10:30:00",
"localLastUpdatedTime": "2026-01-15T16:30:00",
"type": "KZ_ESF_V2",
"source": "PORTAL",
"sendViaPeppol": false,
"statusTime": "2026-01-15T10:30:00",
"localStatusTime": "2026-01-15T16:30:00",
"fileName": "invoice_001.xml",
"ocrParser": null,
"paymentDetails": null,
"profileType": null,
"isActive": true,
"countrySpecificData": null
}

]
}

Successful Response Field Descriptions​

Top-Level Fields​

FieldTypeDescription
totalCountLongTotal number of documents matching the filters
netTotalDoubleTax-exclusive total amount (excludes CREDIT_BLOCKED)
totalDoubleTax-inclusive total amount (excludes CREDIT_BLOCKED)
invoiceListArray<Invoice>List of invoice objects

Invoice Object Fields​

FieldTypeDescription
idString (UUID)Unique identifier of the invoice
companyIdString (UUID)Company ID the invoice belongs to
userIdString (UUID)User ID who created the invoice
customerNameStringCustomer (buyer) name
supplierNameStringSupplier (seller) name
supplierIdStringSupplier ID
supplierVatStringSupplier VAT number
statusString (Enum)Current invoice status
invoiceNumberStringInvoice number
taxExclusiveAmountDoubleTax-exclusive amount
taxInclusiveAmountDoubleTax-inclusive amount
lineExtensionAmountDoubleLine items total amount
payableAmountDoubleAmount payable
allowanceTotalAmountDoubleTotal allowance/discount amount
currencyStringCurrency code (ISO 4217) — KZT for a Kazakhstan ESF invoice
createdTimeString (DateTime)Creation timestamp (UTC)
localCreatedTimeString (DateTime)Creation timestamp (local time)
issueDateString (Date)Invoice issue date
deliveryDateString (Date)Delivery date
dueDateString (Date)Due date
supplierCountryCodeStringSupplier country code (ISO 3166-1 alpha-2)
supplierEndpointString | nullSupplier Peppol endpoint — null for Kazakhstan (ESF does not use Peppol)
customerIdStringCustomer ID
customerVatStringCustomer VAT number (BIN/IIN for Kazakhstan)
customerEndpointString | nullCustomer Peppol endpoint — null for Kazakhstan (ESF does not use Peppol)
customerCountryCodeStringCustomer country code
typeCodeStringInvoice type code (e.g., 380=Invoice, 381=Credit Note)
documentTypeString (Enum)Document direction: INCOMING or OUTGOING
errorMessageStringError message (if any)
lastUpdatedTimeString (DateTime)Last update timestamp (UTC)
localLastUpdatedTimeString (DateTime)Last update timestamp (local time)
typeString (Enum)Document format type (DataType)
sourceString (Enum)Invoice source (PORTAL, ERP, PEPPOL, EMAIL, etc.)
sendViaPeppolBooleanWhether sent via Peppol
statusTimeString (DateTime)Status change timestamp (UTC)
localStatusTimeString (DateTime)Status change timestamp (local time)
fileNameStringFile name
ocrParserString (Enum)OCR parser type
paymentDetailsObjectPayment details (null for certain statuses)
profileTypeString (Enum) | nullZUGFeRD profile type (BASIC, EN16931, EXTENDED) — null for Kazakhstan (ESF v2 is not a ZUGFeRD profile)
isActiveBooleanWhether the invoice is active
countrySpecificDataObjectCountry-specific additional data

Note: Invoices with CREDIT_BLOCKED status are masked — only id, companyId, documentType, type,invoiceNumber ,supplierName,supplierVat , status and isActive fields are returned; all other fields are null.

400 - Bad Request​

Returned when an invalid parameter value is provided (e.g., incorrect enum value, malformed UUID format).

{
"errorMessage": "Invalid value 'INVALID_STATUS' for parameter 'status'",
"errorType": "ILLEGAL_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-abc123-def456",
"status": 400,
"timestamp": "2026-01-15T10:30:00",
"path": "/invoice/search-documents"
}

Error Response Fields​

FieldTypeDescription
errorMessageStringHuman-readable error description
errorTypeStringError type code
errorTitleStringHTTP status name
errorIdStringCorrelation ID (for log tracing)
statusIntegerHTTP status code
timestampString (DateTime)Error occurrence time
pathStringRequest path

401 - Unauthorized​

Returned when an invalid, expired, or missing JWT token is provided.

{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"errorId": "corr-abc123-def456",
"status": 401,
"timestamp": "2026-01-15T10:30:00",
"path": "/invoice/search-documents"
}

Unauthorized Error Response Fields​

FieldTypeDescription
errorMessageStringAuthorization error description
errorTypeStringFixed value: NOT_AUTHORITY
errorTitleStringHTTP status name: UNAUTHORIZED
errorIdStringCorrelation ID
statusInteger401
timestampString (DateTime)Error occurrence time
pathStringRequest path

500 - Internal Server Error​

Returned in case of database connection errors, unexpected runtime exceptions, or other server-side failures.

{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "corr-abc123-def456",
"status": 500,
"timestamp": "2026-01-15T10:30:00",
"path": "/invoice/search-documents"
}

Server Error Response Fields​

FieldTypeDescription
errorMessageStringGeneral error message
errorTypeStringRUNTIME_ERROR, IO_ERROR, or SERVER_ERROR
errorTitleStringHTTP status name: INTERNAL_SERVER_ERROR
errorIdStringCorrelation ID (for log tracing)
statusInteger500
timestampString (DateTime)Error occurrence time
pathStringRequest path

12. Search Documents v2 POST​

Purpose of Use: The POST /invoice/v2/search-documents endpoint behaves identically to Section 11 (Search Document with Filter), with the same request body and filters, but enriches each INCOMING result with additional fields intended for white-label partner integrations and reconciliation tooling.

Endpoint Information​

PropertyValue
URL/invoice/v2/search-documents
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/v2/search-documents' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"companyId": "79499e36-6d45-4c7d-bc52-...",
"documentType": "INCOMING",
"type": "KZ_ESF_V2",
"invoiceSearchType": "CREATE_DATE",
"page": 0,
"size": 50
}'

Request Parameters​

Identical to Section 11 (Search Document with Filter): companyId, tin, uit, status, documentType (INCOMING/OUTGOING), referenceDocument, startDate, endDate, page, size (max 200), type (DataType, e.g. KZ_ESF_V2), and invoiceSearchType (ISSUE_DATE / CREATE_DATE / DUE_DATE, default CREATE_DATE).

Responses​

200 - Successful Response​

Same envelope as Section 11, with each INCOMING invoice item additionally carrying:

{
"supplierPaymentAccount": {
"iban": "KZ123456789012345678",
"bic": "ABCDKZKZ",
"accountHolderName": "Supplier LLP"
},
"lineItems": [
{
"itemName": "Office supplies",
"quantity": 10,
"unitCode": "EA",
"unitPrice": 1500.00,
"netAmount": 15000.00,
"currency": "KZT",
"taxRatePercent": 12,
"taxAmount": 1800.00,
"taxCategoryCode": "S"
}
]
}
FieldTypeDescription
supplierPaymentAccountObject | nullExtracted from the invoice's payment means, when present.
supplierPaymentAccount.ibanStringSupplier IBAN.
supplierPaymentAccount.bicStringSupplier bank BIC/SWIFT code.
supplierPaymentAccount.accountHolderNameStringName on the bank account.
lineItemsArray<Object> | nullOne entry per invoice line, when the archived document could be parsed.
lineItems[].itemNameStringLine item description.
lineItems[].quantityBigDecimalBilled quantity.
lineItems[].unitCodeStringUnit of measure code.
lineItems[].unitPriceBigDecimalPrice per unit.
lineItems[].netAmountBigDecimalNet line amount.
lineItems[].currencyStringISO 4217 currency code.
lineItems[].taxRatePercentBigDecimalTax rate applied to the line.
lineItems[].taxAmountBigDecimalComputed tax amount for the line.
lineItems[].taxCategoryCodeStringTax category code.

⚠️ Note: supplierPaymentAccount and lineItems are only returned for INCOMING invoices, and only when the original archived document could be parsed; both are null otherwise.

13. Retrieve Doc by ID and Type GET​

Purpose of Use: The GET /invoice/get-document/{documentId}/{documentTypes} endpoint allows downloading a previously stored invoice or document in a specific format such as PDF, XML, or JSON.

The client provides the document UUID (documentId) and the desired output format (documentTypes). The API returns the document content as Base64 encoded data. This is mainly used in ERP integrations to programmatically fetch, view, archive, or store invoice documents.

When the requested format is pdf, the API returns the printable or viewable PDF file content as Base64 encoded data.

Endpoint Information​

PropertyValue
URL/invoice/get-document/{documentId}/{documentTypes}
MethodGET
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/get-document/{documentId}/pdf' \
--header 'Accept: */*' \
--header 'R-Auth: {auth-token}'
}'

Request Parameters​

Path Parameters​

Field NameTypeRequiredDescription
documentIdString (UUID)YesUnique identifier of the document. Must be in UUID v4 format. Example: 550e8400-e29b-41d4-a716-...
documentTypesString (Enum)YesRequested document format type. Multiple types can be separated by hyphen -. Example: PDF, XML

Header Parameters​

Field NameTypeRequiredDescription
R-AuthString (JWT)YesAuthentication token. JWT signed with HS512 algorithm.
AcceptStringNoAccepted response media type. Default: /

documentTypes Parameter Values​

ValueFormat TypeDescription
PDFFormatType.PDFReturns Base64-encoded PDF representation of the invoice
XMLFormatType.XMLReturns the Base64-encoded original ESF XML of the invoice
JSONFormatType.JSONReturns a Base64-encoded structured JSON representation of the invoice
PDF-XMLMultiple formatsMultiple formats can be requested simultaneously using hyphen separator
XML-PDF-JSONMultiple formatsAll three formats can be requested at once

Note: JSON format is only supported for invoices processed by OCR (OCR_PARSED) or completed by MelAI (COMPLETED_BY_MELAI_AI).

Responses​

200 - Successful Response​

{
"documents": [
{
"file_type": "PDF",
"data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC..."
}
]
}

Successful Response Field Descriptions​

Field NameTypeDescription
documentsList<Document>List of documents in requested formats. Contains one Document object per format.
documents[].file_typeString (Enum)Document format type. Possible values: PDF, XML, JSON
documents[].dataString (Base64)Base64-encoded content of the document. When decoded for PDF, produces a valid PDF file.

Multi-Format Response Example​

{
"documents": [
{
"file_type": "XML",
"data": "PD94bWwgdmVy... (base64)"
},
{
"file_type": "PDF",
"data": "JVBERi0xLjQK... (base64)"
}
]
}

401 - Unauthorized​

Returned when an invalid or missing R-Auth token is provided.


{
"errorMessage": "Authentication is required. Please complete the authentication process.",
"errorType": "AUTHENTICATION_REQUIRED",
"errorTitle": "UNAUTHORIZED",
"errorId": "corr-abc123",
"status": 401,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../pdf"
}

FieldDescription
errorMessageIndicates that the authentication process must be completed.
errorTypeAUTHENTICATION_REQUIRED Token is missing, expired, or invalid.
status401

400 - Bad Request​

Returned when an invalid documentTypes value is provided.


{

"errorMessage": "Unsupported document type: DOCX",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-def456",
"status": 400,
"timestamp": "2026-02-11T14:31:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../docx"
}

FieldDescription
errorMessageSpecifies the unsupported document type and which type was invalid.
errorTypeINVALID_ARGUMENT An invalid parameter was provided.
status400

400 - Bad Request​

Returned when the document's OCR processing has not yet completed (waiting state).

{
"errorMessage": "Invoice is waiting for MelaAIParser. Please try again later",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-ghi789",
"status": 400,
"timestamp": "2026-02-11T14:32:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../json"
}

FieldDescription
errorMessageIndicates the invoice has not been processed by MelaAI yet and should be retried later.
errorTypeINVALID_ARGUMENT The invoice is not in a processable state currently.
status400

404 - Not Found​

Returned when no document matches the provided UUID. Specifically occurs when JSON format is requested and the invoice is not found.

{
"errorMessage": "af6e8982-b791-4704-bc06-d4655faa4b4c Invoice not found!",
"errorType": "NOT_FOUND_INVOICE",
"errorTitle": "NOT_FOUND",
"errorId": "corr-jkl012",
"status": 404,
"timestamp": "2026-02-11T14:33:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../json"
}

FieldDescription
errorMessageReturns a not found message along with the document UUID.
errorTypeNOT_FOUND_INVOICE No matching invoice record exists in the database.
status404

500 - Internal Server Error​

Returned when an unexpected error occurs (e.g., file cannot be retrieved from S3, PDF conversion fails).

{ 

"errorMessage": "Internal server error",
"errorType": "SERVER_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "corr-mno345",
"status": 500,
"timestamp": "2026-02-11T14:34:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../pdf"
}
FieldDescription
errorMessageGeneric server error message.
errorTypeSERVER_ERROR An unexpected error occurred.
status500

Common Error Response Field Descriptions​

Field NameTypeDescription
errorMessageStringHuman readable description of the error
errorTypeStringProgrammatic classification code of the error
errorTitleString (HttpStatus)Text representation of the HTTP status code
errorIdStringRequest correlation ID (for log tracking)
statusIntegerHTTP status code (numeric)
timestampString (ISO 8601)Timestamp when the error occurred
pathStringEndpoint path where the error occurred
detailsMap<String, Object>Additional error details (if available)
validationErrorsList<ValidationError>List of validation errors (if available)

14. Search Processing History POST​

Purpose of Use: The POST /invoice/document-process/search endpoint serves as the central monitoring and querying interface for all document processing activities within the system. Every document whether it is an invoice, credit note, or waybill that enters or leaves the platform passes through an asynchronous processing pipeline. This endpoint provides full visibility into that pipeline.

Endpoint Information​

PropertyValue
URL/invoice/document-process/search
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)
Required AuthorityADMIN, INCOMING_INVOICE_DISPLAY, or OUTGOING_INVOICE_DISPLAY (at least one)

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/document-process/search?page=0&size=20&sort=createdAt,desc' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: <JWT_TOKEN>' \
--data '{
"companyId": "<COMPANY_UUID>",
"createdAt": {
"from": "2024-01-01",
"to": "2026-02-28"
}
}'

Request Parameters​

FieldTypeRequiredDescription
companyIdUUIDYesUnique identifier of the company to search
directionString (Enum)NoDocument direction filter (INCOMING or OUTGOING)
sourceString (Enum)NoSource system filter
filenameStringNoExact match filter by filename
statusString (Enum)NoDocument processing status filter
createdAtObject (DateRange)NoCreation date range filter
createdAt.fromString (LocalDate)NoStart date (inclusive). Format: yyyy-MM-dd. Must be past or present
createdAt.toString (LocalDate)NoEnd date (inclusive). Format: yyyy-MM-dd. Must be past or present

Query Parameters (Pagination)​

FieldTypeDefaultDescription
pageInteger0Page number (0 indexed)
sizeInteger20Number of records per page (max 100)
sortStringcreatedAt,descSort field and direction. Format: field,asc|desc

Enum Value Reference​

direction Values (Document Direction)​

ValueDescription
INCOMINGIncoming document
OUTGOINGOutgoing document

status Values (Processing Status)​

ValueDescription
PENDINGQueued and waiting for processing
PROCESSINGCurrently being processed
COMPLETEDSuccessfully completed
FAILEDProcessing failed (retriable)
SENDING_FAILEDFailed at the sending stage
PERMANENT_FAILEDPermanently failed (will not be retried)

source Values (Relevant to Kazakhstan)​

ValueDescription
ERPERP integration
PORTALWeb portal
PORTAL_OCRPortal upload via OCR
EMAIL_OCROCR via email
EMAILEmail
SFTPSFTP connection
SERVICEInternal service — e.g. the KZ incoming ESF sync (the ESF section below)
HARVEST / SHOPIFY / AMAZON_SP / EBAY / HUBSPOT / LAZADA / STRIPEMarketplace/accounting integrations, available regardless of country

Shared enum: source also carries values for other countries' direct government/network integrations (PEPPOL, KSEF, ANAF, LHDNM, NEMHANDEL, RS_API, ETA, ERACUN) — not applicable to Kazakhstan.

documentType Values (Relevant to Kazakhstan)​

ValueDescription
KZ_ESF_V2Kazakhstan ESF v2 — the only value a Kazakhstan company will see here.

waybillType Values​

⚠️ Not applicable to Kazakhstan: This field only carries Serbia/Romania waybill format codes. Kazakhstan waybills (SNT) are tracked through the dedicated /snt/* API (the SNT section below).

Responses​


200 - Successful Response​

{
"content": [
{
"trackingId": "a1b2c3d4-...",
"companyId": "60ccd1a7-...",
"direction": "INCOMING",
"documentType": "KZ_ESF_V2",
"waybillType": null,
"source": "ERP",
"target": null,
"status": "COMPLETED",
"filename": "invoice_2024_001.xml",
"invoiceNumber": "00900023888",
"documentId": "f5e6d7c8-...",
"sendingResult": "OK",
"errorType": null,
"errors": null,
"additionalData": null,
"createdAt": "2024-06-15T10:30:00",
"statusUpdatedAt": "2024-06-15T10:30:45",
"completedAt": "2024-06-15T10:31:00"
}
],
"totalElements": 150,
"totalPages": 8,
"number": 0,
"size": 20
}

Response Fields​

FieldTypeDescription
contentArray<Object>Page content (document processing records)
content[].trackingIdUUIDProcessing tracking identifier
content[].companyIdUUIDCompany identifier
content[].directionString (Enum)Document direction (INCOMING / OUTGOING)
content[].documentTypeString (Enum)Document format (see documentType enum table)
content[].waybillTypeString (Enum) | nullWaybill type (only for waybill documents)
content[].sourceString (Enum)Source system of the document
content[].targetString (Enum) | nullTarget system for the document
content[].statusString (Enum)Current processing status
content[].filenameStringOriginal filename
content[].invoiceNumberString | nullInvoice number
content[].documentIdUUID | nullAssociated document identifier
content[].sendingResultString | nullSending result message
content[].errorTypeString (Enum) | nullError type code (on failed processes)
content[].errorsObject | nullError details (validation errors, message list, or text)
content[].additionalDataObject | nullCountry or document type specific metadata
content[].createdAtString (DateTime)Creation timestamp. Format: yyyy-MM-ddTHH:mm:ss
content[].statusUpdatedAtString (DateTime)Last status update timestamp
content[].completedAtString (DateTime) | nullCompletion timestamp (only when COMPLETED)
totalElementsLongTotal number of matching records
totalPagesIntegerTotal number of pages
numberIntegerCurrent page number (0-indexed)
sizeIntegerNumber of records per page

400 - Bad Request​

Trigger: When the companyId field is sent as null in the request body (@NotNull validation) or when required fields are missing.
Scenario: Sending a request without providing companyId.

{
"errorMessage": "Document process required fields: companyId",
"errorType": "DOCUMENT_PROCESS_REQUIRED_FIELDS",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-8f2a1b3c",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}

400 - Bad Request ​

Trigger: When the request body JSON format is malformed, an invalid enum value is sent, or the date format is incorrect.

Scenario: Sending a value like "UNKNOWN_STATUS" that is not defined in the enum for the status field, or sending an invalid date like "2024-13-45" for the createdAt.from field.

{
"errorMessage": "Invalid request. Cannot deserialize value of type `DocumentProcessStatus` from String \"UNKNOWN_STATUS\"",
"errorType": "INVALID_REQUEST",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-4d5e6f7a",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}

401 - Unauthorized​

Trigger: When the R-Auth header is not provided or the JWT token signature is invalid. This error is caught at the Spring Security filter chain and does not reach the RestExceptionHandler.

Scenario: Sending a request without the header or with a corrupted/tampered token.

{
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"status": 401
}

401 - Unauthorized​

Trigger: When the JWT token is valid but the user does not have any of the ADMIN, INCOMING_INVOICE_DISPLAY, or OUTGOING_INVOICE_DISPLAY authorities on the specified companyId. Thrown by AuthorizationService.checkAnyAuthorityByCompanyAndUser().

Scenario: Performing a search with a companyId for which the user has no access permissions.

{ 

"errorMessage": "User is not authorized for this operation",
"errorType": "AUTHORIZATION_FAILED",
"errorTitle": "UNAUTHORIZED",
"errorId": "corr-9a8b7c6d",
"status": 401,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}

498 - Token Expired​

Trigger: When the JWT token has expired. Returned by CustomAuthenticationEntryPoint at the Spring Security filter level.

Scenario: Sending a request with an expired JWT token.

{
"errorMessage": "Your session has expired. Please login again.",
"errorType": "TOKEN_EXPIRED",
"errorTitle": "UNAUTHORIZED",
"status": null,
"timestamp": null,
"path": null
}

Note: Since this response is generated at the Security filter level, the timestamp, path, and status fields are not populated by enrichResponse and return null. A custom HTTP status code of 498 is used.

404 - Not Found​

Trigger: When the provided companyId value is not found in the database. A NotFoundException is thrown by CompanyService.

Scenario: Sending a UUID as companyId that has been deleted or never existed.

{
"errorMessage": "Company not found!",
"errorType": "COMPANY_NOT_FOUND",
"errorTitle": "NOT_FOUND",
"errorId": "corr-1b2c3d4e",
"status": 404,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}

500 - Internal Server Error​

Trigger: When an unexpected error occurs on the server side (database connection failure, NullPointerException, etc.). Caught by the RestExceptionHandler catch-all handler.

Scenario: Database access failure, unexpected runtime exception.

{
"errorMessage": "An unexpected error occurred",
"errorType": "SERVER_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "corr-5e6f7a8b",
"status": 500,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}

Response Structure Reference (ExceptionResponse)​

FieldTypeDescriptionInclusion Condition
errorMessageStringHuman readable error descriptionAlways
errorTypeStringMachine readable error code (ErrorType enum name)Always
errorTitleString (HttpStatus)HTTP status description (BAD_REQUEST, UNAUTHORIZED, etc.)Always
errorIdStringCorrelation ID (for log tracing)If present in ThreadContext
statusIntegerHTTP status code (numeric)Always
timestampString (DateTime)Timestamp when the error occurredBy RestExceptionHandler
pathStringURI of the requestBy RestExceptionHandler
dataStringAdditional data informationIf present (@JsonInclude NON_NULL)
detailsMap<String, Object>Additional detail informationIf present (@JsonInclude NON_NULL)
validationErrorsArray<ValidationError>Field level validation errorsIf present (@JsonInclude NON_NULL)

Note: The ExceptionResponse class uses @JsonInclude(JsonInclude.Include.NON_NULL). Therefore, fields with null values are excluded from the JSON response.

15. Mark Document Processing as Read PATCH​

Purpose of Use: The PATCH /invoice/document-process/update/read endpoint flags one or more document-processing records (the same records returned by Section 14 (Search Processing History) and the status endpoints) as read or unread, for building an inbox-style unread counter in an ERP or portal integration. Failed documents are created as unread by default, to draw attention to them.

Endpoint Information​

PropertyValue
URL/invoice/document-process/update/read
MethodPATCH
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token)

Example Request​

curl --location --request PATCH 'https://api-stage.docnova.ai/invoice/document-process/update/read' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"isRead": true,
"companyId": "79499e36-6d45-4c7d-bc52-...",
"trackingIds": ["dd240417-5896-4577-ae51-...", "ee351528-6907-4688-bf62-..."]
}'

Request Parameters​

FieldTypeRequiredDescription
isReadBooleanYesTarget read state to apply to every listed tracking ID.
companyIdUUIDYesCompany the tracking IDs must belong to.
trackingIdsArray<UUID>YesOne or more document-processing tracking IDs to update. Must not be empty.

Responses​

200 - Read Status Updated​

{
"isRead": true,
"companyId": "79499e36-6d45-4c7d-bc52-...",
"trackingIds": ["dd240417-5896-4577-ae51-...", "ee351528-6907-4688-bf62-..."]
}

403 - Forbidden​

Returned when one or more of the given trackingIds do not belong to companyId.

404 - Not Found​

Returned when none of the given trackingIds were found.

About this section: The endpoints below (/esf prefix) are Kazakhstan's native ESF integration layer — a direct, typed mapping of the government ESF SOAP service's own operations, distinct from the generic cross-country /invoice endpoints above. Every endpoint in this section:

  • Requires the R-Auth JWT and an API key with a company already bound to it (restrictedCompanyId) — there is no compId/apiKey body parameter to select the company; it comes from the authenticated API key's own scope.
  • Requires authority ADMIN or ERP_MANAGEMENT_API_KEY_GENERATE.
  • Returns 403 AUTHORIZATION_FAILED if the API key has no company bound to it.
  • Uses Long invoice IDs (the ESF service's own numeric identifier), not the shared platform's invoice UUID.

ESF​

Электронды Шот-Фактура (ЭСФ) / Electronic Invoice-Facture (ESF) — Kazakhstan's primary e-invoice exchange with the KGD (State Revenue Committee). All endpoints below share the /esf prefix and the same company-bound API key authorization described in Authentication.

1. Enterprise Validation POST​

Purpose of Use: The POST /esf/enterprise-validation endpoint validates a counterparty's banking/certificate identifiers against the government registry before an ESF invoice is created against them — catching a bad TIN, BIK or IIK up front instead of as a late ESF rejection.

Endpoint Information​

PropertyValue
URL/esf/enterprise-validation
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/enterprise-validation' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"enterpriseKeyList": [
{
"tin": "123456789012",
"certificateSeries": "AB",
"certificateNum": "1234567",
"bik": "HSBKKZKX",
"iik": "KZ123456789012345678"
}
]
}'

Request Parameters​

FieldTypeRequiredDescription
enterpriseKeyListArray<Object>YesOne or more entities to validate.
enterpriseKeyList[].tinStringYesTaxpayer Identification Number (ИИН/БИН).
enterpriseKeyList[].certificateSeriesStringNoE-signature certificate series.
enterpriseKeyList[].certificateNumStringNoE-signature certificate number.
enterpriseKeyList[].bikStringNoBank identification code.
enterpriseKeyList[].iikStringNoIndividual identification code (bank account).

Responses​

200 - Successful Response​

{
"resultList": {
"enterpriseValidationResult": [
{ "tin": "123456789012", "resultType": "SUCCESS" }
]
}
}
FieldTypeDescription
resultList.enterpriseValidationResultArray<Object>One result per requested key, in request order.
[].tinStringEchoes the validated TIN.
[].resultTypeString (Enum)See values below.

EnterpriseValidationResultType Values​

ValueDescription
SUCCESSAll supplied identifiers are valid and consistent with the registry.
TIN_ABSENTTIN/BIN not found in the registry.
CERTIFICATE_SERIES_OR_CERTIFICATE_NUM_ABSENTCertificate series or number not found.
BIK_ABSENTBank identification code not found.
BANK_NOT_FOUNDNo bank matches the given BIK.
IIK_ABSENTAccount identification code not found.

2. Upload Invoice List (Sync) POST​

Purpose of Use: The POST /esf/upload-invoice-list endpoint is the native ESF submission call — it submits one or more pre-signed ESF XML documents directly to the government service (synchronously) and returns, per document, whether it was accepted or declined. This is the lowest-level submission primitive; the generic /invoice endpoints in the section above are built on top of it.

⚠️ Note: Every document in invoiceUploadInfoList gets its own reservation, quota charge, and result — a rejection on one document never discards or retries the others in the same call.

Endpoint Information​

PropertyValue
URL/esf/upload-invoice-list
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/upload-invoice-list' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"invoiceUploadInfoList": [
{
"invoiceBody": "<BASE64_ENCODED_ESF_V2_XML>",
"version": "InvoiceV2",
"signature": "<BASE64_ESF_SIGNATURE_MAX_400_CHARS>",
"signatureType": "COMPANY"
}
]
}'

Request Parameters​

FieldTypeRequiredDescription
invoiceUploadInfoListArray<Object>YesOne or more documents to submit.
invoiceUploadInfoList[].invoiceBodyString (Base64)YesThe ESF XML body, Base64-encoded.
invoiceUploadInfoList[].versionString (Enum)NoInvoiceV1 or InvoiceV2 (default).
invoiceUploadInfoList[].signatureStringYesThe e-signature over the invoice body, max 400 characters.
invoiceUploadInfoList[].signatureTypeString (Enum)YesCOMPANY (company's own e-signature) or OPERATOR (an authorized operator signs on the company's behalf).

Responses​

200 - Successful Response​

{
"acceptedSet": {
"standardResponse": [
{ "id": 22116203282, "num": "00900023888", "date": "2026-09-16" }
]
},
"declinedSet": {
"standardResponse": [
{ "num": "00900023889", "date": "2026-09-16", "errors": { "error": [ { "property": "seller.tin", "errorCode": "REQUIRED", "text": "Seller TIN is required" } ] } }
]
}
}
FieldTypeDescription
acceptedSet.standardResponseArray<Object>One entry per accepted document.
declinedSet.standardResponseArray<Object>One entry per rejected document, with the validation errors that caused the rejection.
[].idLongESF's own numeric invoice ID. Present only in acceptedSet. Use this value as idList on the query/action endpoints below.
[].numStringInvoice number, echoed from the XML.
[].dateStringInvoice date, echoed from the XML.
[].errors.error[].propertyStringThe XML field that failed validation, when present.
[].errors.error[].errorCodeStringESF error code.
[].errors.error[].textStringHuman-readable error description.

3. Query Updates POST​

Purpose of Use: The POST /esf/query-updates endpoint is the recommended polling primitive for keeping a local system in sync with ESF: given the last event date/invoice ID the caller has already processed, it returns the next batch of invoices (new or changed) in event order.

Endpoint Information​

PropertyValue
URL/esf/query-updates
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-updates' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"lastEventDate": "2026-09-16T07:00:00",
"lastInvoiceId": 22116203200,
"direction": "INBOUND",
"limit": 50,
"fullInfoOnStatusChange": false
}'

Request Parameters​

FieldTypeRequiredDescription
lastEventDateStringNoResume point. Omit on the very first call to start from the beginning.
lastInvoiceIdLongNoTie-breaker for lastEventDate — advance past this invoice too.
directionString (Enum)NoINBOUND or OUTBOUND.
limitIntegerNoPage size.
fullInfoOnStatusChangeBooleanNoWhen true, includes the full invoice body on status-only changes too, not just on new invoices.

Responses​

200 - Successful Response​

{
"lastEventDate": "2026-09-16T07:30:00",
"lastInvoiceId": 22116203282,
"lastBlock": true,
"invoiceInfoList": {
"invoiceInfo": [
{
"invoiceId": 22116203282,
"invoiceBody": "<BASE64_ESF_V2_XML>",
"registrationNumber": "KZ...",
"inputDate": "2026-09-16T07:25:50",
"lastUpdateDate": "2026-09-16T07:26:00",
"signatureValid": true,
"invoiceStatus": "DELIVERED",
"version": "InvoiceV2",
"signatureType": "COMPANY",
"certificate": "<BASE64_CERTIFICATE>"
}
]
}
}
FieldTypeDescription
lastEventDate / lastInvoiceId—Pass both back as-is on the next call to continue from here.
lastBlockBooleantrue when this page is the last available page — keep polling at interval; false means more pages are ready now, call again immediately with the returned cursor.
invoiceInfoList.invoiceInfoArray<Object>The batch of updated invoices — see the InvoiceInfo fields below.

InvoiceInfo Fields​

FieldTypeDescription
invoiceBodyString (Base64)The full ESF XML.
invoiceIdLongESF's numeric invoice ID.
registrationNumberStringGovernment registration number, once assigned.
inputDate / deliveryDate / lastUpdateDateDateTimeLifecycle timestamps.
signatureValidBooleanWhether the e-signature validated successfully.
invoiceStatusString (Enum)See the InvoiceStatus table below.
cancelReasonStringPopulated for canceled/declined/revoked invoices.
versionString (Enum)InvoiceV1 / InvoiceV2.
signatureTypeString (Enum)COMPANY / OPERATOR.
certificateStringThe signer's certificate.
deadlineObjectAny statutory response deadline attached to the invoice, when applicable.
kogdStringTax authority code, when applicable.

InvoiceStatus Values (ESF)​

ValueDescription
IN_QUEUEQueued
IN_PROCESSINGProcessing
CREATEDCreated
DELIVEREDDelivered
CANCELEDCanceled
CANCELED_BY_OGDCanceled by tax authority for accounting purposes
CANCELED_BY_SNT_DECLINECanceled because the linked waybill (SNT) was declined
CANCELED_BY_SNT_REVOKECanceled because the linked waybill (SNT) was revoked
REVOKEDRevoked
IMPORTEDImported from a legacy system
DRAFTDraft
FAILEDFailed
DELETEDDeleted
DECLINEDDeclined
SEND_TO_ISGOForwarded to ISGO (goods tracking)
WAIT_BIOMETRICS_VERIFICATIONAwaiting biometric identification
FAILED_BIOMETRICS_VERIFICATIONBiometric identification failed
DELETED_BIOMETRICS_VERIFICATIONDeleted before biometric identification completed
WAITING_CUSTOMER_CONFIRMATIONAwaiting recipient confirmation
WAITING_CUSTOMER_REVOKE_CONFIRMATIONAwaiting recipient confirmation of a revoke request

4. Get Unread Invoices POST​

Purpose of Use: The POST /esf/unread-invoices endpoint returns the invoices the company has not yet marked as read — a simpler alternative to Query Updates for building an inbox-style "new invoices" indicator.

Status credit: Each new status this endpoint reads from KGD is charged as described in Status credit (Introduction), and the status is stored on the invoice in the same call. When there is no unread invoice, KGD is not asked and nothing is charged. Without credit the call answers HTTP 400 LIFECYCLE_CREDIT_EXHAUSTED and KGD is not asked.

Endpoint Information​

PropertyValue
URL/esf/unread-invoices
MethodPOST
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/unread-invoices' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Responses​

200 - Successful Response​

Returns an array of InvoiceDTO objects (same shape as the Query Invoice response in the next section).

5. Set Read/Unread Invoices POST​

Purpose of Use: The POST /esf/set-read-list endpoint marks one or more ESF invoices as read.

Endpoint Information​

PropertyValue
URL/esf/set-read-list
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/set-read-list' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282, 22116203283] }'

Request Parameters​

FieldTypeRequiredDescription
idListArray<Long>YesESF numeric invoice IDs to mark as read.

Responses​

200 - Successful Response​

true

Returns a plain boolean indicating success.

6. Get Invoice Status List by ID POST​

Purpose of Use: The POST /esf/get-invoice-status-list-by-id endpoint returns just the current status (not the full body) for a batch of invoice IDs — a lightweight way to refresh status for a list already held locally.

Status credit: Each new status this endpoint reads from KGD is charged as described in Status credit (Introduction). Without credit the call answers HTTP 400 LIFECYCLE_CREDIT_EXHAUSTED and KGD is not asked.

Endpoint Information​

PropertyValue
URL/esf/get-invoice-status-list-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/get-invoice-status-list-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282, 22116203283] }'

Request Parameters​

FieldTypeRequiredDescription
idListArray<Long>YesESF numeric invoice IDs to check.

Responses​

200 - Successful Response​

[
{ "invoiceId": 22116203282, "status": "DELIVERED", "cancelReason": null }
]
FieldTypeDescription
invoiceIdLongESF numeric invoice ID.
statusString (Enum)See the InvoiceStatus table in the previous section.
cancelReasonString | nullPopulated for canceled/declined/revoked invoices.

7. Query Invoice POST​

Purpose of Use: The POST /esf/query-invoice-request endpoint searches ESF invoices by criteria (direction, date range, status, type) and returns them converted into the platform's own InvoiceDTO shape, ready for display.

Endpoint Information​

PropertyValue
URL/esf/query-invoice-request
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-invoice-request' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"criteria": {
"direction": "INBOUND",
"dateFrom": "2026-09-01T00:00:00+06:00",
"dateTo": "2026-09-30T23:59:59+06:00",
"invoiceStatusList": ["DELIVERED", "CREATED"],
"invoiceType": "ORDINARY_INVOICE",
"asc": false,
"pageNum": 0
}
}'

Request Parameters​

FieldTypeRequiredDescription
criteria.directionString (Enum)NoINBOUND (default) or OUTBOUND.
criteria.dateFrom / criteria.dateToDateTimeNoDate range filter.
criteria.invoiceStatusListArray<String>NoFilter by one or more InvoiceStatus values.
criteria.invoiceTypeString (Enum)NoORDINARY_INVOICE, FIXED_INVOICE, or ADDITIONAL_INVOICE.
criteria.ascBooleanNoSort direction.
criteria.pageNumIntegerNoPage number.

InvoiceType Values​

ValueDescription
ORDINARY_INVOICEStandard ESF invoice
FIXED_INVOICECorrective ESF invoice (A4)
ADDITIONAL_INVOICESupplementary ESF invoice (A5)

Responses​

200 - Successful Response​

[
{
"id": "22116203282",
"companyId": "79499e36-6d45-4c7d-bc52-...",
"invoiceGuid": "a1b2c3d4-...",
"slipDate": "2026-09-16",
"issueDate": "2026-09-16",
"slipNr": "00900023888",
"taxNr": "123456789012",
"clientName": "Supplier LLP",
"status": "DELIVERED",
"invoiceType": "ORDINARY_INVOICE",
"invoiceNo": "00900023888",
"quantity": 10,
"price": 1500.00,
"grossTotal": 16800.00,
"netTotal": 15000.00,
"totalVat": 1800.00,
"payableAmount": 16800.00,
"currencyCode": "KZT",
"itemList": []
}
]
FieldTypeDescription
idStringESF numeric invoice ID, as a string.
companyIdUUIDShared platform company identifier.
invoiceGuidStringESF's own GUID for the invoice, when present.
slipDate / issueDate / deliveryDocDateString (Date)Document dates.
slipNr / invoiceNo / deliveryDocNumStringDocument numbers.
taxNrStringCounterparty TIN/BIN.
clientNameStringCounterparty name.
statusString (Enum)See the InvoiceStatus table above.
invoiceTypeString (Enum)See the InvoiceType table above.
invoiceObjectXml / xmlDataStringRaw XML, when requested/available.
htmlView / pdfViewStringRendered views, when available.
quantityIntegerLine item count or quantity summary.
price / grossTotal / netTotal / totalDiscount / totalVat / payableAmount / vatBigDecimalMonetary fields. Never null — default to zero when absent.
currencyCodeStringISO 4217 currency code.
currencyRateDoubleExchange rate applied, when the currency is not KZT.
itemListArray<Object>Line items, when available.

8. Query Invoice by ID POST​

Purpose of Use: The POST /esf/query-invoice-by-id-request endpoint retrieves the full ESF XML body and metadata for a specific set of invoices by their numeric ESF ID — the direct counterpart of Query Updates for a known ID rather than a date range.

Endpoint Information​

PropertyValue
URL/esf/query-invoice-by-id-request
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-invoice-by-id-request' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

FieldTypeRequiredDescription
idListArray<Long>YesESF numeric invoice IDs to retrieve.

Responses​

200 - Successful Response​

{
"lastBlock": true,
"currPage": 0,
"rsCount": 1,
"invoiceInfoList": {
"invoiceInfo": [ { "invoiceId": 22116203282, "invoiceBody": "<BASE64_ESF_V2_XML>", "invoiceStatus": "DELIVERED" } ]
}
}
FieldTypeDescription
lastBlockBooleanWhether this is the final page of results.
currPageIntegerCurrent page number.
rsCountIntegerTotal result count.
invoiceInfoList.invoiceInfoArray<Object>Same InvoiceInfo shape as in Query Updates.

9. Query Invoice by Key POST​

Purpose of Use: The POST /esf/query-invoice-by-key-request endpoint is identical to Query Invoice by ID, but looks invoices up by their business key (invoice number + date) instead of the ESF numeric ID — useful when the ESF ID was never recorded locally.

Endpoint Information​

PropertyValue
URL/esf/query-invoice-by-key-request
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-invoice-by-key-request' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"invoiceKeyList": [ { "num": "00900023888", "date": "2026-09-16" } ],
"direction": "OUTBOUND"
}'

Request Parameters​

FieldTypeRequiredDescription
invoiceKeyListArray<Object>YesKeys to look up.
invoiceKeyList[].numStringYesInvoice number.
invoiceKeyList[].dateStringYesInvoice date.
directionString (Enum)YesINBOUND or OUTBOUND — the number/date pair is only unique within one direction.

Responses​

Same response shape as Query Invoice by ID.

10. Query Invoice Summary by ID POST​

Purpose of Use: The POST /esf/query-invoice-summary-by-id-request endpoint returns just the summary (status, dates, registration number) for a batch of invoice IDs — without the full XML body — for a lighter-weight status check than Query Invoice by ID.

Endpoint Information​

PropertyValue
URL/esf/query-invoice-summary-by-id-request
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-invoice-summary-by-id-request' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

Same as Query Invoice by ID: idList (Array<Long>, required).

Responses​

200 - Successful Response​

{
"invoiceSummaryList": {
"invoiceSummary": [
{
"invoiceId": 22116203282,
"date": "2026-09-16",
"invoiceStatus": "DELIVERED",
"num": "00900023888",
"cancelReason": null,
"registrationNumber": "KZ...",
"lastUpdateDate": "2026-09-16T07:26:00"
}
]
}
}
FieldTypeDescription
invoiceSummaryList.invoiceSummaryArray<Object>One summary per requested ID.
[].invoiceIdLongESF numeric invoice ID.
[].date / [].numStringInvoice date/number.
[].invoiceStatusString (Enum)See the InvoiceStatus table above.
[].cancelReasonString | nullPopulated for canceled/declined/revoked invoices.
[].registrationNumberStringGovernment registration number.
[].lastUpdateDateDateTimeLast status change timestamp.

11. Query Invoice Summary by Key POST​

Purpose of Use: The POST /esf/query-invoice-summary-by-key-request endpoint is the summary-only counterpart of Query Invoice by Key.

Endpoint Information​

PropertyValue
URL/esf/query-invoice-summary-by-key-request
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-invoice-summary-by-key-request' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"invoiceKeyList": [ { "num": "00900023888", "date": "2026-09-16" } ],
"direction": "OUTBOUND"
}'

Request Parameters​

Same as Query Invoice by Key: invoiceKeyList and direction.

Responses​

Same response shape as Query Invoice Summary by ID.

12. Query Invoice History by ID POST​

Purpose of Use: The POST /esf/query-invoice-history-by-id-request endpoint returns the full status change history (audit trail) of an ESF invoice — who changed it, to what status, and when.

Endpoint Information​

PropertyValue
URL/esf/query-invoice-history-by-id-request
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-invoice-history-by-id-request' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

Same as Query Invoice by ID: idList.

Responses​

200 - Successful Response​

{
"resultList": {
"esfHistory": [
{
"invoiceId": 22116203282,
"status": "DELIVERED",
"dateTime": "2026-09-16T07:26:00",
"userId": "123456789012",
"tin": "123456789012",
"statusDescription": "Invoice delivered to recipient",
"clientType": "SUPPLIER"
}
]
}
}
FieldTypeDescription
resultList.esfHistoryArray<Object>Chronological list of status changes.
[].invoiceIdLongESF numeric invoice ID.
[].statusString (Enum)See the InvoiceStatus table above.
[].dateTimeDateTimeWhen the change occurred.
[].userId / [].tinStringWho made the change.
[].statusDescriptionStringHuman-readable description of the change.
[].clientTypeString (Enum)Whether the change was made by the SUPPLIER or the CUSTOMER side.

13. Query Invoice Error by ID POST​

Purpose of Use: The POST /esf/query-invoice-error-by-id-request endpoint returns the validation errors recorded against a FAILED invoice — the detail that Upload Invoice List's declinedSet gives inline, retrievable later by ID.

Endpoint Information​

PropertyValue
URL/esf/query-invoice-error-by-id-request
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/query-invoice-error-by-id-request' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

Same as Query Invoice by ID: idList.

Responses​

200 - Successful Response​

{
"invoiceErrorList": {
"invoiceError": [
{
"invoiceId": 22116203282,
"errors": { "error": [ { "property": "seller.tin", "errorCode": "REQUIRED", "text": "Seller TIN is required" } ] }
}
]
}
}
FieldTypeDescription
invoiceErrorList.invoiceErrorArray<Object>One entry per requested invoice.
[].invoiceIdLongESF numeric invoice ID.
[].errors.error[].propertyStringThe XML field that failed validation.
[].errors.error[].errorCodeStringESF error code.
[].errors.error[].textStringHuman-readable error description.

14. Approve Invoice by ID POST​

Purpose of Use: The POST /esf/approve-by-id endpoint is the recipient's acceptance action — it moves one or more invoices to the CREATED/delivered-and-accepted state.

Shared result shape: This endpoint and the five that follow (Confirm, Confirm Revoke, Decline, Revoke, Unrevoke) all return the same TryChangeStatusResponse envelope, shown once here.

Endpoint Information​

PropertyValue
URL/esf/approve-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/approve-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

FieldTypeRequiredDescription
idListArray<Long>YesESF numeric invoice IDs to approve.

Responses​

200 - Successful Response​

{
"resultList": {
"changeStatusResult": [
{
"invoiceSummary": { "invoiceId": 22116203282, "invoiceStatus": "CREATED", "num": "00900023888", "date": "2026-09-16" },
"isChanged": true,
"errorCode": null,
"errorText": null
}
]
}
}
FieldTypeDescription
resultList.changeStatusResultArray<Object>One result per requested ID, in request order — a partial success for some IDs never discards the others.
[].invoiceSummaryObjectThe invoice's resulting summary — same shape as Query Invoice Summary by ID's items.
[].isChangedBooleanWhether the status actually changed as a result of this call.
[].errorCode / [].errorTextString | nullPopulated when isChanged is false because the transition was not allowed from the invoice's current status.

15. Confirm Invoice by ID POST​

Purpose of Use: The POST /esf/confirm-by-id endpoint confirms one or more invoices.

⚠️ Different response envelope: Unlike its five siblings, this endpoint's native ESF operation returns an InvoiceSummaryResponse (a flat list of summaries) rather than TryChangeStatusResponse — there is no per-item isChanged/errorCode.

Endpoint Information​

PropertyValue
URL/esf/confirm-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/confirm-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

Same as Approve Invoice by ID: idList.

Responses​

200 - Successful Response​

{
"invoiceSummaryList": {
"invoiceSummary": [
{ "invoiceId": 22116203282, "invoiceStatus": "WAITING_CUSTOMER_CONFIRMATION", "num": "00900023888", "date": "2026-09-16" }
]
}
}

Same InvoiceSummary field shape as Query Invoice Summary by ID.

16. Confirm Revoke Invoice by ID POST​

Purpose of Use: The POST /esf/confirm-revoke-by-id endpoint is the recipient's confirmation of a supplier's revoke request — completing the two-sided revoke flow once the supplier has called Revoke Invoice by ID.

Endpoint Information​

PropertyValue
URL/esf/confirm-revoke-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/confirm-revoke-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

Same as Approve Invoice by ID: idList.

Responses​

Same TryChangeStatusResponse envelope as Approve Invoice by ID — resulting status REVOKED.

17. Decline Invoice by ID POST​

Purpose of Use: The POST /esf/decline-by-id endpoint is the recipient's rejection action, with a required reason per invoice.

Endpoint Information​

PropertyValue
URL/esf/decline-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/decline-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idWithReasonList": [ { "id": 22116203282, "reason": "Incorrect quantity" } ] }'

Request Parameters​

FieldTypeRequiredDescription
idWithReasonListArray<Object>YesOne or more invoices to decline.
idWithReasonList[].idLongYesESF numeric invoice ID.
idWithReasonList[].reasonStringYesReason for declining.

Responses​

Same TryChangeStatusResponse envelope as Approve Invoice by ID — resulting status DECLINED.

18. Revoke Invoice by ID POST​

Purpose of Use: The POST /esf/revoke-invoice-by-id endpoint is the supplier's revoke request — it starts the two-sided revoke flow (status moves to WAITING_CUSTOMER_REVOKE_CONFIRMATION) that the recipient completes via Confirm Revoke Invoice by ID.

Endpoint Information​

PropertyValue
URL/esf/revoke-invoice-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/revoke-invoice-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idWithReasonList": [ { "id": 22116203282, "reason": "Incorrect quantity" } ] }'

Request Parameters​

Same as Decline Invoice by ID: idWithReasonList.

Responses​

Same TryChangeStatusResponse envelope as Approve Invoice by ID — resulting status WAITING_CUSTOMER_REVOKE_CONFIRMATION.

19. Unrevoke Invoice by ID POST​

Purpose of Use: The POST /esf/unrevoke-invoice-by-id endpoint cancels a revoke request that has not yet been confirmed by the recipient, restoring the invoice's prior status.

Endpoint Information​

PropertyValue
URL/esf/unrevoke-invoice-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/unrevoke-invoice-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idWithReasonList": [ { "id": 22116203282, "reason": "Reconsidered — invoice is valid" } ] }'

Request Parameters​

Same as Decline Invoice by ID: idWithReasonList.

Responses​

Same TryChangeStatusResponse envelope as Approve Invoice by ID.

20. Delete Invoice by ID POST​

Purpose of Use: The POST /esf/delete-by-id endpoint deletes one or more ESF invoices that have not progressed past a deletable status (e.g. a DRAFT or FAILED invoice).

Endpoint Information​

PropertyValue
URL/esf/delete-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/esf/delete-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [22116203282] }'

Request Parameters​

Same as Approve Invoice by ID: idList.

Responses​

200 - Successful Response​

{
"resultList": {
"changeStatusResult": [
{ "invoiceId": 22116203282, "isDeleted": true }
]
}
}
FieldTypeDescription
resultList.changeStatusResultArray<Object>One result per requested ID.
[].invoiceIdLongESF numeric invoice ID.
[].isDeletedBooleanfalse when the invoice's current status does not allow deletion.

About this section: The endpoints below (/snt prefix) are Kazakhstan's native SNT (waybill) integration layer — the ESF system's companion service for electronic waybills (накладные), mirroring the /esf section's pattern one-to-one. The same rules apply: authentication is via a company-bound API key (no compId parameter), authority ADMIN or ERP_MANAGEMENT_API_KEY_GENERATE is required, and IDs are the SNT service's own numeric sntId.

SNT​

Электронная счет-фактура товаротранспортная накладная (ЭСФ ТТН) / electronic waybill (SNT) — Kazakhstan's electronic waybill exchange with the KGD, tracking the physical movement of goods alongside the ESF invoice. All endpoints below share the /snt prefix and the same authorization as ESF.

1. Upload SNT POST​

Purpose of Use: The POST /snt/upload-snt endpoint submits one or more signed SNT (waybill) XML documents to the government service.

⚠️ Note: Like ESF's Upload Invoice List, every document in sntUploadInfoList is validated and submitted independently — one rejection does not affect the others.

Endpoint Information​

PropertyValue
URL/snt/upload-snt
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/upload-snt' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"sntUploadInfoList": [
{
"sntBody": "<BASE64_ENCODED_SNT_V1_XML>",
"version": "SntV1",
"signature": "<BASE64_SNT_SIGNATURE>",
"signatureType": "COMPANY"
}
]
}'

Request Parameters​

FieldTypeRequiredDescription
sntUploadInfoListArray<Object>YesOne or more waybills to submit.
sntUploadInfoList[].sntBodyString (Base64)YesThe SNT XML body, Base64-encoded.
sntUploadInfoList[].versionString (Enum)NoSntV1 (default, and currently the only version).
sntUploadInfoList[].signatureStringYesE-signature over the SNT body.
sntUploadInfoList[].signatureTypeString (Enum)YesCOMPANY or OPERATOR.

Responses​

200 - Successful Response​

{
"acceptedList": {
"sntUploadResult": [ { "sntId": 9887654321, "number": "SNT-00012345", "date": "2026-09-16" } ]
},
"declinedList": {
"sntUploadResult": [
{ "number": "SNT-00012346", "date": "2026-09-16", "errorList": { "error": [ { "property": "recipient.tin", "errorCode": "REQUIRED", "text": "Recipient TIN is required" } ] } }
]
}
}
FieldTypeDescription
acceptedList.sntUploadResult / declinedList.sntUploadResultArray<Object>One entry per submitted document, split by outcome.
[].sntIdLongSNT's own numeric ID. Present only in acceptedList. Use this as idList on the query/action endpoints below.
[].number / [].dateStringWaybill number/date, echoed from the XML.
[].errorList.error[]Array<Object>Validation errors, when declined — same property/errorCode/text shape as ESF's errors.

2. Get Unread Waybills POST​

Purpose of Use: The POST /snt/unread-waybills endpoint is the SNT equivalent of ESF's Query Updates — the polling primitive for new/changed waybills since a given cursor.

Endpoint Information​

PropertyValue
URL/snt/unread-waybills
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/unread-waybills' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"direction": "INBOUND",
"lastEventDate": "2026-09-16T07:00:00",
"lastSntId": 9887654300,
"limit": 50
}'

Request Parameters​

FieldTypeRequiredDescription
directionString (Enum)NoINBOUND or OUTBOUND.
lastEventDateDateTimeNoResume point. Omit to start from the beginning.
lastSntIdLongNoTie-breaker for lastEventDate.
limitIntegerNoPage size.

Responses​

200 - Successful Response​

{
"lastEventDate": "2026-09-16T07:30:00",
"lastSntId": 9887654321,
"lastBlock": true,
"sntInfoList": {
"sntInfo": [
{
"sntId": 9887654321,
"inputDate": "2026-09-16T07:25:50",
"lastUpdateDate": "2026-09-16T07:26:00",
"registrationNumber": "KZ...",
"version": "SntV1",
"status": "DELIVERED"
}
]
}
}
FieldTypeDescription
lastEventDate / lastSntId—Pass both back on the next call to resume from here.
lastBlockBooleanfalse means more pages are ready now — call again immediately.
sntInfoList.sntInfoArray<Object>The batch of updated waybills — see SntInfo fields below.

SntInfo Fields​

FieldTypeDescription
sntIdLongSNT numeric ID.
inputDate / lastUpdateDate / dateForFixedDateTimeLifecycle timestamps.
registrationNumberStringGovernment registration number, once assigned.
versionString (Enum)SntV1.
statusString (Enum)See the SntStatus table below.
documentInfoObjectShipment document details (sender/recipient, goods, transport).
acceptanceGoodsInfoObject | nullGoods acceptance details, once the recipient has acted.
ogdMarksInfoObject | nullCustoms/tax authority marks, when applicable.
cancelReasonString | nullPopulated for canceled/revoked/declined waybills.
primarySntIdLong | nullThe original waybill this one corrects/supersedes, when applicable.

SntStatus Values​

ValueDescription
DRAFTDraft
NOT_VIEWEDNot yet viewed by the recipient
DELIVEREDDelivered
CREATEDCreated
IMPORTEDImported from a legacy system
FAILEDFailed
CONFIRMEDConfirmed by recipient
DECLINEDDeclined by recipient
CONFIRMED_BY_OGDConfirmed by tax authority inspector
DECLINED_BY_OGDDeclined by tax authority inspector
CANCELEDCanceled
REVOKEDRevoked
SEND_TO_ISGOForwarded to ISGO (goods tracking)

3. Query SNT by ID POST​

Purpose of Use: The POST /snt/query-snt-by-id endpoint retrieves the full details for a specific set of waybills by their numeric SNT ID.

Endpoint Information​

PropertyValue
URL/snt/query-snt-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/query-snt-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [9887654321] }'

Request Parameters​

FieldTypeRequiredDescription
idListArray<Long>YesSNT numeric IDs to retrieve.

Responses​

200 - Successful Response​

{
"lastBlock": true,
"currPage": 0,
"rsCount": 1,
"sntInfoList": { "sntInfo": [ { "sntId": 9887654321, "status": "DELIVERED" } ] }
}

Same SntInfo shape as Get Unread Waybills, paginated the same way as ESF's Query Invoice by ID.

4. Query by Regnum POST​

Purpose of Use: The POST /snt/query-by-regnum endpoint resolves one or more government registration numbers to the platform's internal SNT numeric IDs — needed because the registration number is only assigned after submission and is not known ahead of time.

Endpoint Information​

PropertyValue
URL/snt/query-by-regnum
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/query-by-regnum' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "regnumList": ["KZ20260916000012345"] }'

Request Parameters​

FieldTypeRequiredDescription
regnumListArray<String>YesGovernment registration numbers to resolve.

Responses​

200 - Successful Response​

{
"regnumIdMap": {
"entry": [ { "key": "KZ20260916000012345", "value": 9887654321 } ]
}
}
FieldTypeDescription
regnumIdMap.entryArray<Object>One map entry per requested registration number.
[].keyStringThe registration number, echoed.
[].valueLongThe resolved SNT numeric ID — use this on the other query/action endpoints.

5. Query Status by Regnum POST​

Purpose of Use: The POST /snt/query-status-by-regnum endpoint returns an extended status summary directly by registration number, skipping the two-step resolve-then-query of Query by Regnum + Query SNT by ID — and additionally surfaces any linked FNO matching information (goods declaration cross-checks).

Status credit: Each new status this endpoint reads from KGD is charged as described in Status credit (Introduction); this endpoint and Query SNT Status by ID charge one SNT once for the same status. Without credit the call answers HTTP 400 LIFECYCLE_CREDIT_EXHAUSTED and KGD is not asked.

Endpoint Information​

PropertyValue
URL/snt/query-status-by-regnum
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/query-status-by-regnum' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "regnumList": ["KZ20260916000012345"] }'

Request Parameters​

Same as Query by Regnum: regnumList.

Responses​

200 - Successful Response​

{
"sntExtendedSummaryList": {
"sntExtendedSummary": [
{
"summary": { "sntId": 9887654321, "registrationNumber": "KZ20260916000012345", "status": "DELIVERED", "senderTin": "123456789012", "recipientTin": "987654321098", "matchingNotification": false },
"fnoMatchingInfos": null
}
]
}
}
FieldTypeDescription
sntExtendedSummaryList.sntExtendedSummaryArray<Object>One entry per resolved registration number.
[].summaryObject (SntSummary)See fields below.
[].fnoMatchingInfosObject | nullLinked goods-declaration matching records, when any exist.

SntSummary Fields​

FieldTypeDescription
sntIdLongSNT numeric ID.
inputDate / lastUpdateDateDateTimeLifecycle timestamps.
registrationNumberStringGovernment registration number.
versionStringSNT schema version.
statusString (Enum)See the SntStatus table in Get Unread Waybills.
cancelReasonString | nullPopulated for canceled/declined/revoked waybills.
senderTin / recipientTinStringParties' TIN/BIN.
matchingNotificationBooleanWhether an FNO matching discrepancy notification exists for this waybill.

6. Query View SNT POST​

Purpose of Use: The POST /snt/query-view-snt endpoint marks the specified waybills as viewed by the recipient and returns their change-status result — used when a recipient opens a waybill in the UI, moving it out of NOT_VIEWED.

Endpoint Information​

PropertyValue
URL/snt/query-view-snt
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/query-view-snt' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [9887654321] }'

Request Parameters​

Same as Query SNT by ID: idList.

Responses​

200 - Successful Response​

{
"resultList": {
"changeStatusResult": [
{ "sntSummary": { "sntId": 9887654321, "status": "DELIVERED" }, "isChanged": true, "canceledInvoiceRegNumbers": null, "errors": null, "notifications": null }
]
}
}
FieldTypeDescription
resultList.changeStatusResultArray<Object>One result per requested ID.
[].sntSummaryObjectSame SntSummary shape as Query Status by Regnum.
[].isChangedBooleanWhether the view was newly recorded.
[].canceledInvoiceRegNumbersArray<String> | nullESF invoice registration numbers canceled as a side effect, when applicable.
[].errorsArray<Object> | nullPopulated when the action could not be applied.
[].notificationsArray<Object> | nullAny notifications raised as a result of this action.

Shared envelope: This changeStatusResult shape is also used by Change Status (below).

7. Query SNT History by ID POST​

Purpose of Use: The POST /snt/query-snt-history-by-id endpoint returns the full status change history (audit trail) of a waybill — the SNT equivalent of ESF's Query Invoice History by ID.

Endpoint Information​

PropertyValue
URL/snt/query-snt-history-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/query-snt-history-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [9887654321] }'

Request Parameters​

Same as Query SNT by ID: idList.

Responses​

200 - Successful Response​

{
"resultList": {
"sntHistory": [
{ "sntId": 9887654321, "date": "2026-09-16T07:26:00", "tin": "123456789012", "clientType": "SUPPLIER", "userId": "...", "status": "DELIVERED", "statusDescription": "Waybill delivered", "action": "SEND" }
]
}
}
FieldTypeDescription
resultList.sntHistoryArray<Object>Chronological list of status changes.
[].sntIdLongSNT numeric ID.
[].dateDateTimeWhen the change occurred.
[].tin / [].userIdStringWho made the change.
[].clientTypeString (Enum)SUPPLIER or CUSTOMER.
[].statusString (Enum)See the SntStatus table in Get Unread Waybills.
[].statusDescriptionStringHuman-readable description.
[].actionString (Enum)The action type that produced this history entry.

8. Query SNT Error by ID POST​

Purpose of Use: The POST /snt/query-snt-error-by-id endpoint returns the validation errors recorded against a FAILED waybill.

Endpoint Information​

PropertyValue
URL/snt/query-snt-error-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/query-snt-error-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [9887654321] }'

Request Parameters​

Same as Query SNT by ID: idList.

Responses​

200 - Successful Response​

{
"sntErrorList": {
"sntError": [
{ "sntId": 9887654321, "errors": { "error": [ { "property": "recipient.tin", "errorCode": "REQUIRED", "text": "Recipient TIN is required" } ] } }
]
}
}

Same property/errorCode/text error shape as ESF's Query Invoice Error by ID.

9. Change Status POST​

Purpose of Use: The POST /snt/change-status endpoint is the general-purpose waybill lifecycle action — confirm, decline, cancel, or otherwise act on one or more waybills, with the action itself carried inside each waybill's signed action body rather than as a separate parameter.

Endpoint Information​

PropertyValue
URL/snt/change-status
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/change-status' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"sntActionInfoList": [
{
"sntId": 9887654321,
"sntActionBody": "<BASE64_ENCODED_ACTION_XML>",
"sntVersion": "SntV1",
"signatureType": "COMPANY"
}
]
}'

Request Parameters​

FieldTypeRequiredDescription
sntActionInfoListArray<Object>YesOne or more actions to apply.
sntActionInfoList[].sntIdLongYesThe waybill to act on.
sntActionInfoList[].sntActionBodyString (Base64)YesThe signed action XML (confirm/decline/cancel), Base64-encoded.
sntActionInfoList[].sntVersionString (Enum)NoSntV1 (default).
sntActionInfoList[].signatureTypeString (Enum)NoCOMPANY or OPERATOR.

Responses​

Same changeStatusResult envelope as Query View SNT above.

10. Delete Waybill by ID POST​

Purpose of Use: The POST /snt/delete-by-id endpoint deletes one or more waybills that have not progressed past a deletable status.

Endpoint Information​

PropertyValue
URL/snt/delete-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/delete-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "sntActionInfoList": [ { "sntId": 9887654321 } ] }'

Request Parameters​

Same shape as Change Status (sntActionInfoList); the SNT service only requires sntId per entry for a delete.

Responses​

200 - Successful Response​

{
"resultList": {
"changeStatusResult": [
{ "sntId": 9887654321, "isDeleted": true, "errorCode": null }
]
}
}
FieldTypeDescription
resultList.changeStatusResultArray<Object>One result per requested waybill.
[].sntIdLongSNT numeric ID.
[].isDeletedBooleanfalse when the waybill's current status does not allow deletion.
[].errorCodeString | nullPopulated when deletion was refused.

11. Query SNT Status by ID POST​

Purpose of Use: The POST /snt/query-snt-status-by-id endpoint returns KGD's current status summary (without the XML body) for one or more SNTs by their numeric IDs.

Status credit: Each new status this endpoint reads from KGD is charged as described in Status credit (Introduction); this endpoint and Query Status by Regnum charge one SNT once for the same status. Without credit the call answers HTTP 400 LIFECYCLE_CREDIT_EXHAUSTED and KGD is not asked.

Endpoint Information​

PropertyValue
URL/snt/query-snt-status-by-id
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) + company-bound API key

Example Request​

curl --location 'https://api-stage.docnova.ai/snt/query-snt-status-by-id' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "idList": [9887654321] }'

Request Parameters​

FieldTypeRequiredDescription
idListArray<Long>YesSNT numeric IDs (KGD's SNT id, e.g. kgdSntId from Section 8).

Responses​

200 - Successful Response​

{
"sntSummaryList": {
"sntSummary": [
{ "sntId": 9887654321, "registrationNumber": "KZ20260916000012345", "status": "DELIVERED", "lastUpdateDate": "2026-09-16T08:00:00" }
]
}
}
FieldTypeDescription
sntSummaryList.sntSummaryArray<Object (SntSummary)>One summary per SNT; same SntSummary fields as Query Status by Regnum.

VWH​

Виртуальный склад (ВС) / Virtual Warehouse (VWH) — Kazakhstan's real-time inventory tracking integration with the KGD, covering reference data (Dict), warehouse registration (Store), stock levels (Balance), inventory movements (UForm) and goods-receipt requests (ZVT).

Internal variants only: The endpoints below are the Internal controller variants — Authorization is a company-restricted R-Auth JWT obtained via API-key login, same as ESF/SNT: the company is resolved from the token's restrictedCompanyId, so no explicit companyId is sent in most requests. Base path: /kz/vwh/internal. (The platform also exposes External VWH controllers, with normal JWTs and an explicit companyId parameter, which are out of scope for this guide.)

⚠️ POST/PUT bodies carry Base64-encoded KGD XML: Unlike ESF/SNT/AVR (which carry individually-typed JSON fields), most VWH write endpoints accept a single Base64-encoded KGD XML document as their only body field (storeXml, uFormXml, zvtXml). The XML must not include an <?xml?> declaration or an outer wrapper element — only the inner document body, and its element order must follow the KGD XSD exactly.

Dict (Reference Data)

1. Get Measure Units GET​

Purpose of Use: The GET /kz/vwh/internal/dict/measure-units endpoint returns KGD's measurement unit dictionary, optionally filtered to entries updated after a given date.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/dict/measure-units
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/dict/measure-units?lastUpdateDate=2026-01-01T00%3A00%3A00' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
lastUpdateDateDateTimeNoReturns only entries updated after this date. Omit to retrieve the full dictionary.

Responses​

200 - Successful Response​

[
{
"code": "166",
"codeMkei": "166",
"codeOkei": "166",
"codeTis": "166",
"nameRu": "Килограмм",
"nameKz": "Килограмм",
"lastUpdateDate": "2017-10-01T00:00:00+05:00"
}
]
FieldTypeDescription
codeStringKGD measure unit code — used as measureUnitCode elsewhere in VWH.
codeMkei / codeOkei / codeTisStringEquivalent codes in other Kazakhstan classification systems.
nameRu / nameKzStringUnit name in Russian and Kazakh.
lastUpdateDateDateTimeWhen this entry was last updated in KGD's dictionary.

2. Get GSVS Code Updates GET​

Purpose of Use: The GET /kz/vwh/internal/dict/gsvs endpoint polls KGD's product classification (GSVS) dictionary for changes, paginated by an incrementing changeId.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/dict/gsvs
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/dict/gsvs?lastChangeId=0&blockSize=100' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
lastChangeIdLongNoResume point from a previous call. Default: 0.
blockSizeIntegerNoPage size. Default: 100. KGD accepts at most 200.

Responses​

200 - Successful Response​

[
{
"changeDate": "2026-01-01T00:00:00",
"changeId": "100045",
"operation": "ADD",
"code": "10.61.11.01",
"gsvsCode": "10.61.11.01",
"description": null,
"nameRu": "Мука пшеничная",
"nameKz": "Бидай ұны",
"gsvsTypeCode": "GOODS",
"id": "100045",
"fixedId": "100045",
"fixedParentId": null,
"isDeleted": false,
"isCanSelect": true,
"isTwofoldPurpose": false,
"endDate": null
}
]
FieldTypeDescription
changeIdStringPass as lastChangeId on the next call to resume from here.
operationStringThe dictionary change type, e.g. ADD/UPDATE.
code / gsvsCodeStringThe GSVS classification code — used as gsvsCode on UForm product lines and AVR work lines. Only entries with isCanSelect = true can be used.
nameRu / nameKzStringThe entry's official Russian and Kazakh names. An AVR work line (work/name) must carry one of them letter for letter, or KGD fails the AVR with AWP_WORK_NAME_INCORRECT.
descriptionString | nullAlways null: KGD does not send it. Use nameRu / nameKz.
gsvsTypeCodeStringClassification type.
id / fixedId / fixedParentIdStringInternal and fixed hierarchy identifiers.
isDeleted / isCanSelect / isTwofoldPurposeBooleanEntry flags.
endDateDateTimeWhen the entry stopped being valid, if applicable.

3. Evict Dict Cache POST​

Purpose of Use: The POST /kz/vwh/internal/dict/cache/evict endpoint clears the server-side cache backing the Dict endpoints above, forcing the next call to re-fetch from KGD.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/dict/cache/evict
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location --request POST 'https://api-stage.docnova.ai/kz/vwh/internal/dict/cache/evict' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

None.

Responses​

204 - No Content​

No response body.

Store

4. List Stores GET​

Purpose of Use: The GET /kz/vwh/internal/store endpoint lists all warehouses/points of sale registered for the calling company.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/store
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/store' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

None — the company is taken from the JWT.

Responses​

200 - Successful Response​

[
{
"id": 16011,
"tin": "123456789012",
"storeName": "Almaty Warehouse",
"storeTypeCode": "STORE_HOUSE",
"status": "VALID",
"address": "Almaty, Kabanbay Batyr Ave 15",
"responsiblePersonIin": "123456789012",
"isDefault": false,
"isJointStore": false,
"isPostingGoods": true,
"isInherited": false
}
]
FieldTypeDescription
idLongStore's numeric ID — used as storeId elsewhere in VWH.
tinStringOwning company's TIN/BIN.
storeNameStringStore display name.
storeTypeCodeString (Enum)POINT_OF_SALE or STORE_HOUSE.
statusString (Enum)VALID (active) or INVALID (closed).
addressStringPhysical address.
responsiblePersonIinStringIIN of the person responsible for the store.
isDefaultBooleanWhether this is the company's default store.
isJointStoreBooleanWhether the store is shared/joint.
isPostingGoodsBooleanWhether goods receipts can be posted to this store.
isInheritedBooleanWhether the store was inherited rather than created directly.

5. Create Store POST​

Purpose of Use: The POST /kz/vwh/internal/store endpoint registers a new warehouse/point of sale with KGD from a Base64-encoded KGD Store XML document.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/store
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

⚠️ Field names differ from the REST response: The KGD Store XML uses name and type — not storeName/storeTypeCode as returned by List Stores. No <?xml?> declaration or wrapper element.

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/store' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "storeXml": "<BASE64_ENCODED_STORE_XML>" }'

Request Parameters​

FieldTypeRequiredDescription
storeXmlString (Base64)YesThe KGD Store XML body, Base64-encoded (schema below).

KGD Store XML Schema​

XML ElementRequiredTypeDescription
nameYesStringStore name.
typeYeseStoreTypePOINT_OF_SALE or STORE_HOUSE.
responsiblePersonIinYesStringIIN of the responsible person.
isDefaultYesBooleanWhether this is the default store.
isInheritedYesBooleanWhether the store is inherited.
isJointStoreYesBooleanWhether the store is a joint store.
isPostingGoodsYesBooleanWhether goods receipts can be posted.
addressNoStringStore address.
<name>Almaty Warehouse</name>
<address>Almaty, Kabanbay Batyr Ave 15</address>
<type>STORE_HOUSE</type>
<responsiblePersonIin>123456789012</responsiblePersonIin>
<isInherited>false</isInherited>
<isDefault>false</isDefault>
<isJointStore>false</isJointStore>
<isPostingGoods>true</isPostingGoods>

Responses​

200 OK — a KzVwhStoreResponse, same field shape as List Stores above.

6. Update Store PUT​

Purpose of Use: The PUT /kz/vwh/internal/store/{storeId} endpoint updates an existing store's details via a Base64-encoded KGD Store XML document, using the same schema as Create Store.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/store/{storeId}
MethodPUT
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location --request PUT 'https://api-stage.docnova.ai/kz/vwh/internal/store/16852' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "storeXml": "<BASE64_ENCODED_STORE_XML>" }'

Request Parameters​

FieldTypeRequiredDescription
storeId (path)LongYesThe store to update.
storeXmlString (Base64)YesSame KGD Store XML schema as Create Store.

Responses​

204 - No Content​

No response body.

7. Close Store DELETE​

Purpose of Use: The DELETE /kz/vwh/internal/store/{storeId} endpoint closes a store. KGD does not physically delete it — its status is set to INVALID.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/store/{storeId}
MethodDELETE
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location --request DELETE 'https://api-stage.docnova.ai/kz/vwh/internal/store/16852' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
storeId (path)LongYesThe store to close.

Responses​

204 - No Content​

No response body.

Balance

8. Query Current Balance GET​

Purpose of Use: The GET /kz/vwh/internal/balance endpoint returns the current stock level per product/store, optionally filtered and paginated.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/balance
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/balance?storeId=16011&tnvedCode=1006201500' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
lastBalanceIdLongNoPagination cursor from a previous call.
storeIdLongNoFilter to a specific store.
tnvedCodeStringNoFilter by EAEU TN VED commodity code.

Responses​

200 - Successful Response​

[
{
"balanceId": 152687,
"tin": "123456789012",
"taxpayerStoreId": 16011,
"projectCode": null,
"name": "Wheat flour, 50kg bag",
"kpvedCode": "10.61.11.01",
"tnvedCode": "1006201500",
"gtinCode": null,
"productId": 1029296,
"measureUnitCode": "166",
"unitPrice": 10.00,
"quantity": 9.000000,
"reserveQuantity": 0.000000,
"spiritPercent": null,
"receiptDocNumber": "123456789012/O/290426/38972333",
"productNumberInReceiptDoc": "1",
"manufactureOrImportDocNumber": null,
"productNumberInImportDoc": null,
"productNameInImportDoc": null,
"physicalLabel": null,
"pinCode": null,
"dutyType": "NOT_INSTALLED",
"countryCode": "KZ",
"originCode": "4",
"originType": "MANUFACTURE",
"markingCode": null,
"confiscated": false,
"canExport": true,
"createDate": "2026-04-29T10:49:32+05:00"
}
]
FieldTypeDescription
balanceIdLongPass as lastBalanceId to page through results.
taxpayerStoreIdLongThe store this balance belongs to.
kpvedCode / tnvedCodeStringProduct classification codes.
productIdLongVWH's internal product identifier.
measureUnitCodeStringSee Get Measure Units above.
unitPrice / quantity / reserveQuantityDecimalPrice and on-hand/reserved quantities.
receiptDocNumber / productNumberInReceiptDocStringThe goods-receipt document and line this stock came from.
dutyTypeString (Enum)CCT, WTO, EAEU or NOT_INSTALLED.
countryCode / originCode / originTypeStringCountry of origin details.
canExport / confiscatedBooleanExport eligibility and confiscation flags.
createDateDateTimeWhen this balance record was created.

9. Query Product IDs GET​

Purpose of Use: The GET /kz/vwh/internal/balance/product-ids endpoint resolves VWH's internal productId for one or more goods-receipt document registration numbers.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/balance/product-ids
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/balance/product-ids?registrationNumbers=123456789012%2FO%2F290426%2F38972333' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
registrationNumbersArray<String>NoOne or more goods-receipt document registration numbers (repeat the query parameter for multiple values).

Responses​

200 - Successful Response​

[
{
"balanceId": 152687,
"productId": 1029296,
"receiptDocNumber": "123456789012/O/290426/38972333",
"productNumberInReceiptDoc": "1",
"taxpayerStoreId": 16011,
"kpvedCode": "10.61.11.01",
"tnvedCode": "1006201500",
"measureUnitCode": "166",
"unitPrice": 10.00,
"quantity": 9.000000,
"manufactureOrImportDocNumber": null,
"productNumberInImportDoc": null,
"productNameInImportDoc": null,
"canExport": true,
"confiscated": false,
"markingCode": null,
"dutyType": "NOT_INSTALLED",
"countryCode": "KZ",
"originCode": "4",
"originType": "MANUFACTURE",
"createDate": "2026-04-29T10:49:32+05:00"
}
]

Same field meanings as Query Current Balance above, keyed to the requested registrationNumbers.

10. Query Reserved Products GET​

Purpose of Use: The GET /kz/vwh/internal/balance/reserved endpoint returns stock reservation events (quantity held against an in-progress movement/sale) since a given date.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/balance/reserved
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/balance/reserved?lastEventDate=01.01.2026%2000%3A00%3A00' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
lastEventDateStringYesReservation events after this date. Format: dd.MM.yyyy HH:mm:ss (URL-encoded).
lastBalanceIdLongNoPagination cursor from a previous call.

Responses​

200 - Successful Response​

[
{
"balanceId": 152700,
"tin": "123456789012",
"taxpayerStoreId": 16011,
"productId": 1029296,
"quantity": 2.000000,
"measureUnitCode": "166",
"movementDoc": "MOV-2026-00045",
"productNumberInMovementDoc": "1",
"reserveQuantity": 2.000000,
"createDate": "2026-05-01T09:00:00+05:00"
}
]
FieldTypeDescription
balanceIdLongPass as lastBalanceId to page through results.
movementDoc / productNumberInMovementDocStringThe document/line that created the reservation.
quantity / reserveQuantityDecimalQuantity involved and quantity reserved.
createDateDateTimeWhen the reservation event occurred.

UForm

UForm (Universal Form): The single mechanism for reporting all inventory movements to KGD — initial balance declaration, manufacturing output, inter-store transfer, and write-off — distinguished by uFormType. Submission endpoints each accept a Base64-encoded KGD UForm XML; its type is implied by the endpoint called (not re-declared in the body).

11. Submit Balance UForm POST​

Purpose of Use: The POST /kz/vwh/internal/uform/balance endpoint declares a company's opening stock balance to KGD — typically the first UForm submitted for a new store/product.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/balance
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/balance' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "uFormXml": "<BASE64_ENCODED_UFORM_XML>" }'

Request Parameters​

FieldTypeRequiredDescription
uFormXmlString (Base64)YesThe KGD UForm XML body, Base64-encoded (schema below).

KGD UForm XML Schema (strict element order)​

OrderXML ElementRequiredTypeDescription
1dateYesStringForm date — format dd.MM.yyyy.
2numberYesStringSender's own accounting number for this form.
3recipientNoObjectRecipient info (required for MOVEMENT).
4senderNoObjectSender info.
5totalSumNoDecimalTotal amount.
6typeYeseuFormTypeImplied by the endpoint; must match it.
7commentNoStringFree-text comment.
8productsNoArray<Object>Product lines (schema below).
9writeOffReasonNouFormWriteOffTypeRequired for WRITE_OFF.

sender / recipient element order: name → storeId → storeName → tin (required).

UForm Product Line Schema (strict element order)​

OrderXML ElementRequiredTypeDescription
1gsvsCodeYesStringGSVS classification code.
2measureUnitCodeYesStringSee Get Measure Units.
3priceNoDecimalUnit price.
4quantityYesDecimalQuantity.
5sumNoDecimalLine total.
6canExportNoBooleanExport eligibility.
7dutyTypeCodeNoeCustomsDutyTypeCCT, WTO, EAEU, NOT_INSTALLED.
8originCodeNoStringOrigin code.
9manufactureOrImportCountryNoStringCountry of manufacture/import.
10manufactureOrImportDocNumberNoStringManufacture/import document number.
13nameYesStringProduct name.
18tnvedCodeNoStringEAEU TN VED code.
<?xml version="1.0" encoding="UTF-8"?><v1:uForm xmlns:v1="namespace.v1" xmlns:abs="namespace.abstractUForm"><date>14.05.2026</date><number>BAL-001</number><sender><storeId>16011</storeId><tin>123456789012</tin></sender><totalSum>1500.00</totalSum><type>BALANCE</type><products><product><gsvsCode>10.61.11.01</gsvsCode><measureUnitCode>166</measureUnitCode><price>1500.00</price><quantity>1.000000</quantity><sum>1500.00</sum><canExport>true</canExport><dutyTypeCode>NOT_INSTALLED</dutyTypeCode><originCode>4</originCode><manufactureOrImportCountry>KAZ</manufactureOrImportCountry><name>Test Product</name></product></products></v1:uForm>

⚠️ Not Base64 above: The XML is shown decoded for readability; the actual uFormXml field value must be this document Base64-encoded, with no <?xml?> declaration stripped at the application layer (KGD accepts it either way, but encode exactly what you intend to submit).

Responses​

200 - Successful Response​

{
"id": "6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b",
"uFormNumber": "BAL-001",
"uFormType": "BALANCE",
"status": "CREATED",
"kgdRegistrationNumber": "KZ...",
"senderTin": "123456789012",
"recipientTin": null,
"senderStoreId": 16011,
"recipientStoreId": null,
"errorMessage": null,
"createdTime": "2026-05-12T10:00:00",
"updatedTime": "2026-05-12T10:00:00"
}
FieldTypeDescription
idUUIDThis UForm's identifier in the platform — use it as id on the endpoints below.
uFormNumberStringEchoed from number in the XML.
uFormTypeString (Enum)See the KzVwhUFormType table below.
statusString (Enum)See the KzVwhUFormStatus table below.
kgdRegistrationNumberStringGovernment registration number, once assigned.
senderTin / recipientTinStringParties involved; recipientTin is populated only for MOVEMENT.
senderStoreId / recipientStoreIdLongStores involved.
errorMessageStringPopulated when status is FAILED.
createdTime / updatedTimeDateTimeLifecycle timestamps.

KzVwhUFormType Values​

ValueDescription
BALANCEOpening stock declaration — this endpoint.
MANUFACTUREManufacturing output — Submit Manufacture UForm.
MOVEMENTInter-store transfer — Submit Movement UForm.
WRITE_OFFWrite-off/disposal — Submit Write-Off UForm.
BALANCE_CORRECTIONBalance correction (not exposed by a dedicated submission endpoint below).
DETAILINGDetailing (not exposed by a dedicated submission endpoint below).

KzVwhUFormStatus Values​

ValueDescription
DRAFTDraft, not yet submitted to KGD.
CREATEDAccepted and created.
IN_PROCESSINGBeing processed by KGD.
WAIT_INSTOCKWaiting on stock availability.
WAIT_DOCUMENTWaiting on a related document.
PROCESSEDFully processed.
CANCELEDCanceled.
FAILEDRejected/failed — see errorMessage.

12. Submit Manufacture UForm POST​

Purpose of Use: The POST /kz/vwh/internal/uform/manufacture endpoint reports manufacturing output into stock, using the same UForm XML schema as Submit Balance UForm with type set to MANUFACTURE.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/manufacture
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/manufacture' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "uFormXml": "<BASE64_ENCODED_UFORM_XML_TYPE_MANUFACTURE>" }'

Request Parameters​

Same as Submit Balance UForm (uFormXml), with type set to MANUFACTURE in the decoded XML.

Responses​

200 OK — a KzVwhUFormResponse, same field shape as Submit Balance UForm above.

13. Submit Movement UForm POST​

Purpose of Use: The POST /kz/vwh/internal/uform/movement endpoint reports a transfer of stock between two stores. Unlike the other UForm types, both sender and recipient must be populated in the XML.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/movement
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/movement' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "uFormXml": "<BASE64_ENCODED_UFORM_XML_TYPE_MOVEMENT_WITH_SENDER_AND_RECIPIENT>" }'

Request Parameters​

Same as Submit Balance UForm (uFormXml), with type set to MOVEMENT and both sender and recipient populated in the decoded XML.

Responses​

200 OK — a KzVwhUFormResponse; both senderStoreId/senderTin and recipientStoreId/recipientTin are populated.

14. Submit Write-Off UForm POST​

Purpose of Use: The POST /kz/vwh/internal/uform/writeoff endpoint reports stock removed from inventory (damage, loss, recycling, etc.), requiring writeOffReason in the XML.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/writeoff
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/writeoff' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "uFormXml": "<BASE64_ENCODED_UFORM_XML_TYPE_WRITE_OFF>" }'

Request Parameters​

Same as Submit Balance UForm (uFormXml), with type set to WRITE_OFF and writeOffReason populated in the decoded XML.

KzVwhWriteOffReason Values​

ValueDescription
MANUFACTUREUsed in manufacturing.
DAMAGEDamaged.
RECYCLINGRecycled.
RECLAMATIONReclamation.
LOSSLost.
IS_NOT_VSTOREThis TN VED code is not within VWH's scope.
CONVERSIONWritten off for raw-material conversion.
OTHEROther reason.

Responses​

200 OK — a KzVwhUFormResponse, same field shape as Submit Balance UForm above.

15. List UForms GET​

Purpose of Use: The GET /kz/vwh/internal/uform endpoint lists all UForms submitted by the calling company.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

None — the company is taken from the JWT.

Responses​

200 OK — Array<KzVwhUFormResponse>, same field shape as Submit Balance UForm's response.

16. Search UForms POST​

Purpose of Use: The POST /kz/vwh/internal/uform/search endpoint filters UForms by date range, type, status and store, returning a paginated result.

⚠️ Exception to the Internal pattern: This endpoint requires an explicit companyId in the request body rather than resolving it from the JWT. If the JWT is company-restricted, companyId must match the token's company.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/search
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) — companyId must match the token's restricted company, if any

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/search?page=0&size=20' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{
"companyId": "60ccd1a7-5348-47b2-9ef6-000000000000",
"createdTime": { "from": "2026-05-01T00:00:00", "to": "2026-05-31T23:59:59" },
"types": ["BALANCE", "MOVEMENT"],
"statuses": ["PROCESSED"],
"senderStoreId": 16011,
"recipientStoreId": null
}'

Request Parameters​

FieldTypeRequiredDescription
companyIdUUIDYesThe company to search within.
createdTimeObjectNofrom/to date-time range filter.
typesArray<Enum>NoFilter by one or more KzVwhUFormType values.
statusesArray<Enum>NoFilter by one or more KzVwhUFormStatus values.
senderStoreId / recipientStoreIdLongNoFilter by sender/recipient store.

Standard Spring page/size/sort query parameters are also accepted for pagination.

Responses​

200 - Successful Response​

{
"content": [
{ "id": "6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b", "uFormNumber": "BAL-001", "uFormType": "BALANCE", "status": "PROCESSED", "senderTin": "123456789012", "senderStoreId": 16011, "createdTime": "2026-05-12T10:00:00" }
],
"totalElements": 1,
"totalPages": 1,
"number": 0,
"size": 20
}

A standard Spring Data Page envelope; content items share the KzVwhUFormResponse shape from Submit Balance UForm's response.

17. Get UForm by ID GET​

Purpose of Use: The GET /kz/vwh/internal/uform/{id} endpoint retrieves a single UForm by its platform UUID.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/{id}
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe UForm's platform identifier.

Responses​

200 OK — a KzVwhUFormResponse, same field shape as Submit Balance UForm's response.

18. Get UForm Details GET​

Purpose of Use: The GET /kz/vwh/internal/uform/details/{id} endpoint returns the raw KGD-side detail record for a UForm, including its signature and full body — useful when the summary from Get UForm by ID is not enough.

Status credit: Each new status this endpoint reads from KGD is charged as described in Status credit (Introduction). Without credit the call answers HTTP 400 LIFECYCLE_CREDIT_EXHAUSTED and KGD is not asked.

⚠️ Exception to the Internal pattern: This endpoint also requires an explicit companyId query parameter rather than resolving it from the JWT, like Search UForms above.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/details/{id}
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (JWT token) — companyId must match the token's restricted company, if any

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/details/6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b?companyId=60ccd1a7-5348-47b2-9ef6-000000000000' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe UForm's platform identifier.
companyId (query)UUIDYesThe owning company.

Responses​

200 - Successful Response​

{
"uFormId": 90045,
"uFormBody": "<BASE64_UFORM_XML>",
"status": "PROCESSED",
"registrationNumber": "KZ...",
"inputDate": "2026-05-12T10:00:00",
"lastUpdateDate": "2026-05-12T10:05:00",
"signatureValid": true,
"cancelReason": null,
"version": "UFormV1",
"signature": "<BASE64_SIGNATURE>",
"signatureType": "COMPANY",
"creatorLogin": "api-user-1"
}
FieldTypeDescription
uFormIdLongKGD's own numeric UForm identifier (distinct from the platform's id UUID).
uFormBodyString (Base64)The full UForm XML as held by KGD.
statusString (Enum)See the KzVwhUFormStatus table above.
registrationNumberStringGovernment registration number.
inputDate / lastUpdateDateStringLifecycle timestamps as returned by KGD.
signatureValidBooleanWhether the e-signature validated successfully.
cancelReasonStringPopulated when canceled.
version / signature / signatureTypeStringDocument version, e-signature and signature type.
creatorLoginStringThe KGD user/login that created the record.

19. Cancel UForm POST​

Purpose of Use: The POST /kz/vwh/internal/uform/{id}/cancel endpoint cancels a UForm, with a mandatory reason.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/{id}/cancel
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location --request POST 'https://api-stage.docnova.ai/kz/vwh/internal/uform/6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b/cancel?cancelReason=Entered%20in%20error' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe UForm to cancel.
cancelReason (query)StringYesReason for cancellation.

Responses​

200 OK — a KzVwhUFormResponse with status set to CANCELED.

20. Cancel UForm DELETE​

Purpose of Use: The DELETE /kz/vwh/internal/uform/{id} endpoint is an alternate way to cancel a UForm, with the cancellation reason optional.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/{id}
MethodDELETE
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location --request DELETE 'https://api-stage.docnova.ai/kz/vwh/internal/uform/6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe UForm to cancel.
cancelReason (query)StringNoReason for cancellation. Default: empty.

Responses​

200 OK — a KzVwhUFormResponse with status set to CANCELED.

21. Get UForm Live Status GET​

Purpose of Use: The GET /kz/vwh/internal/uform/{id}/status endpoint queries KGD directly for the UForm's current status, bypassing the platform's locally cached value.

Status credit: Each new status this endpoint reads from KGD is charged as described in Status credit (Introduction). Without credit the call answers HTTP 400 LIFECYCLE_CREDIT_EXHAUSTED and KGD is not asked.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/{id}/status
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b/status' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe UForm to check.

Responses​

200 OK — a KzVwhUFormResponse, same field shape as Submit Balance UForm's response, refreshed from KGD.

22. Get UForm Live Errors GET​

Purpose of Use: The GET /kz/vwh/internal/uform/{id}/errors endpoint queries KGD directly for any validation errors recorded against the UForm.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/{id}/errors
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/6f1b2a3c-4d5e-6f70-8a9b-0c1d2e3f4a5b/errors' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe UForm to check.

Responses​

200 OK — a KzVwhUFormResponse; errorMessage carries KGD's validation error text when present.

23. Get UForm Updates GET​

Purpose of Use: The GET /kz/vwh/internal/uform/updates endpoint is the polling primitive for UForm changes — given the last event date already processed, it returns raw field data for UForms updated since then.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/uform/updates
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/uform/updates?lastEventDate=2026-05-01T00%3A00%3A00' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
lastEventDateDateTimeYesReturns updates after this date (ISO format). Mandatory — KGD's SOAP layer rejects the call without it.

Responses​

200 - Successful Response​

{
"lastEventDate": "2026-05-01T12:00:00",
"lastBlock": true,
"uFormInfoList": [
{ "uFormId": "90045", "status": "PROCESSED", "registrationNumber": "KZ..." }
]
}
FieldTypeDescription
lastEventDateStringPass back as-is on the next call to continue from here.
lastBlockBooleantrue when this page is the last available page.
uFormInfoListArray<Object>Raw key/value field map per updated UForm, passed through directly from KGD rather than mapped to a fixed shape — field names may vary by update type.

ZVT

24. Create ZVT POST​

Purpose of Use: The POST /kz/vwh/internal/zvt endpoint submits a goods-receipt request (ZVT — "Заявка на возврат товара"/goods-receipt notification) to KGD from a Base64-encoded XML document.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/zvt
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/zvt' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}' \
--data '{ "zvtXml": "<BASE64_ENCODED_ZVT_XML>" }'

Request Parameters​

FieldTypeRequiredDescription
zvtXmlString (Base64)YesThe ZVT XML document, Base64-encoded. The decoded content (not the raw string) is what gets forwarded to KGD.

Responses​

200 - Successful Response​

{
"registrationNumber": "KZ...",
"status": "CREATED",
"errorMessage": null,
"errorCode": null,
"body": "<BASE64_ZVT_XML>",
"inputDate": "2026-05-14T09:00:00"
}
FieldTypeDescription
registrationNumberStringGovernment registration number, once assigned — use this as regnum on the endpoints below.
statusStringKGD-reported status.
errorMessage / errorCodeStringPopulated when the submission failed validation.
bodyString (Base64)The submitted XML, echoed back.
inputDateStringWhen the request was received.

25. Query ZVT by Period GET​

Purpose of Use: The GET /kz/vwh/internal/zvt endpoint lists ZVT documents submitted within a date range.

⚠️ KGD limits the period to 1 day: periodFrom/periodTo cannot span more than 24 hours — longer ranges are rejected by KGD.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/zvt
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/zvt?periodFrom=14.05.2026%2000%3A00%3A00&periodTo=14.05.2026%2023%3A59%3A59' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
periodFromStringYesPeriod start. Format: dd.MM.yyyy HH:mm:ss (URL-encoded).
periodToStringYesPeriod end. Same format. Max 1 day after periodFrom.
lastIdLongNoPagination cursor from a previous call.

Responses​

200 OK — Array<KzVwhZvtDocumentResponse>, same field shape as Create ZVT's response.

26. Get ZVT by Registration Number GET​

Purpose of Use: The GET /kz/vwh/internal/zvt/{regnum} endpoint retrieves a single ZVT document by its government registration number.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/zvt/{regnum}
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/zvt/KZ20260514000123' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
regnum (path)StringYesZVT government registration number.

Responses​

200 OK — a KzVwhZvtDocumentResponse, same field shape as Create ZVT's response.

27. Query ZVT by Registration Numbers GET​

Purpose of Use: The GET /kz/vwh/internal/zvt/regnum endpoint retrieves multiple ZVT documents in one call by their registration numbers.

Status credit: Each new status this endpoint reads from KGD is charged as described in Status credit (Introduction). Without credit the call answers HTTP 400 LIFECYCLE_CREDIT_EXHAUSTED and KGD is not asked.

Endpoint Information​

PropertyValue
URL/kz/vwh/internal/zvt/regnum
MethodGET
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
AuthorizationR-Auth header (company-restricted JWT token)

Example Request​

curl --location 'https://api-stage.docnova.ai/kz/vwh/internal/zvt/regnum?regnums=KZ20260514000123&regnums=KZ20260514000124' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'

Request Parameters​

FieldTypeRequiredDescription
regnumsArray<String>YesOne or more ZVT registration numbers (repeat the query parameter for multiple values).

Responses​

200 OK — Array<KzVwhZvtDocumentResponse>, same field shape as Create ZVT's response.

AVR​

Акт выполненных работ (АВР) — the Act of Completed Works/Services, a Kazakhstan e-document exchanged with the KGD (State Revenue Committee) alongside ESF and SNT. It is coded internally as AWP.

Docnova signs and tracks AVRs on your behalf (recommended for ERPs). The ERP sends the AVR data as a JSON object or a Base64-encoded XML document; Docnova checks it, signs it with the company's KGD certificate (uploaded in the Docnova portal), uploads it to KGD, stores the record and follows its status at KGD every minute.

Prerequisite: Before using any AVR endpoint, the company's KGD certificate must be uploaded in the Docnova portal (Settings → KGD Certificate). Docnova uses this certificate to sign documents on the ERP's behalf.


1. Create AVR​

There are two ways to submit an AVR:

  • JSON format (send-document-async-json) — send AVR data as a structured JSON object; Docnova builds the XML internally. Recommended for most ERP integrations.
  • Base64 XML format (send-document-async) — send a fully-formed AwpV1 XML file encoded as Base64. Use when your ERP already builds KGD-compatible XML.

Both endpoints are asynchronous: they return a trackingId immediately and process the document in the background. Use GET /invoice/document-status/{trackingId} to retrieve the result. The documentId in the completed response is Docnova's AVR record ID — use it for Get AVR, history, PDF, and all action endpoints.


1a. Create AVR — JSON Format POST​

Purpose of Use: The POST /invoice/send-document-async-json endpoint accepts AVR data as a plain JSON object, signs it with the company's KGD certificate, uploads it to KGD, and tracks its status. The ERP does not need to build XML.

Endpoint Information​

PropertyValue
URL/invoice/send-document-async-json
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token obtained with the company's API key

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/send-document-async-json' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"compId": "{COMPANY_ID}",
"waybillType": "KZ_AWP",
"senderSignerName": "Генеральный директор",
"awp": {
"companyId": "{COMPANY_ID}",
"number": "AVR-2026-0001",
"avrDate": "06.11.2026",
"performedDate": "05.11.2026",
"senderTin": "123456789012",
"senderName": "TOO Performer",
"senderAddress": "Almaty",
"senderRegistrationType": "ENTERPRISE",
"recipientTin": "987654321098",
"recipientName": "TOO Customer",
"recipientAddress": "Almaty",
"recipientRegistrationType": "ENTERPRISE",
"currencyCode": "KZT",
"totalNdsAmount": 0,
"totalSumWithTax": 100000,
"totalSumWithoutTax": 100000,
"totalTurnoverSize": 100000,
"works": [
{
"name": "Услуги по аренде машин и оборудования для строительства промышленного и гражданского",
"gsvsCode": "77.32.10.01",
"quantity": 1,
"measureUnitCode": "5114",
"unitPriceWithoutTax": 100000,
"sumWithoutTax": 100000,
"sumWithTax": 100000,
"turnoverSize": 100000
}
]
}
}'

Request Parameters​

FieldTypeRequiredDescription
compIdString (UUID)YesDocnova UUID of the sending company
waybillTypeString (Enum)YesFixed value: KZ_AWP
senderSignerNameStringYesPosition of the person signing on the sender side, e.g. Генеральный директор. Required by KGD on every upload.
awpObjectYesAVR content — fields below
awp.companyIdString (UUID)YesSame as compId
awp.numberStringYesAVR number, e.g. AVR-2026-0001
awp.avrDateString (dd.MM.yyyy)YesAVR date — must match the KGD server's current date
awp.performedDateString (dd.MM.yyyy)NoDate the work was actually performed
awp.senderTinStringYesSender company TIN — must match the company's TIN on the token
awp.senderNameStringYesSender company name
awp.senderAddressStringYesSender company address
awp.senderRegistrationTypeString (Enum)YesSender participant type at KGD — must match the company's registered type (usually ENTERPRISE). See Registration Type Values below.
awp.recipientTinStringYesRecipient company TIN
awp.recipientNameStringYesRecipient company name
awp.recipientAddressStringYesRecipient company address
awp.recipientRegistrationTypeString (Enum)ConditionalRequired when recipient is a resident (nonResident = false); must be omitted when non-resident
awp.currencyCodeStringYesCurrency code, e.g. KZT
awp.totalNdsAmountDecimalYesTotal VAT amount; send 0 if the company is not a VAT payer
awp.totalSumWithTaxDecimalYesTotal amount including VAT
awp.totalSumWithoutTaxDecimalYesTotal amount excluding VAT
awp.totalTurnoverSizeDecimalYesTotal taxable turnover (equals totalSumWithoutTax for non-VAT payers)
awp.worksArray<Object>YesWork line items — at least one entry required
awp.works[].nameStringYesOfficial GSVS dictionary name for the service (Russian or Kazakh) — must match the code's dictionary name exactly
awp.works[].gsvsCodeStringYesGSVS service code, e.g. 77.32.10.01
awp.works[].quantityNumberYesQuantity
awp.works[].measureUnitCodeStringYesUnit of measure code
awp.works[].unitPriceWithoutTaxDecimalYesUnit price excluding VAT
awp.works[].sumWithoutTaxDecimalYesLine total excluding VAT
awp.works[].sumWithTaxDecimalYesLine total including VAT
awp.works[].turnoverSizeDecimalYesLine taxable turnover

Responses​

202 - Request Accepted​

{
"trackingId": "f9e16331-85e3-40ae-bb94-eabd4ed12759",
"status": "PENDING",
"message": "Document processing request submitted successfully"
}

Poll GET /invoice/document-status/{trackingId} until status is COMPLETED or FAILED.

{
"trackingId": "f9e16331-85e3-40ae-bb94-eabd4ed12759",
"status": "COMPLETED",
"invoiceNumber": "AVR-2026-0001",
"documentId": "0f86baee-bd04-4682-887e-7e20a576c7ae",
"additionalData": {
"kgdAwpId": "946365",
"awpStatus": "CREATED"
}
}
FieldTypeDescription
trackingIdUUIDUse to poll GET /invoice/document-status/{trackingId}
statusString (Enum)PENDING → COMPLETED or FAILED
documentIdUUIDDocnova's AVR record ID — use for Get AVR, history, PDF and all action endpoints
additionalData.kgdAwpIdStringKGD's numeric AVR ID
additionalData.awpStatusStringKGD status at the time of completion — see AVR Status Values below

1b. Create AVR — Base64 XML Format POST​

Purpose of Use: The POST /invoice/send-document-async endpoint accepts a fully-formed AwpV1 XML document encoded as Base64. Use this variant when your ERP already generates KGD-compatible AVR XML. Docnova signs, uploads and tracks the document; the ERP receives a trackingId and polls for the result the same way as the JSON endpoint.

Endpoint Information​

PropertyValue
URL/invoice/send-document-async
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token

Example Request​

curl --location 'https://api-stage.docnova.ai/invoice/send-document-async' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"compId": "{COMPANY_ID}",
"waybillType": "KZ_AWP",
"base64Document": "{BASE64_ENCODED_AWP_XML}",
"senderSignerName": "Генеральный директор"
}'

Request Parameters​

FieldTypeRequiredDescription
compIdString (UUID)YesDocnova UUID of the sending company
waybillTypeString (Enum)YesFixed value: KZ_AWP
base64DocumentString (Base64)YesAwpV1 AVR XML, UTF-8, Base64-encoded. Single-line and line-wrapped Base64 (CRLF or LF) are both accepted.
senderSignerNameStringYesPosition of the person signing on the sender side. Required by KGD on every upload.

Responses​

Same structure as 1a — trackingId on 202, then poll GET /invoice/document-status/{trackingId}.


Registration Type Values​

Used in senderRegistrationType and recipientRegistrationType.

ValueDescription
ENTERPRISELegal entity (ТОО, АО, etc.)
ENTREPRENEURIndividual entrepreneur (ИП)
INDIVIDUALPrivate individual
LAWYERLawyer
NOTARYNotary
MEDIATORMediator
BAILIFFBailiff
JOINT_ACTIVITY_PARTICIPANTJoint activity participant
SHARING_AGREEMENT_PARTICIPANTProduction sharing agreement participant

The sender's registrationType must match the company's registered participant type at KGD. For most companies this is ENTERPRISE. The recipient's registrationType is required when nonResident = false and must be omitted when nonResident = true.


AVR Status Values​

StatusDescriptionFinal?
DRAFTUpload in progress, or KGD's answer was not received. The AVR may already be registered at KGD — do not resend it; contact Docnova.No
CREATEDKGD received and registered the upload. Transitions to NOT_VIEWED within seconds once KGD processes it.No
NOT_VIEWEDAccepted by KGD; the customer has not opened the document yet.No
DELIVEREDThe customer has viewed the document.No
CONFIRMEDThe customer confirmed the AVR.Yes
DECLINEDThe customer declined the AVR.Yes
REVOKEDThe sender cancelled the AVR before it was confirmed.Yes
IN_TERMINATINGTermination initiated by one party; waiting for the other party to confirm.No
TERMINATEDBoth parties agreed to terminate a previously confirmed AVR.Yes
CANCELEDCancelled by KGD.Yes
IMPORTEDBrought into KGD outside the API (legacy).Yes
FAILEDKGD refused the upload or failed the AVR after acceptance. The errorMessage field contains KGD's errors. The AVR number is free to reuse — correct and resend under the same number.Yes

Status Transition Flow​

                    ┌──────────────────────────────────────┐
▼ │ REVOKE
DRAFT ──► CREATED ──► NOT_VIEWED ──► DELIVERED ──┤
│ CONFIRM ──► CONFIRMED ──► IN_TERMINATING ──► TERMINATED
│
└──► DECLINED
FromActionTo
(upload)Docnova uploads to KGDDRAFT → CREATED → NOT_VIEWED
NOT_VIEWEDCustomer opens the documentDELIVERED
DELIVEREDCustomer confirmsCONFIRMED
DELIVEREDCustomer declinesDECLINED
CREATED / NOT_VIEWED / DELIVEREDSender revokesREVOKED
CONFIRMEDEither party initiates terminationIN_TERMINATING
IN_TERMINATINGThe other party confirms terminationTERMINATED

2. Get AVR GET​

Purpose of Use: The GET /api/awp/{id} endpoint returns Docnova's AVR record with its current status. Docnova reads AVR statuses from KGD every minute, so this call does not call KGD itself. Suggested polling interval: every 5–15 minutes, only for AVRs that are not in a final status.

Endpoint Information​

PropertyValue
URL/api/awp/{id}?companyId={companyId}
MethodGET
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — user token or company API key

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}?companyId={COMPANY_ID}' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Accept: application/json'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe documentId returned by Create AVR (the trackingId completion response)
companyId (query)UUIDYesThe company the AVR belongs to. With a company-scoped token it must match the token's company; otherwise COMPANY_SCOPE_MISMATCH

Responses​

200 - Successful Response​

{
"id": "0f86baee-bd04-4682-887e-7e20a576c7ae",
"internalId": "AWP-2026-00205",
"status": "TERMINATED",
"role": "PERFORMER",
"kgdAwpId": "946365",
"kgdReference": "AVR-2026-006",
"kgdRegistrationNumber": "AKT-160840016422-261105-00441662",
"ourTin": "160840016422",
"counterpartyTin": "940240000498",
"counterpartyName": "Invivo",
"contractNumber": null,
"contractDate": null,
"avrDate": "05.11.2026",
"performedDate": "04.11.2026",
"currencyCode": "KZT",
"totalSumWithTax": 1000,
"totalNdsAmount": 0,
"corrected": false,
"parentAwpId": null,
"errorMessage": null,
"senderRegistrationType": "ENTERPRISE",
"recipientRegistrationType": "ENTERPRISE",
"recipientNonResident": false,
"esfConvertible": false,
"linkedEsf": null,
"createdTime": "2026-11-04T19:27:45",
"updatedTime": "2026-11-05T09:02:21",
"workItems": [
{
"id": "415c80fd-4dec-4c9e-91c3-d8394d2e07c4",
"name": "Услуги по аренде машин и оборудования для строительства промышленного и гражданского",
"gsvsCode": "77.32.10.01",
"quantity": 1,
"unitPrice": 1000,
"ndsRate": null,
"sumWithTax": 1000,
"sumWithoutTax": 1000,
"turnoverSize": 1000,
"ndsAmount": null,
"measureUnitCode": "5114",
"additionalInfo": null
}
]
}
FieldTypeDescription
idUUIDDocnova's AVR record ID. Use this for history, PDF and all action endpoints.
internalIdStringDocnova's human-readable record number, e.g. AWP-2026-00205.
statusString (Enum)Current AVR status — see AVR Status Values.
roleString (Enum)PERFORMER for an AVR the company sent; CUSTOMER for one it received.
kgdAwpIdStringKGD's numeric AVR ID.
kgdReferenceStringThe AVR number as echoed by KGD.
kgdRegistrationNumberStringKGD's official registration number, format AKT-<TIN>-<yyMMdd>-<sequence>. May be null immediately after upload.
ourTinStringThe calling company's TIN.
counterpartyTinStringThe other party's TIN.
counterpartyNameStringThe other party's name.
contractNumber / contractDateStringContract details from the AVR XML, if provided.
avrDateString (dd.MM.yyyy)AVR issue date.
performedDateStringDate the work was performed.
currencyCodeStringCurrency code, e.g. KZT.
totalSumWithTaxDecimalTotal amount including VAT.
totalNdsAmountDecimalTotal VAT amount; 0 for non-VAT payers.
correctedBooleantrue if this is a correction AVR.
parentAwpIdUUIDDocnova ID of the original AVR this corrects; null for primary AVRs.
errorMessageStringKGD error details when status is FAILED.
senderRegistrationTypeString (Enum)Sender's participant type — see Registration Type Values.
recipientRegistrationTypeString (Enum)Recipient's participant type.
recipientNonResidentBooleantrue if the recipient is a non-resident.
esfConvertibleBooleanWhether an ESF can be created from this AVR in the Docnova portal.
linkedEsfObjectESF linked to this AVR, if one was created.
createdTimeDateTimeWhen the Docnova record was created.
updatedTimeDateTimeWhen the record was last updated.
workItemsArray<Object>Work line items — see fields below.
statusSyncPausedBooleanPresent only when status polling is paused due to insufficient credit.
statusSyncPausedReasonStringReason for the pause, when statusSyncPaused is true.

workItems fields:

FieldTypeDescription
idUUIDDocnova's internal ID for this work line.
nameStringOfficial GSVS dictionary name for the service.
gsvsCodeStringGSVS service classification code, e.g. 77.32.10.01.
quantityNumberQuantity (6 decimal places).
unitPriceDecimalUnit price excluding VAT.
ndsRateIntegerVAT rate (%); null for non-VAT payers.
ndsAmountDecimalVAT amount for this line; null for non-VAT payers.
sumWithTaxDecimalLine total including VAT.
sumWithoutTaxDecimalLine total excluding VAT.
turnoverSizeDecimalTaxable turnover for this line.
measureUnitCodeStringUnit of measure code, e.g. 5114 (services).
additionalInfoStringOptional additional information.

404 - Error Response​

HTTPCodeDescription
404AWP_NOT_FOUNDNo AVR with this ID in the company.

3. Get AVR History GET​

Purpose of Use: The GET /api/awp/{id}/history endpoint returns every status change Docnova has recorded for the AVR, ordered from newest to oldest. Use it to audit the full lifecycle of a document — when each transition happened, what triggered it, and what comment was left.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/history?companyId={companyId}
MethodGET
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — user token or company API key

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}/history?companyId={COMPANY_ID}' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Accept: application/json'

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe documentId returned by Create AVR
companyId (query)UUIDYesThe company the AVR belongs to

Responses​

200 - Successful Response​

[
{
"id": "f4e52678-47de-438c-b3db-0493cad08fd8",
"oldStatus": "IN_TERMINATING",
"newStatus": "TERMINATED",
"source": "SCHEDULER",
"comment": null,
"createdTime": "2026-11-05T09:02:21"
},
{
"id": "0d8f111e-07d6-46fc-9aaf-97a0f5a4c7c0",
"oldStatus": "CONFIRMED",
"newStatus": "IN_TERMINATING",
"source": "USER",
"comment": "Termination request",
"createdTime": "2026-11-05T08:40:35"
}
]
FieldTypeDescription
idUUIDDocnova's internal ID for this history entry.
oldStatusString (Enum)AVR status before the change — see AVR Status Values.
newStatusString (Enum)AVR status after the change.
sourceString (Enum)What triggered the transition — see Source Values below.
commentStringThe reason provided with the action. null for SCHEDULER-triggered transitions.
createdTimeDateTimeWhen the status change was recorded.

Source Values:

ValueDescription
SCHEDULERStatus read from KGD by Docnova's periodic polling (every minute). No user action involved.
USERAction taken through the Docnova portal or API (confirm, decline, revoke, initiate/confirm termination).
SAPTriggered by the Create AVR endpoint submission.

404 - Error Response​

HTTPCodeDescription
404AWP_NOT_FOUNDNo AVR with this ID in the company.

4. Download AVR PDF GET​

Purpose of Use: The GET /api/awp/{id}/pdf endpoint returns the AVR as a downloadable PDF file, laid out as the official Kazakh form Р-1 (Annex 50 to MinFin Order No. 562 of 20 December 2012). The PDF is generated entirely from Docnova's stored data — no KGD call is made and no credit is charged.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/pdf?companyId={companyId}
MethodGET
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — user token or company API key

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}/pdf?companyId={COMPANY_ID}' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Accept: application/pdf, application/json' \
--output 'AVR-document.pdf'

Include application/json in Accept so that error responses come back as JSON rather than binary.

Request Parameters​

FieldTypeRequiredDescription
id (path)UUIDYesThe documentId returned by Create AVR
companyId (query)UUIDYesThe company the AVR belongs to. Must match the token's company scope; otherwise COMPANY_SCOPE_MISMATCH.

Responses​

200 - Successful Response​

Content-Type: application/pdf
Content-Disposition: attachment; filename="AVR-2026-0001.pdf"; filename*=UTF-8''AVR-2026-0001.pdf
Cache-Control: no-store

PDF file as binary response body. Use the filename* parameter from Content-Disposition when saving the file — it preserves Cyrillic characters in the AVR number.

What the PDF contains:

  • Parties: customer (Заказчик) and performer (Исполнитель) — name, TIN, address and bank details (when provided)
  • Contract number and date, or "без договора" when no contract was specified
  • Document number and date
  • Work line items table with columns: index, service name, date, unit, quantity, unit price, total; VAT columns (rate, amount, VAT-inclusive total) are added only when at least one line carries VAT
  • Signature lines (Сдал / Принял)
  • IS ESF block: KGD registration number, current status (in Russian), and for each side the signer's position, full name and signing date/time (Kazakhstan time)

For correction AVRs, the PDF prints "Исправленный АВР" with the number, date and registration number of the original.

If the AVR has not yet been registered at KGD (e.g. still in DRAFT), the PDF displays a prominent "Не зарегистрирован в ИС ЭСФ" mark.

4xx - Error Responses​

HTTPCodeDescription
404AWP_NOT_FOUNDNo AVR with this ID in the company.
400AWP_PDF_INCOMING_NOT_SUPPORTEDThe AVR is incoming (role = CUSTOMER); PDF download is currently supported for outgoing AVRs only.
409AWP_PDF_NO_DOCUMENTThe record holds no sent AVR XML.
409AWP_PDF_DOCUMENT_UNREADABLEThe stored XML cannot be read.
400COMPANY_SCOPE_MISMATCHcompanyId does not match the token's company scope.

AVR Action Endpoints​

The following endpoints change the status of an AVR that Docnova manages. They all share the same request body shape:

FieldTypeRequiredDescription
companyIdUUIDYesDocnova UUID of the calling company
commentStringYesReason for the action (required by KGD)
signerNameStringYesPosition of the person authorizing the action, e.g. Director. Returns MISSING_SIGNER_NAME if omitted.

5. Confirm AVR POST​

Purpose of Use: The POST /api/awp/{id}/confirm endpoint is called by the customer (recipient) to confirm acceptance of a delivered AVR. The AVR must be in DELIVERED status.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/confirm
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — company API key of the customer company

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}/confirm' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"companyId": "{CUSTOMER_COMPANY_ID}",
"comment": "Services received and accepted",
"signerName": "Director"
}'

Request Parameters​

See Common Request Body above. {AVR_ID} is the documentId of the AVR as seen by the customer company.

Responses​

200 - Successful Response​

Full AVR object (same shape as Get AVR), with status: "CONFIRMED".

Required statusAllowed caller
DELIVEREDCUSTOMER (recipient)

6. Decline AVR POST​

Purpose of Use: The POST /api/awp/{id}/decline endpoint is called by the customer (recipient) to reject a delivered AVR. DECLINED is a final status — it cannot be reversed.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/decline
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — company API key of the customer company

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}/decline' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"companyId": "{CUSTOMER_COMPANY_ID}",
"comment": "Services not delivered as agreed",
"signerName": "Director"
}'

Request Parameters​

See Common Request Body above.

Responses​

200 - Successful Response​

Full AVR object with status: "DECLINED".

Required statusAllowed caller
DELIVEREDCUSTOMER (recipient)

7. Revoke AVR POST​

Purpose of Use: The POST /api/awp/{id}/revoke endpoint is called by the sender (performer) to withdraw an AVR before the customer has confirmed it. Allowed from CREATED, NOT_VIEWED or DELIVERED status. REVOKED is a final status.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/revoke
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — company API key of the performer company

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}/revoke' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"companyId": "{PERFORMER_COMPANY_ID}",
"comment": "Sent in error — withdrawing the document",
"signerName": "Director"
}'

Request Parameters​

See Common Request Body above.

Responses​

200 - Successful Response​

AVR object with status: "REVOKED".

Required statusAllowed caller
CREATED / NOT_VIEWED / DELIVEREDPERFORMER (sender)

8. Initiate Termination POST​

Purpose of Use: The POST /api/awp/{id}/initiate-termination endpoint starts the two-step mutual termination process for a confirmed AVR. Either party (performer or customer) can initiate. After this call the AVR moves to IN_TERMINATING and waits for the other party to call Confirm Termination.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/initiate-termination
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — company API key of either party

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}/initiate-termination' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"companyId": "{COMPANY_ID}",
"comment": "Mutual agreement to terminate",
"signerName": "Director"
}'

Request Parameters​

See Common Request Body above.

Responses​

200 - Successful Response​

AVR object with status: "IN_TERMINATING".

Required statusAllowed caller
CONFIRMEDPERFORMER or CUSTOMER

9. Confirm Termination POST​

Purpose of Use: The POST /api/awp/{id}/confirm-termination endpoint completes the two-step termination process. It is called by the party that did not initiate the termination. On success the AVR moves to TERMINATED — a final, irreversible status.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/confirm-termination
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — company API key of either party

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{AVR_ID}/confirm-termination' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"companyId": "{COMPANY_ID}",
"comment": "Termination confirmed",
"signerName": "Director"
}'

Request Parameters​

See Common Request Body above.

Responses​

200 - Successful Response​

Full AVR object with status: "TERMINATED".

Required statusAllowed caller
IN_TERMINATINGPERFORMER or CUSTOMER

10. Create Corrected AVR POST​

Purpose of Use: The POST /api/awp/{id}/create-corrected endpoint creates a correction AVR for a confirmed document that contains an error. The original AVR must be in CONFIRMED status. Either party can initiate a correction.

This endpoint is synchronous — unlike send-document-async-json, it does not return a trackingId. It signs, uploads to KGD and returns the new AVR record in a single response.

Endpoint Information​

PropertyValue
URL/api/awp/{id}/create-corrected
MethodPOST
Content-Typeapplication/json
Base URL
Stage Environment URLhttps://api-stage.docnova.ai/
Production Environment URLhttps://api.docnova.ai/
Authorizationr-auth: JWT token — company API key of either party

Example Request​

curl --location 'https://api-stage.docnova.ai/api/awp/{ORIGINAL_AVR_ID}/create-corrected' \
--header 'r-auth: {JWT_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"companyId": "{COMPANY_ID}",
"number": "AVR-2026-001-C1",
"avrDate": "06.11.2026",
"performedDate": "05.11.2026",
"senderTin": "123456789012",
"senderName": "TOO Performer",
"senderAddress": "Almaty",
"senderRegistrationType": "ENTERPRISE",
"recipientTin": "987654321098",
"recipientName": "TOO Customer",
"recipientAddress": "Almaty",
"recipientRegistrationType": "ENTERPRISE",
"currencyCode": "KZT",
"totalNdsAmount": 0,
"totalSumWithTax": 120000,
"totalSumWithoutTax": 120000,
"totalTurnoverSize": 120000,
"senderSignerName": "Генеральный директор",
"works": [
{
"name": "Услуги по аренде машин и оборудования для строительства промышленного и гражданского",
"gsvsCode": "77.32.10.01",
"quantity": 1,
"measureUnitCode": "5114",
"unitPriceWithoutTax": 120000,
"sumWithoutTax": 120000,
"sumWithTax": 120000,
"turnoverSize": 120000
}
]
}'

Request Parameters​

The body uses the same AVR fields as send-document-async-json (see Create AVR — JSON Format). Key differences:

FieldNote
{id} (path)The documentId of the original confirmed AVR
numberA new unique number for the correction document, e.g. AVR-2026-001-C1
companyIdRequired in the body (in addition to the token scope)
senderSignerNameRequired in the body (same as Create AVR)
awpTypeDo not include — Docnova sets it to FIXED automatically
parentAwpIdDo not include — Docnova sets it from the {id} path parameter

Responses​

200 - Successful Response​

{
"id": "b852b2d9-da60-4aeb-a9f0-c8ffb220ee62",
"internalId": "AWP-2026-00220",
"status": "NOT_VIEWED",
"role": "PERFORMER",
"kgdAwpId": "946382",
"kgdReference": "AVR-2026-001-C1",
"kgdRegistrationNumber": "AKT-123456789012-261106-00441822",
"corrected": true,
"parentAwpId": "dcde9582-4842-43ee-af34-d9e9e1b58b29",
"totalSumWithTax": 120000
}
FieldDescription
correctedAlways true for correction AVRs
parentAwpIdDocnova ID of the original AVR that was corrected
statusStarts at NOT_VIEWED — follows the same lifecycle as a new AVR
Required statusAllowed caller
CONFIRMEDPERFORMER or CUSTOMER