> For the complete documentation index, see [llms.txt](https://typless.gitbook.io/typlessapi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://typless.gitbook.io/typlessapi/automation-use-cases/invoice-with-metadata.md).

# Invoice with metadata

### Overview

This guide covers how to extract metadata from multiple supplier invoices with examples in **Python** and **Node**. For this example, we will use the **Trainable model**.\
You will extract the following fields:

* Name of the supplier
* Name of the receiver
* Invoice number
* Purchase order number
* Issue date
* Pay due date
* Total amount

**This guide shows you how to**

1. [Create invoice-metadata document type](#id-1.-create-a-new-document-type)
2. [Add multiple suppliers](#id-2.-add-suppliers)
3. [Execute training](#id-3.-execute-training)
4. [Extract data from documents](#id-4.-extract-data-from-documents)
5. [Continuously improve models after extraction](#id-5.-continuously-improve-models)

## Get your API Key

The *Authorization* header for your API key is: `Token YOUR-API-KEY` ([Login](https://app.typless.com/login/?redirect=https://docs.typless.com/) if you do not see one).\
You can also obtain the **API key** by visiting the [Settings page](https://app.typless.com/settings/profile).

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FePXqOCeLb4FOuZhmYG8X%2Fuploads%2FXwpyvlMgoIW7PXZKkPwE%2FREC-20260515112641.mp4?alt=media&token=810fbc33-d3d7-4687-b49c-62abae6c7029>" %}
Getting your API key
{% endembed %}

## 1. Create a new document type

Before you start extracting data, you need to define a document type. Navigate to the [Dashboard page](https://app.typless.com) and click on the **New document type** button in the top right corner of the table. Next, select the **Trainable model**, followed by **Use a Predefined Template**. Then, click on **Metadata invoice** card. The wizard will already pre-fill all the needed [extraction fields](/typlessapi/typless/extraction-fields.md) along with the [document type configuration](/typlessapi/typless/document-type.md).\
Click on the **Create document type**.\
This will create a new **document type** with name **metadata-invoice** with the following fields:

* **`supplier_name`**
* **`invoice_number`**
* **`purchase_order_number`**
* **`receiver_name`**
* **`issue_date`**
* **`pay_due_date`**
* **`total_amount`**

## 2. Add suppliers

Typless is a tool for automation. That's why you need to fill the **dataset** and **train it first**. To automate a new supplier, you need to first add its invoices to the data set. Download invoices - one from Awesome Company and another from Good Services.

* [Amazing Company - download](https://typless-public.s3-eu-west-1.amazonaws.com/use_cases/metadata-invoice/amazing_company_1.pdf)
* [Good Services - download](https://typless-public.s3-eu-west-1.amazonaws.com/use_cases/metadata-invoice/good_services_1.pdf)

{% hint style="success" %}
To add a document to the dataset, use the [**add-document**](/typlessapi/api-docs/api-schema.md#api-add-document) endpoint or use the [**training room**](/typlessapi/typless-hub/document-type.md#training-room)**,** where you can easily upload a file and fill out the necessary information.
{% endhint %}

The dataset is created by uploading an original file with the correct value for each field defined inside the document type:

<details>

<summary><strong>1 Open file as base64 string</strong> <em><mark style="color:green;">(Lines 6-7)</mark></em></summary>

Make sure you are pointing to the correct path in your file system.

</details>

<details>

<summary><strong>2 Specify payload</strong> <em><mark style="color:green;">(Lines 9-43)</mark></em></summary>

</details>

<details>

<summary><strong>3 Specify headers</strong> <em><mark style="color:green;">(Lines 48-52)</mark></em></summary>

</details>

<details>

<summary><strong>4 Send POST request</strong> <em><mark style="color:green;">(Lines 54-56)</mark></em></summary>

</details>

{% tabs %}
{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
import requests
import base64

file_name = 'amazing_company_1.pdf'

with open(file_name, 'rb') as file:
    base64_data = base64.b64encode(file.read()).decode('utf-8')

payload = {
    "file": base64_data,
    "file_name": file_name,
    "document_type_name": "metadata-invoice",
    "learning_fields": [
        {
            "name": "supplier_name",
            "value": "Amazing Company"
        },
        {
            "name": "receiver_name",
            "value": "Amazing Client"
        },
        {
            "name": "invoice_number",
            "value": "333"
        },
        {
            "name": "purchase_order_number",
            "value": "234778"
        },
        {
            "name": "pay_due_date",
            "value": "2021-03-31"
        },
        {
            "name": "issue_date",
            "value": "2021-02-01"
        },
        {
            "name": "total_amount",
            "value": "15.0000"
        }
    ]
}


url = "https://developers.typless.com/api/add-document"

headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "Authorization": "<<apiKey>>"
}

response = requests.request("POST", url, json=payload, headers=headers)

print(response.json())
```

{% endcode %}
{% endtab %}

{% tab title="Node" %}
{% code lineNumbers="true" %}

```javascript
const fetch = require('node-fetch');
const fs = require('fs');

const fileName = 'amazing_company_1.pdf';
const base64File = fs.readFileSync(fileName, {encoding: 'base64'});

let url = 'https://developers.typless.com/api/add-document';

const payload = {
  file: base64File,
  file_name: fileName,
  document_type_name: "metadata-invoice",
  learning_fields: [
      {
          name: "supplier_name",
          value: "Amazing Company"
      },
      {
          name: "receiver_name",
          value: "Amazing Client"
      },
      {
          name: "invoice_number",
          value: "333"
      },
      {
          name: "purchase_order_number",
          value: "234778"
      },
      {
          name: "pay_due_date",
          value: "2021-03-31"
      },
      {
          name: "issue_date",
          value: "2021-02-01"
      },
      {
          name: "total_amount",
          value: "15.0000"
      }
  ]
};

const headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'Authorization': '<<apikey>>'
}

let options = {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(payload)
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));
```

{% endcode %}
{% endtab %}
{% endtabs %}

Response:

{% tabs %}
{% tab title="JSON" %}
{% code lineNumbers="true" %}

```json
 {
    "details":["0cb9c9227a1f67dcd54ce4019aed6867a8b32a5b"],
    "message":"Document added successfully."
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

As you can see, to achieve high accuracy, Typless only needs **the values that are in the document**. Nevertheless, there are some [**rules**](/typlessapi/typless/extraction-fields.md) to keep in mind when providing values.\
Applying these to the **Amazing Company** example, we changed three fields:

* **`total_amount`**  value was converted with [**number type rules**](/typlessapi/typless/extraction-fields.md#number-type) from **15,00** to **15.0000**
* **`issue_date`** value was converted with [**date type rules**](/typlessapi/typless/extraction-fields.md#date-type) from the word **Feb 1, 2021,** to **2021-02-01**
* **`pay_due_date`** value was converted with [**date type rules**](/typlessapi/typless/extraction-fields.md#date-type) from the word **Mar 31, 2021,** to **2021-03-31**

The same rules were also applied to the **Good Services** example.

You will have two suppliers added to your document type after you run both code examples.

## 3. Execute training

{% hint style="success" %}
**👍&#x20;**<mark style="color:green;">**Training is executed automatically every day at 10 PM CET**</mark>

For **all of your suppliers** with new documents in the [dataset](/typlessapi/typless/training/building-a-dataset.md) of all your document types.\
**Free of charge**
{% endhint %}

To immediately see results, you can trigger the training process on the [Dashboard page](https://app.typless.com). Look for the **metadata-invoice** document type in the list, and click on ![cogs icon](https://typless-public.s3-eu-west-1.amazonaws.com/cogs.png).\
The training for the example should finish in a matter of seconds.

{% hint style="info" %}
Need more information? Read more about [**training**](/typlessapi/typless/training.md).
{% endhint %}

## 4. Extract data from documents

After the training is finished, you can start precisely extracting data from documents from trained suppliers. Here you have two new invoices from the trained suppliers:

* [Amazing Company - download](https://typless-public.s3-eu-west-1.amazonaws.com/use_cases/metadata-invoice/amazing_company_2.pdf)
* [Good Services - download](https://typless-public.s3-eu-west-1.amazonaws.com/use_cases/metadata-invoice/good_services_2.pdf)

Download them and extract the data using the code:

<details>

<summary><strong>1 Open file as base64 string</strong> <em><mark style="color:green;">(Lines 5-7)</mark></em></summary>

Make sure you are pointing to the correct path in your file system.

</details>

<details>

<summary>2 Specify payload <em><mark style="color:green;">(Lines 9-12)</mark></em></summary>

</details>

<details>

<summary>3 Specify headers <em><mark style="color:green;">(Lines 17-20)</mark></em></summary>

</details>

<details>

<summary>4 Send POST request <em><mark style="color:green;">(Line 23)</mark></em></summary>

</details>

{% tabs %}
{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
import requests
import requests
import base64

file_name = 'amazing_company_2.pdf'
with open(file_name, 'rb') as file:
    base64_data = base64.b64encode(file.read()).decode('utf-8')

payload = {
    "file": base64_data,
    "file_name": file_name,
    "document_type_name": "metadata-invoice"
}

url = "https://developers.typless.com/api/extract-data"

headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "Authorization": "<<apikey>>"
}

response = requests.request("POST", url, json=payload, headers=headers)

for field in response.json()['extracted_fields']:
    print(f'{field["name"]}: {field["values"][0]["value"]}')
```

{% endcode %}
{% endtab %}

{% tab title="Node" %}
{% code lineNumbers="true" %}

```javascript
const fetch = require('node-fetch');
const fs = require('fs');

const fileName = 'amazing_company_2.pdf';
const base64File = fs.readFileSync(fileName, {encoding: 'base64'});

const url = 'https://developers.typless.com/api/extract-data';

const payload = {
  file: base64File,
  file_name: fileName,
  document_type_name: "metadata-invoice"
}

const headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'Authorization': '<<apikey>>'
}

let options = {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(payload)
};

fetch(url, options)
  .then(res => res.json())
  .then(json => {
    json.extracted_fields.forEach(field => console.log(`${field.name}: ${field.values[0].value}`))
  })
  .catch(err => console.error('error:' + err));
```

{% endcode %}
{% endtab %}
{% endtabs %}

Response:

{% tabs %}
{% tab title="JSON" %}
{% code lineNumbers="true" %}

```json
// Example extraction response - the provided recipe will not produce equal results
{
    "file_name": "invoice_2.pdf",
    "object_id": "1cb25cc8-c9fa-4149-9a83-b4ed6a2173b9",
    "extracted_fields": [
        {
            "name": "supplier_name",
            "values": [
                {
                    "x": -1,
                    "y": -1,
                    "width": -1,
                    "height": -1,
                    "value": "ScaleGrid",
                    "confidence_score": "0.968",
                    "page_number": -1
                }
            ],
            "data_type": "AUTHOR"
        },
        {
            "name": "invoice_number",
            "values": [
                {
                    "x": 1989,
                    "y": 545,
                    "width": 323,
                    "height": 54,
                    "value": "20190500005890",
                    "confidence_score": "0.250",
                    "page_number": 0
                },
                {
                    "x": 167,
                    "y": 574,
                    "width": 391,
                    "height": 54,
                    "value": "GB123456789",
                    "confidence_score": "0.250",
                    "page_number": 0
                }
            ],
            "data_type": "STRING"
        },
        {
            "name": "issue_date",
            "values": [
                {
                    "x": 2072,
                    "y": 628,
                    "width": 240,
                    "height": 54,
                    "value": "2019-06-05",
                    "confidence_score": "0.358",
                    "page_number": 0
                }
            ],
            "data_type": "DATE"
        },
      	{
            "name": "pay_due_date",
            "values": [
                {
                    "x": 2072,
                    "y": 628,
                    "width": 240,
                    "height": 54,
                    "value": "2019-06-05",
                    "confidence_score": "0.358",
                    "page_number": 0
                }
            ],
            "data_type": "DATE"
        },
        {
            "name": "total_amount",
            "values": [
                {
                    "x": 2146,
                    "y": 1196,
                    "width": 126,
                    "height": 54,
                    "value": "47.5300",
                    "confidence_score": "0.990",
                    "page_number": 0
                }
            ],
            "data_type": "NUMBER"
        }
    ],
    "line_items": []
}
    "customer": null
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Need a more in-depth explanation of the response?**\
You can read about it [here](/typlessapi/typless/data-extraction.md#understanding-response).
{% endhint %}

## 5. Continuously improve models

Typless embraces the fact that the world is changing all the time.\
That's why you can improve models **on the fly** by providing correct data after extraction.\
Let's say your company has a new partner, *Best Supplier*. You don't need to start over with building the dataset. You can simply extract and send the correct data after they **are verified by your users**.\
You can learn more about providing feedback on the [building dataset](/typlessapi/typless/training/building-a-dataset.md) page.

{% hint style="info" %}
**📘&#x20;**<mark style="color:blue;">**Closed workflow loop - improve models live!**</mark>

Use every action from your users to adapt and improve Typless models without any extra costs.
{% endhint %}

{% hint style="info" %}
To send feedback, use the [**add-document-feedback**](/typlessapi/api-docs/api-schema.md#api-add-document-feedback) with the [**object\_id**](/typlessapi/typless/data-extraction.md#response-base-params)**.**
{% endhint %}

## Running Typless live

The only thing that you need to do to automate your manual data entry is to integrate those simple API calls into your system.

{% hint style="success" %}
Have any questions, or do you need some help? Contact us via email <mark style="color:green;">**<support@typless.com>**</mark>**.**
{% endhint %}

![Typless usage is very easy and straightforward!](https://files.readme.io/ad56c3d-typless_1.PNG)
