Upload Document
curl --request POST \
--url http://api.gu1.ai/documents/upload \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"entityId": "<string>",
"categoryId": "<string>"
}
'import requests
url = "http://api.gu1.ai/documents/upload"
payload = {
"entityId": "<string>",
"categoryId": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({entityId: '<string>', categoryId: '<string>'})
};
fetch('http://api.gu1.ai/documents/upload', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/documents/upload",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'entityId' => '<string>',
'categoryId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/documents/upload"
payload := strings.NewReader("{\n \"entityId\": \"<string>\",\n \"categoryId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/documents/upload")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"entityId\": \"<string>\",\n \"categoryId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/documents/upload")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityId\": \"<string>\",\n \"categoryId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"400": {},
"401": {},
"500": {},
"id": "<string>",
"name": "<string>",
"originalFileName": "<string>",
"fileSize": 123,
"mimeType": "<string>",
"storagePath": "<string>",
"storageProvider": "<string>",
"categoryId": "<string>",
"organizationId": "<string>",
"createdAt": {}
}API Reference
Upload Document
Upload a document and optionally associate it with an entity and category β in the gu1 platform for KYC, KYB, and compliance evidence.
POST
/
documents
/
upload
Upload Document
curl --request POST \
--url http://api.gu1.ai/documents/upload \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"entityId": "<string>",
"categoryId": "<string>"
}
'import requests
url = "http://api.gu1.ai/documents/upload"
payload = {
"entityId": "<string>",
"categoryId": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({entityId: '<string>', categoryId: '<string>'})
};
fetch('http://api.gu1.ai/documents/upload', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/documents/upload",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'entityId' => '<string>',
'categoryId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/documents/upload"
payload := strings.NewReader("{\n \"entityId\": \"<string>\",\n \"categoryId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/documents/upload")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"entityId\": \"<string>\",\n \"categoryId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/documents/upload")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityId\": \"<string>\",\n \"categoryId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"400": {},
"401": {},
"500": {},
"id": "<string>",
"name": "<string>",
"originalFileName": "<string>",
"fileSize": 123,
"mimeType": "<string>",
"storagePath": "<string>",
"storageProvider": "<string>",
"categoryId": "<string>",
"organizationId": "<string>",
"createdAt": {}
}Upload files associated with entities using multipart/form-data.
Common categories include:
Authentication
This endpoint requires authentication via Bearer token and organization context. Required Headers:Authorization: Bearer <jwt-token>X-Organization-ID: <organization-id>
Form Data Parameters
File
required
The file to upload (any type supported)
UUID
ID of the entity to associate the document with
UUID
ID of the document category (UBO, Legal Representative, Corporate, etc.)
Request Example
curl -X POST https://api.gu1.ai/documents/upload \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "X-Organization-ID: YOUR_ORG_ID" \
-F "file=@/path/to/document.pdf" \
-F "entityId=bb0c2d24-b519-40ec-b765-86de831ca0af" \
-F "categoryId=c5e9a3f2-1234-5678-9abc-def012345678"
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('entityId', 'bb0c2d24-b519-40ec-b765-86de831ca0af');
formData.append('categoryId', 'c5e9a3f2-1234-5678-9abc-def012345678');
const response = await fetch('https://api.gu1.ai/documents/upload', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'X-Organization-ID': organizationId
},
body: formData
});
const document = await response.json();
import requests
files = {'file': open('/path/to/document.pdf', 'rb')}
data = {
'entityId': 'bb0c2d24-b519-40ec-b765-86de831ca0af',
'categoryId': 'c5e9a3f2-1234-5678-9abc-def012345678'
}
response = requests.post(
'https://api.gu1.ai/documents/upload',
headers={
'Authorization': f'Bearer {token}',
'X-Organization-ID': org_id
},
files=files,
data=data
)
document = response.json()
Response
UUID
Unique identifier for the document
string
Display name of the document
string
Original filename of the uploaded file
number
File size in bytes
string
MIME type of the file
string
Path where the file is stored (S3 key or local path)
string
Storage provider used (βs3β or βlocalβ)
UUID
ID of the document category (if assigned)
UUID
ID of the organization that owns the document
timestamp
When the document was created
Response Example
{
"id": "d7f8e9c0-1234-5678-9abc-def012345678",
"name": "document.pdf",
"description": "Documento subido: document.pdf",
"type": "other",
"fileName": "1730649606123_document.pdf",
"originalFileName": "document.pdf",
"fileSize": 245678,
"mimeType": "application/pdf",
"fileExtension": "pdf",
"storagePath": "/uploads/1730649606123_document.pdf",
"storageProvider": "local",
"securityLevel": "internal",
"categoryId": "c5e9a3f2-1234-5678-9abc-def012345678",
"organizationId": "24236b0a-e34d-4218-b3d2-76b101ce8aa9",
"createdBy": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"createdAt": "2025-11-03T15:30:45.123Z",
"updatedAt": "2025-11-03T15:30:45.123Z"
}
What Happens After Upload
- Storage: File is uploaded to S3 (if enabled) or local storage
- Database Record: Document record is created in the database
- Versioning: Initial version (v1) is automatically created
- Entity Relationship: If
entityIdis provided, a relationship is created automatically - Risk Analysis: Automatic risk analysis is triggered if rules are configured
Supported File Types
- Documents: PDF, DOC, DOCX, TXT
- Images: PNG, JPG, JPEG, GIF
- Spreadsheets: XLS, XLSX, CSV
- Others: Any file type
Document Categories
To get available categories, use:GET /documents/categories
- UBO (Ultimate Beneficial Owner)
- Legal Representative
- Corporate Documents
- Enhanced Due Diligence
Error Responses
error
Bad Request - Missing file or authentication
{
"error": "No file provided"
}
error
Unauthorized - Invalid token
{
"error": "Unauthorized - No token provided"
}
error
Internal Server Error
{
"error": "Error interno del servidor",
"details": "Error message here"
}
Notes
The system automatically detects if S3 storage is configured and uses it, otherwise falls back to local storage.
Maximum file size depends on server configuration (typically 50MB).
Even if
entityId or categoryId donβt exist, the document will still be created. The relationship or category assignment will simply be skipped.Was this page helpful?