Skip to content

Asynchronous processing of Smartscan

Logo

The asynchronous processing of Smartscan allows you to submit a document for processing and receive the results at a later time. This feature is particularly useful for large documents that require more time to process.

Getting started

Asynchronous processing workflow

The asynchronous processing of Smartscan is built around Transactions. A Transaction is a request to process a document with a list of features - the data points you want to extract from the document. The transaction can be tagged with a custom ID for easier tracking and deletion. The workflow consists of the following steps:

  1. Create Transaction: Submit a document for processing with a list of features and optional tags and custom ID.
  2. Get Transaction Status: Check the status of the transaction to see if it is completed or failed.
  3. Get Transaction Results: Retrieve the extracted data from the document.
  4. Delete Transaction: Delete the transaction and its data if needed.

Access to the API

  1. Demo Access Token

    For development purposes, you can use the demo access token demo, like in the example below, for access to staging. Use the staging endpoints indicated in the endpoints section. Please note that this token is rate-limited and should only be used for testing. We strongly advise you to not use demo token for any sensitive data as anyone with the token can access the data. The demo token only covers creating a transaction (POST /v1/transactions) and reading its status and results (GET /v1/transactions/...); updating results, deleting transactions and deleting tags require a project token — see Authentication.

  2. Staging Access Token (Recommended)

    For more extensive testing and integration purposes, we recommend generating a staging access token through our Staging portal. Follow the steps in the Quick Start Guide for generating a staging or production access tokens. Refer to the Authentication for more information on the server-to-server token method.

Example requests

Create Transaction Request


POST v1/transactions

https://api.stag.ssn.visma.ai/v1/transactions

Authorization - Bearer Token

Token: demo


Body - raw (json)

Body
{
    "document": {
        "source": {
            "httpUri": "http://storage.googleapis.com/vml-test-data/distributable/pdf5/10.pdf"
        }
    },
    "features": [ "RECEIVER_COUNTRY_CODE", "IBAN" ],
    "tags": ["testing"],
    "customId": "my-first-transaction"
}


Information

customId is optional, but it must be unique within your project. Creating another transaction with a customId that is already in use is rejected with 409 Conflict (ALREADY_EXISTS). Delete the existing transaction first if you need to reuse the identifier.

Create Transaction Response


Body - raw (json)

Body
{
    "id": "<transaction-id>",
    "customId": "my-first-transaction"
}


Get Transaction Status Request

You can get transaction status either by the transaction ID or the custom ID. The transaction ID is unique for each transaction, while the custom ID is optional and can be set by the user.


GET v1/transactions/{transaction_id}/status

https://api.stag.ssn.visma.ai/v1/transactions/<transaction-id>/status

Authorization - Bearer Token

Token: demo


Calling the Get Transaction Status endpoint with the custom ID:


GET v1/transactions/status?custom_id={custom_id}

https://api.stag.ssn.visma.ai/v1/transactions/status?custom_id=my-first-transaction

Authorization - Bearer Token

Token: demo


Get Transaction Status Response

The status of the transaction can be CREATED, RUNNING, DONE, PARTIAL, or FAILED.

PARTIAL is a terminal state, returned when some of the requested features completed and others failed. The results of the features that completed are returned as usual, together with an errorMessage describing the failure.


Body - raw (json)

Body
{
    "id": "<transaction-id>",
    "status": "DONE",
    "customId": "my-first-transaction"
}


Get Transaction Results Request

You can get transaction results either by the transaction ID or the custom ID. The transaction ID is unique for each transaction, while the custom ID is optional and can be set by the user.


GET v1/transactions/{transaction_id}/results

https://api.stag.ssn.visma.ai/v1/transactions/<transaction-id>/results

Authorization - Bearer Token

Token: demo


Calling the Get Transaction Results endpoint with the custom ID:


GET v1/transactions/results?custom_id={custom_id}

https://api.stag.ssn.visma.ai/v1/transactions/results?custom_id=my-first-transaction

Authorization - Bearer Token

Token: demo


Filtering the results

Both forms of the endpoint accept two optional query parameters:

Parameter Type Default Description
min_confidence string HIGH Only return candidates whose confidence level is at least this value.
max_results integer 1 Maximum number of candidates to return per feature.

Information

Both parameters default to a narrow result set. Unless you set them, each feature returns at most one candidate, and only if its confidence level is HIGH or better. If a feature returns nothing, lowering min_confidence (for example to VERY_LOW) and raising max_results will surface the remaining candidates.


GET v1/transactions/{transaction_id}/results?min_confidence={level}&max_results={n}

https://api.stag.ssn.visma.ai/v1/transactions/<transaction-id>/results?min_confidence=VERY_LOW&max_results=5

Authorization - Bearer Token

Token: demo


Get Transaction Results Response

The Get Transaction Results response includes:

  • Transaction ID: A unique identifier for the transaction.
  • Custom ID: The custom ID if provided in the request.
  • Annotations: The extracted data, with one entry per requested feature. Absent while the transaction is still processing.
  • Error message: The errorMessage field, present when the transaction is FAILED or PARTIAL, describing what went wrong.

Information

This endpoint returns 200 OK for any existing transaction - the state of the transaction is not signalled through the HTTP status code:

  • While the transaction is CREATED or RUNNING, the response contains only id and customId, with no annotations. Keep polling until the annotations appear, or poll the status endpoint instead.
  • When the transaction is FAILED, the response contains errorMessage and no annotations.
  • When the transaction is PARTIAL, the response contains the annotations of the features that completed and an errorMessage.

