/api/v1_2/documentsTo create a new Document send POST request with body containing a JSON hash of the required fields. The file content must be encoded as url safe base64 string (Base64URL in validator https://base64.guru/tools/validator). Online Base64 encoder https://www.base64encode.org/
Only one file per document is allowed, but you can create multiple documents in one request or post files in compressed archive.
In case of multipage file with enabled split max 200 pages are allowed.
For each new created document is returned document id. All created documents are automatically queued for processing.
Big files (big request bodies) can lead to timeouts or unreasonable response times. Rule of thumb is to keep the size of uploaded data under 20MB.
Supported file formats:
Format Description
PDF Containing text or scanned documents
single page PDF document, multipage PDF document, multiple documents in PDF
TIFF, JPEG, PNG image, color/grayscale/b&w
ZIP containing file formats see above
RAR containing file formats see above
7ZIP containing file formats see above
Set content_type parameter according to HTTP header field Content-Type:
File format Content type
PDF application/pdf
JPEG image/jpeg
PNG image/png
TIFF image/tiff
ZIP application/zip
RAR application/x-rar
7ZIP application/x-7z-compressed
Please check example request body to see required structure.
Following attributes are mandatory:
Attribute Required Type, Example Description
filename true String invoice.pdf File name
content_type true String, application/pdf MIME type of document
agenda_id true String, 143 Agenda ID where document belongs to
type true String, PurchaseInvoice Type of document. Allowed values: PurchaseInvoice, SalesInvoice
content true String, JVBERi0xLjQgZGVt..(omitted)) url safe base64 encoded string of file content. File content needs to use url safe variant of base64 encoding/decoding (common pitfall).
file_split false Boolean,true true,false. In case of false automatic splitting is disabled. One file = one document. Number of pages for split is limited to 200.
Optional file duplicates check
If you add additional parameter check_file_duplicates=1 to create document url you will get response message “File duplicate” with additional meta data in case the check is positive. You can use the provided metadata either to let you user know that the file is duplicate or to obtain extracted data from original. Just be aware that there can be multiple processed docs from single upload (archives, multi page scans).
Query parameters
| Name | Example | Description |
|---|---|---|
check_file_duplicates |
1 | [object Object] |
Headers
| Name | Example | Description |
|---|---|---|
Accept-Encoding |
application/json | — |
Content-Type |
application/json | — |
Request body
{
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": false,
"type": "PurchaseInvoice"
}
]
}Code examples
curl --request POST 'https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1' \
--header 'Accept-Encoding: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer demo_access_token' \
--data '{
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": false,
"type": "PurchaseInvoice"
}
]
}'POST /api/v1_2/documents?check_file_duplicates=1 HTTP/1.1
Host: app.datamolino.com
Accept-Encoding: application/json
Content-Type: application/json
Authorization: Bearer demo_access_token
{
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": false,
"type": "PurchaseInvoice"
}
]
}const response = await fetch("https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1", {
method: "POST",
headers: {
"Accept-Encoding": "application/json",
"Content-Type": "application/json",
"Authorization": "Bearer demo_access_token"
},
body: JSON.stringify({
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": false,
"type": "PurchaseInvoice"
}
]
}),
});
const data = await response.json();import axios from "axios";
const response = await axios({
method: "post",
url: "https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1",
headers: {
"Accept-Encoding": "application/json",
"Content-Type": "application/json",
"Authorization": "Bearer demo_access_token"
},
data: {
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": false,
"type": "PurchaseInvoice"
}
]
}
});
console.log(response.data);import requests
url = "https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1"
headers = {
"Accept-Encoding": "application/json",
"Content-Type": "application/json",
"Authorization": "Bearer demo_access_token"
}
payload = {
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": False,
"type": "PurchaseInvoice"
}
]
}
response = requests.request("POST", url, headers=headers, json=payload)
response.raise_for_status()
print(response.json())require 'json'
require 'net/http'
uri = URI("https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1")
request = Net::HTTP::Post.new(uri)
request["Accept-Encoding"] = "application/json"
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer demo_access_token"
request.body = <<~JSON
{
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": false,
"type": "PurchaseInvoice"
}
]
}
JSON
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts JSON.parse(response.body)# app/services/datamolino_client.rb
require 'json'
require 'net/http'
class DatamolinoClient
BASE_URL = "https://app.datamolino.com"
def initialize(access_token: Rails.application.credentials.dig(:datamolino, :access_token))
@access_token = access_token
end
def request_create_document
uri = URI("#{BASE_URL}/api/v1_2/documents?check_file_duplicates=1")
request = Net::HTTP::Post.new(uri)
request["Accept-Encoding"] = "application/json"
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer #{@access_token}"
request.body = <<~JSON
{
"documents": [
{
"files": [
{
"filename": "demo-supplier-invoice.pdf",
"content_type": "application/pdf",
"content": "JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"
}
],
"agenda_id": 12345,
"file_split": false,
"type": "PurchaseInvoice"
}
]
}
JSON
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
JSON.parse(response.body)
end
end<?php
use GuzzleHttp\Client;
$client = new Client();
$response = $client->request('POST', 'https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1', [
'headers' => json_decode('{"Accept-Encoding":"application/json","Content-Type":"application/json","Authorization":"Bearer demo_access_token"}', true),
'json' => json_decode('{"documents":[{"files":[{"filename":"demo-supplier-invoice.pdf","content_type":"application/pdf","content":"JVBERi0xLjQgZGF0YW1vbGluby1kZW1v"}],"agenda_id":12345,"file_split":false,"type":"PurchaseInvoice"}]}', true)
]);
echo $response->getBody();OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create("{\n \"documents\": [\n {\n \"files\": [\n {\n \"filename\": \"demo-supplier-invoice.pdf\",\n \"content_type\": \"application/pdf\",\n \"content\": \"JVBERi0xLjQgZGF0YW1vbGluby1kZW1v\"\n }\n ],\n \"agenda_id\": 12345,\n \"file_split\": false,\n \"type\": \"PurchaseInvoice\"\n }\n ]\n}", MediaType.parse("application/json"));
Request request = new Request.Builder()
.url("https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1")
.addHeader("Accept-Encoding", "application/json")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer demo_access_token")
.method("POST", body)
.build();
Response response = client.newCall(request).execute();using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1");
request.Headers.Add("Accept-Encoding", "application/json");
request.Headers.Add("Authorization", "Bearer demo_access_token");
request.Content = new StringContent("{\n \"documents\": [\n {\n \"files\": [\n {\n \"filename\": \"demo-supplier-invoice.pdf\",\n \"content_type\": \"application/pdf\",\n \"content\": \"JVBERi0xLjQgZGF0YW1vbGluby1kZW1v\"\n }\n ],\n \"agenda_id\": 12345,\n \"file_split\": false,\n \"type\": \"PurchaseInvoice\"\n }\n ]\n}", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());client := &http.Client{}
req, err := http.NewRequest("POST", "https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1", strings.NewReader("{\n \"documents\": [\n {\n \"files\": [\n {\n \"filename\": \"demo-supplier-invoice.pdf\",\n \"content_type\": \"application/pdf\",\n \"content\": \"JVBERi0xLjQgZGF0YW1vbGluby1kZW1v\"\n }\n ],\n \"agenda_id\": 12345,\n \"file_split\": false,\n \"type\": \"PurchaseInvoice\"\n }\n ]\n}"))
if err != nil { panic(err) }
req.Header.Add("Accept-Encoding", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer demo_access_token")
res, err := client.Do(req)
if err != nil { panic(err) }
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil { panic(err) }
fmt.Println(string(body))import Foundation
var request = URLRequest(url: URL(string: "https://app.datamolino.com/api/v1_2/documents?check_file_duplicates=1")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Accept-Encoding")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer demo_access_token", forHTTPHeaderField: "Authorization")
request.httpBody = "{\n \"documents\": [\n {\n \"files\": [\n {\n \"filename\": \"demo-supplier-invoice.pdf\",\n \"content_type\": \"application/pdf\",\n \"content\": \"JVBERi0xLjQgZGF0YW1vbGluby1kZW1v\"\n }\n ],\n \"agenda_id\": 12345,\n \"file_split\": false,\n \"type\": \"PurchaseInvoice\"\n }\n ]\n}".data(using: .utf8)
let (data, _) = try await URLSession.shared.data(for: request)
print(String(data: data, encoding: .utf8)!)Responses
Response Create Document - with duplicate file
Response Create Document - real pdf sample