Documents upload
The call must be authenticated following the pattern described in section 1.1.3. Authentication Test. Authentication Test. With the following caveats:
- The value of the md5_hash variable (md5_body for v1 of our authentication) sent in the header signature must be the MD5 of the binary file being sent.
- The binary file must be sent in the request body as FormData using the string "file" as the key and the file to be sent as the value. (This content is not encrypted)
- The response body of this call will return a GUID, which is the document identifier (referred to as DOCUMENT_KEY from now on) and must be stored for future use.
Request
ENDPOINT
/uploadMETHOD
POSTResponse Body
{
"document_key": "cfbc8469-89ea-4a80-9f64-ba7b1566c68b",
"document_md5": "cd451103fa512frc98ce684d3896698c"
}
Attention
It is crucial to save the document_key, obtained from the response. This key is necessary for retrieving or referencing the document in future interactions.
Call Example
Example Call for Uploading an Image from a URL
- Python
- Node.js
import jwt
import hashlib
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
import json
from datetime import datetime
BASE_URL = "https://api-auth.sandbox.qitech.app"
API_KEY = "4c268c0a-53ff-429b-92b6-47ef98a6d89a" # This key is an example, please use your own
CLIENT_PRIVATE_KEY = ''''
-----BEGIN EC PRIVATE KEY-----
MIHbAgEBBEHh1hIeOPE5XNNhn6bxRAmVswsPZ0wZCmzVvP8Tl/LZK9ofVmRVGzll
srU1uezJEyHKYdOHrE2p52xUj+pHzjJvb6AHBgUrgQQAI6GBiQOBhgAEAAofUz1J
hBSOyGHLsnV9Sz0DSWmhl7U+ljqbfa8PKVFWSV3w16I1v2zME5/UzUhHn1gWsjnv
7/ekcLLAQbvqMPNXAfjIhFXLAPzqbB9iCuVua1v0Vgy52rBemOWrJka/Ws2bnKR8
h1N1OxOYeYr6C2jqMygBLktKMAs+282CEiEb4bIv
-----END EC PRIVATE KEY-----
''' # This key is an example, please use your own
def get_document(url):
try:
response = requests.get(url)
return response.content
except Exception as error:
print("Error fetching document:", error)
raise
def upload_document(array_buffer):
endpoint = "/upload"
method = "POST"
timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
md5_hash = hashlib.md5(array_buffer).hexdigest()
jwt_header = {
"typ": "JWT",
"alg": "ES512",
}
jwt_body = {
"payload_md5": md5_hash,
"timestamp": timestamp,
"method": method,
"uri": endpoint,
}
encoded_header_token = jwt.encode(jwt_body, CLIENT_PRIVATE_KEY, algorithm="ES512", headers=jwt_header)
signed_header = {
"Authorization": encoded_header_token,
"API-CLIENT-KEY": API_KEY,
"Content-Type": "multipart/form-data",
}
url = f"{BASE_URL}{endpoint}"
multipart_data = MultipartEncoder(
fields={'file': ('image.jpeg', array_buffer, 'image/jpeg')}
)
signed_header['Content-Type'] = multipart_data.content_type
try:
response = requests.post(url, headers=signed_header, data=multipart_data)
response_data = response.json()
document_key = response_data.get('document_key')
print(f'Response data is: {response_data} and document_key is: {document_key}')
return document_key
except Exception as error:
print('Error:', error)
raise
def main():
file_url = "{FILE_URL}"
document_buffer = get_document(file_url)
document_key = upload_document(document_buffer)
print("Document key is", document_key)
if __name__ == "__main__":
main()
const jwt = require('jsonwebtoken')
const crypto = require('crypto')
const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')
const fetch = require('node-fetch')
async function getDocument(url) {
try {
const response = await axios.get(url, { responseType: 'arraybuffer' })
return response.data
} catch (error) {
console.error('Error fetching document:', error)
throw error
}
}
async function uploadDocument(arrayBuffer) {
const base_url = "[https://api-auth.sandbox.qitech.app](https://api-auth.sandbox.qitech.app)"
const endpoint = '/upload'
const method = 'POST'
const timestamp = new Date().toISOString()
const md5_hash = crypto.createHash('md5').update(arrayBuffer).digest('hex')
const client_private_key = `-----BEGIN EC PRIVATE KEY-----
MIHbAgEBBEHh1hIeOPE5XNNhn6bxRAmVswsPZ0wZCmzVvP8Tl/LZK9ofVmRVGzll
srU1uezJEyHKYdOHrE2p52xUj+pHzjJvb6AHBgUrgQQAI6GBiQOBhgAEAAofUz1J
hBSOyGHLsnV9Sz0DSWmhl7U+ljqbfa8PKVFWSV3w16I1v2zME5/UzUhHn1gWsjnv
7/ekcLLAQbvqMPNXAfjIhFXLAPzqbB9iCuVua1v0Vgy52rBemOWrJka/Ws2bnKR8
h1N1OxOYeYr6C2jqMygBLktKMAs+282CEiEb4bIv
-----END EC PRIVATE KEY-----`; // This key is an example, please use your own
const api_key = '4c268c0a-53ff-429b-92b6-47ef98a6d89a' // This key is an example, please use your own
try {
const jwt_header = {
typ: 'JWT',
alg: 'ES512',
}
const jwt_body = {
payload_md5: md5_hash,
timestamp: timestamp,
method: method,
uri: endpoint,
}
const encoded_header_token = jwt.sign(jwt_body, client_private_key, {
algorithm: 'ES512',
header: jwt_header,
})
const signed_header = {
AUTHORIZATION: encoded_header_token,
'API-CLIENT-KEY': api_key,
}
const url = `${base_url}${endpoint}`
const formData = new FormData()
formData.append('file', Buffer.from(arrayBuffer), {
filename: 'image.jpeg',
})
const response = await fetch(url, {
method: 'POST',
headers: {
...signed_header,
...formData.getHeaders(),
},
body: formData,
})
if (!response.ok) {
const errorText = await response.text()
console.log(`Error: ${response.status} ${response.statusText}`, errorText)
return
}
const data = await response.json()
console.log('Response data is: ', data)
return data.document_key
} catch (error) {
console.error('Error:', error)
}
}
async function main() {
const fileUrl = '<URL_LINK_TO_DOCUMENT_IMAGE>'
const documentBuffer = await getDocument(fileUrl)
const documentKey = await uploadDocument(documentBuffer)
console.log('Document key is: ' + documentKey)
}
main()
- Note: The example above uses the node-fetch library to make the call, but you can use the library of your choice. The important thing is that the call is made with the POST method, with the
Content-Typeheader set tomultipart/form-data, and the body is a FormData with the keyfileand the value as the binary of the file to be sent.
Warning
The 'Axios' library has a bug that causes the FormData to be sent empty. The issue can be seen in the GitHub repository. If this problem has not yet been resolved at the time of your integration, we suggest using the 'node-fetch' library to make this call.