Body - raw (json)

Body
{
    "id": "<transaction-id>",
    "annotations": [
        {
            "feature": "RECEIVER_COUNTRY_CODE",
            "candidates": [
                {
                    "value": "DK",
                    "confidence": {
                        "level": "VERY_HIGH"
                    },
                    "modelMetadata": {
                        "modelName": "layoutlm-r3",
                        "modelVer": "1"
                    }
                }
            ]
        }
    ],
    "customId": "my-first-transaction"
}


Update Transaction Results (Feedback)

You can provide feedback on the results of a transaction by updating the transaction with the correct values. This is useful for improving the models. You can update the transaction results by the transaction ID.

Information

Feedback can only be submitted once processing has finished, that is when the transaction status is DONE or PARTIAL. Submitting feedback while the transaction is still CREATED or RUNNING, or after it has FAILED, is rejected with a FAILED_PRECONDITION error.


PUT v1/transactions/{transaction_id}/results

https://api.stag.ssn.visma.ai/v1/transactions/<transaction-id>/results

Authorization - Bearer Token

Token: [API token]


Body - raw (json)

Body
{
  "customId": "YOUR_CUSTOM_ID_12345",
  "annotations": [
    {
      "feature": "TOTAL_INCL_VAT",
      "candidates": [
        {
          "value": "125.50",
          "text": "125,50",
          "confidence": {
            "level": "VERY_HIGH",
            "value": 0.99
          },
          "boundingBox": {
            "vertices": [
              { "x": 100, "y": 50 },
              { "x": 200, "y": 50 },
              { "x": 200, "y": 75 },
              { "x": 100, "y": 75 }
            ]
          },
          "type": "FIELD",
          "pageRef": 1
        }
      ]
    },
    {
      "feature": "PURCHASE_LINES",
      "purchaseLineCandidates": [
        {
          "pageRef": 1,
          "description": "Product A",
          "quantity": "2",
          "totalInclVat": "50.00",
          "totalExclVat": "40.00",
          "totalVat": "10.00",
          "percentageVat": "25"
        },
        {
          "pageRef": 1,
          "description": "Product B",
          "quantity": "1",
          "totalInclVat": "75.50",
          "totalExclVat": "60.40",
          "totalVat": "15.10",
          "percentageVat": "25"
        }
      ]
    }
  ]
}


Update Transaction Results Response


Body - raw (json)

Body
{
    "id": "<transaction-id>",
    "customId": "my-first-transaction"
}


Model tiers

The optional tier field on the Create Transaction request selects which model processes the document:

  • PREMIUM - our proprietary AI. This is the tier used when tier is not set.
  • ULTRA - combines our proprietary AI with reasoning LLMs for the highest available quality. ULTRA is only available through the asynchronous API.
{
    "document": {
        "source": {
            "httpUri": "http://storage.googleapis.com/vml-test-data/distributable/pdf5/10.pdf"
        }
    },
    "features": [ "TOTAL_INCL_VAT" ],
    "tier": "PREMIUM"
}

Features marked Premium in the feature list require a Premium or higher tier. See Model Versions for a fuller comparison of the tiers.

Document Data Sources

You can provide the document in one of two ways:

  1. By URI: Provide a URL to the file (as shown in the Create Transaction request)
  2. By Content: Send the file directly in the request body using the content field

Proper Base64 Encoding for content Field

The content field requires the raw binary bytes of the file, Base64 encoded.

  • Read the file in binary mode (e.g., rb in Python, FileInputStream in Java)
  • Base64 encode those raw bytes directly
  • Send the Base64-encoded binary data in the content field

Example request


POST v1/transactions

https://api.stag.ssn.visma.ai/v1/transactions

Authorization - Bearer Token

Token: demo


Body - raw (json)

Body
{
    "document": {
        "content": "Vl00oANHjF3gxaYT4fQ0PSDJwwZIuMLl0GdNlgyKhF4KYOtcH3r... -- this is unfinished base64 enconding --"
    },
   "features": [ "RECEIVER_COUNTRY_CODE", "IBAN" ],
    "tags": ["testing"],
    "customId": "my-first-transaction"
}


Smartscan Response

Individual candidates carry the same meaning as in the synchronous Smartscan: values, confidence levels, bounding boxes and page references all behave identically.

The response envelope differs. Asynchronous results are returned as an annotations array, with one entry per requested feature identified by its feature name, rather than one named field per feature. The asynchronous response does not include feedbackId or documentMetadata.

Data Deletion Policy

You can either delete the data by deleting the transaction either by transaction_id or custom_id, or you can delete multiple transactions via tag, if provided in the Create Transaction request.

Deletion is processed asynchronously: the 200 OK confirms that the deletion request has been accepted, and the data is removed shortly afterwards.

Delete Transaction Request


DELETE v1/transactions/{transaction_id}

https://api.stag.ssn.visma.ai/v1/transactions/<transaction-id>

Authorization

Bearer Token

Token: [API token]


Response

200 OK

Calling the Delete Transaction endpoint with the custom ID:


DELETE v1/transactions?custom_id={custom_id}

https://api.stag.ssn.visma.ai/v1/transactions?custom_id=my-first-transaction

Authorization

Bearer Token

Token: [API token]


Response

200 OK

Delete Tag Request

Delete transaction by tag will delete all transactions with the provided tag.


DELETE v1/tags/{tag}

https://api.stag.ssn.visma.ai/v1/tags/testing

Authorization

Bearer Token

Token: [API token]


Response

200 OK