Documents API
Documentation complète de l'API de gestion et d'extraction de documents dans Devana.ai.
Base URL: https://api.devana.ai
Préfixe: /v1/documents
Authentification: API Key requise
📑 Table des matières
- Vue d'ensemble
- Authentification
- Endpoints disponibles
- Format des payloads
- Statuts d'extraction
- Types de fichiers supportés
- Gestion des erreurs
- Exemples avancés
Vue d'ensemble
L'API Documents permet de gérer le cycle de vie complet des documents :
- Upload de documents avec extraction automatique du contenu
- Récupération du contenu extrait et structuré
- Suivi du statut d'extraction en temps réel
- Support de multiples formats (PDF, DOCX, images, etc.)
Cette API utilise un système d'extraction avancé (Odin) pour traiter les documents complexes et extraire leur structure, texte, tableaux et métadonnées.
Authentification
Toutes les requêtes nécessitent une clé API dans le header Authorization :
Authorization: Bearer YOUR_API_KEY
Les permissions sont vérifiées au niveau du dossier contenant le document.
Endpoints disponibles
GET /v1/documents/:id - Récupérer le contenu d'un document
Récupère le payload complet d'un document incluant le texte extrait, la structure et les métadonnées.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
id | String (CUID) | Oui | Identifiant unique du document |
Requête
GET /v1/documents/cm4doc123abc456def
Authorization: Bearer YOUR_API_KEY
Réponse (200 OK) - Document traité par Odin
{
"success": true,
"data": {
"documentId": "cm4doc123abc456def",
"status": "DONE",
"title": "Rapport Annuel 2024",
"content": "Contenu extrait du document...",
"pages": [
{
"pageNumber": 1,
"text": "Texte de la première page...",
"tables": [],
"images": []
}
],
"metadata": {
"author": "John Doe",
"creationDate": "2024-01-15",
"pageCount": 45,
"language": "fr"
},
"summary": "Résumé automatique du document...",
"keywords": ["rapport", "annuel", "2024", "finance"],
"totalWords": 12500
}
}
Réponse (200 OK) - Document texte simple
{
"success": true,
"data": {
"documentId": "cm4doc789xyz123abc",
"status": "DONE",
"text": "Contenu textuel du document...",
"words": 500,
"title": "document.txt",
"metadata": {
"mimetype": "text/plain",
"size": 15678
}
}
}
Exemple avec curl
curl -X GET https://api.devana.ai/v1/documents/cm4doc123abc456def \
-H "Authorization: Bearer YOUR_API_KEY"
GET /v1/documents/:id/status - Statut d'extraction
Récupère uniquement le statut d'extraction d'un document sans le contenu complet.
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
id | String (CUID) | Oui | Identifiant unique du document |
Requête
GET /v1/documents/cm4doc123abc456def/status
Authorization: Bearer YOUR_API_KEY
Réponse (200 OK)
{
"success": true,
"data": "DONE"
}
Statuts possibles :
PENDING: En attente de traitementIN_PROGRESS: Extraction en coursDONE: Extraction terminée avec succèsERROR: Erreur lors de l'extraction
Exemple avec curl
curl -X GET https://api.devana.ai/v1/documents/cm4doc123abc456def/status \
-H "Authorization: Bearer YOUR_API_KEY"
Utilisation pour le polling
# Script de polling pour attendre la fin de l'extraction
DOCUMENT_ID="cm4doc123abc456def"
STATUS="PENDING"
while [ "$STATUS" != "DONE" ] && [ "$STATUS" != "ERROR" ]; do
STATUS=$(curl -s -X GET "https://api.devana.ai/v1/documents/$DOCUMENT_ID/status" \
-H "Authorization: Bearer YOUR_API_KEY" | jq -r '.data')
echo "Status: $STATUS"
if [ "$STATUS" = "ERROR" ]; then
echo "Erreur lors de l'extraction"
exit 1
fi
if [ "$STATUS" != "DONE" ]; then
sleep 2
fi
done
echo "Extraction terminée, récupération du contenu..."
curl -X GET "https://api.devana.ai/v1/documents/$DOCUMENT_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
POST /v1/documents - Upload et extraction de document
Upload un document et lance automatiquement l'extraction du contenu. Retourne immédiatement le payload pour les fichiers simples ou après traitement pour les documents complexes.
Headers
| Header | Type | Requis | Description |
|---|---|---|---|
Authorization | String | Oui | Token Bearer avec API Key |
Content-Type | String | Oui | multipart/form-data |
Body Parameters (multipart/form-data)
| Paramètre | Type | Requis | Description |
|---|---|---|---|
file | File | Oui | Le fichier à uploader |
folderId | String (CUID) | Oui | ID du dossier de destination |
Requête
POST /v1/documents
Authorization: Bearer YOUR_API_KEY
Content-Type: multipart/form-data
Réponse (200 OK) - Document complexe (PDF, DOCX, Images)
Le système attend la fin de l'extraction avant de répondre :
{
"success": true,
"data": {
"documentId": "cm4newdoc456xyz789",
"status": "DONE",
"title": "Présentation Q4 2024",
"content": "Contenu extrait structuré...",
"pages": [
{
"pageNumber": 1,
"text": "Slide 1: Résultats Q4 2024...",
"images": [
{
"url": "https://storage.devana.ai/images/chart1.png",
"caption": "Graphique des ventes"
}
]
}
],
"metadata": {
"format": "PDF",
"pageCount": 25,
"extractionTime": 3.5
},
"summary": "Présentation des résultats du quatrième trimestre...",
"totalWords": 3500
}
}
Réponse (200 OK) - Document texte simple
Pour les fichiers texte simples, la réponse est immédiate :
{
"success": true,
"data": {
"text": "Contenu du fichier texte...",
"words": 250,
"title": "readme.md",
"metadata": {
"mimetype": "text/markdown",
"size": 5678
}
}
}
Exemple avec curl - Upload PDF
curl -X POST https://api.devana.ai/v1/documents \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@presentation.pdf" \
-F "folderId=cm4folder123abc"
Exemple avec curl - Upload image
curl -X POST https://api.devana.ai/v1/documents \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@diagram.png" \
-F "folderId=cm4folder123abc"
Format des payloads
Payload Odin (documents complexes)
Les documents traités par Odin retournent un payload structuré :
interface OdinPayload {
documentId: string;
status: ExtractStatus;
title?: string;
content?: string;
pages?: Page[];
metadata?: DocumentMetadata;
summary?: string;
keywords?: string[];
totalWords?: number;
error?: string;
}
interface Page {
pageNumber: number;
text: string;
tables?: Table[];
images?: Image[];
}
interface DocumentMetadata {
author?: string;
creationDate?: string;
modificationDate?: string;
pageCount?: number;
language?: string;
format?: string;
extractionTime?: number;
}
Payload texte simple
Les fichiers texte retournent un payload simplifié :
interface TextPayload {
text: string;
words: number;
title: string;
metadata: {
mimetype: string;
size: number;
};
}
Statuts d'extraction
| Statut | Description | Actions recommandées |
|---|---|---|
PENDING | Document en file d'attente | Attendre et vérifier régulièrement |
IN_PROGRESS | Extraction en cours | Continuer le polling |
DONE | Extraction réussie | Récupérer le payload complet |
ERROR | Échec de l'extraction | Vérifier les logs, réessayer si nécessaire |
Types de fichiers supportés
Documents avec extraction Odin
- PDF : Extraction complète avec structure, images, tableaux
- DOCX/DOC : Documents Word avec formatage préservé
- PPTX/PPT : Présentations PowerPoint
- Images : PNG, JPG, JPEG (avec OCR si nécessaire)
Documents avec extraction simple
- Texte : TXT, MD, CSV
- Code : JS, PY, JSON, XML, HTML
- Tableurs : XLSX, XLS (extraction basique)
Pour la liste complète, consultez Formats supportés.
Gestion des erreurs
| Code | Message | Description | Solution |
|---|---|---|---|
400 | Bad Request | Paramètres invalides | Vérifier le format des paramètres |
400 | No file uploaded | Aucun fichier fourni | Inclure un fichier dans la requête |
401 | Unauthorized | Permissions insuffisantes | Vérifier les droits sur le dossier |
404 | File/Folder not found | Ressource introuvable | Vérifier l'ID fourni |
408 | Request Timeout | Extraction trop longue | Réessayer ou utiliser l'API Jobs |
500 | Internal Server Error | Erreur serveur | Contacter le support |
Gestion des erreurs d'extraction
En cas d'erreur lors de l'extraction :
{
"success": false,
"error": {
"code": "EXTRACTION_FAILED",
"message": "Failed to extract content from PDF",
"details": "Corrupted file or unsupported format"
}
}
Exemples avancés
Upload et traitement de document avec retry
async function uploadDocumentWithRetry(file, folderId, maxRetries = 3) {
const formData = new FormData();
formData.append("file", file);
formData.append("folderId", folderId);
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch("https://api.devana.ai/v1/documents", {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
},
body: formData,
});
if (response.ok) {
const data = await response.json();
// Si le document est en cours de traitement
if (data.data.status === "IN_PROGRESS") {
return await waitForExtraction(data.data.documentId);
}
return data.data;
}
if (response.status === 408 && attempt < maxRetries) {
console.log(`Timeout, retry ${attempt}/${maxRetries}`);
await new Promise((resolve) => setTimeout(resolve, 2000 * attempt));
continue;
}
throw new Error(`Upload failed: ${response.statusText}`);
} catch (error) {
if (attempt === maxRetries) throw error;
console.log(`Error on attempt ${attempt}, retrying...`);
}
}
}
async function waitForExtraction(documentId) {
let status = "PENDING";
let attempts = 0;
const maxAttempts = 60; // 2 minutes maximum
while (status !== "DONE" && status !== "ERROR" && attempts < maxAttempts) {
await new Promise((resolve) => setTimeout(resolve, 2000));
const response = await fetch(
`https://api.devana.ai/v1/documents/${documentId}/status`,
{
headers: {
Authorization: `Bearer ${API_KEY}`,
},
}
);
const data = await response.json();
status = data.data;
attempts++;
console.log(`Status: ${status} (attempt ${attempts}/${maxAttempts})`);
}
if (status === "DONE") {
// Récupérer le payload complet
const response = await fetch(
`https://api.devana.ai/v1/documents/${documentId}`,
{
headers: {
Authorization: `Bearer ${API_KEY}`,
},
}
);
return (await response.json()).data;
}
throw new Error(`Extraction failed with status: ${status}`);
}
Batch processing de documents
#!/bin/bash
# Upload multiple documents to a folder
FOLDER_ID="cm4folder123abc"
FILES=("report.pdf" "presentation.pptx" "data.xlsx")
DOCUMENT_IDS=()
echo "Uploading documents..."
for FILE in "${FILES[@]}"; do
echo "Uploading $FILE..."
RESPONSE=$(curl -s -X POST https://api.devana.ai/v1/documents \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@$FILE" \
-F "folderId=$FOLDER_ID")
DOC_ID=$(echo $RESPONSE | jq -r '.data.documentId')
DOCUMENT_IDS+=($DOC_ID)
echo "Document $FILE uploaded with ID: $DOC_ID"
done
echo "Checking extraction status..."
# Wait for all documents to be processed
ALL_DONE=false
while [ "$ALL_DONE" = false ]; do
ALL_DONE=true
for DOC_ID in "${DOCUMENT_IDS[@]}"; do
STATUS=$(curl -s -X GET "https://api.devana.ai/v1/documents/$DOC_ID/status" \
-H "Authorization: Bearer YOUR_API_KEY" | jq -r '.data')
echo "Document $DOC_ID: $STATUS"
if [ "$STATUS" != "DONE" ] && [ "$STATUS" != "ERROR" ]; then
ALL_DONE=false
fi
done
if [ "$ALL_DONE" = false ]; then
sleep 3
fi
done
echo "All documents processed!"
# Retrieve all payloads
for DOC_ID in "${DOCUMENT_IDS[@]}"; do
echo "Retrieving content for $DOC_ID..."
curl -X GET "https://api.devana.ai/v1/documents/$DOC_ID" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o "output_$DOC_ID.json"
done
Extraction avec analyse du contenu
import requests
import json
from typing import Dict, List
class DocumentProcessor:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.devana.ai/v1"
self.headers = {"Authorization": f"Bearer {api_key}"}
def upload_and_analyze(self, file_path: str, folder_id: str) -> Dict:
"""Upload un document et analyse son contenu"""
# Upload du document
with open(file_path, 'rb') as f:
files = {'file': f}
data = {'folderId': folder_id}
response = requests.post(
f"{self.base_url}/documents",
headers=self.headers,
files=files,
data=data
)
if response.status_code != 200:
raise Exception(f"Upload failed: {response.text}")
document = response.json()['data']
# Analyser le contenu
analysis = self.analyze_content(document)
return {
'document': document,
'analysis': analysis
}
def analyze_content(self, document: Dict) -> Dict:
"""Analyse le contenu extrait"""
analysis = {
'word_count': document.get('totalWords', 0),
'page_count': len(document.get('pages', [])),
'has_tables': False,
'has_images': False,
'keywords': document.get('keywords', []),
'language': document.get('metadata', {}).get('language'),
'summary_available': 'summary' in document
}
# Vérifier la présence de tableaux et images
for page in document.get('pages', []):
if page.get('tables'):
analysis['has_tables'] = True
if page.get('images'):
analysis['has_images'] = True
return analysis
def extract_tables(self, document: Dict) -> List[Dict]:
"""Extrait tous les tableaux du document"""
tables = []
for page in document.get('pages', []):
for table in page.get('tables', []):
tables.append({
'page': page['pageNumber'],
'data': table
})
return tables
# Utilisation
processor = DocumentProcessor("YOUR_API_KEY")
result = processor.upload_and_analyze(
"financial_report.pdf",
"cm4folder123abc"
)
print(f"Document analysé : {result['document']['title']}")
print(f"Analyse : {json.dumps(result['analysis'], indent=2)}")
# Extraire les tableaux si présents
if result['analysis']['has_tables']:
tables = processor.extract_tables(result['document'])
print(f"Nombre de tableaux trouvés : {len(tables)}")
Intégration avec l'API Jobs
Pour les documents volumineux ou les traitements batch, utilisez l'API Jobs pour suivre l'extraction :
# Vérifier le job d'extraction
curl -X GET "https://api.devana.ai/v1/jobs?targetId=cm4doc123abc&type=EXTRACTION" \
-H "Authorization: Bearer YOUR_API_KEY"
Bonnes pratiques
-
Gestion des timeouts
- Implémenter un système de retry pour les uploads
- Utiliser le polling pour les documents complexes
- Définir un timeout maximum (ex: 5 minutes)
-
Optimisation des performances
- Grouper les uploads en batch quand possible
- Utiliser l'API Jobs pour le suivi asynchrone
- Mettre en cache les payloads extraits
-
Gestion des erreurs
- Toujours vérifier le statut d'extraction
- Logger les erreurs pour le debugging
- Prévoir un fallback pour les échecs d'extraction
-
Sécurité
- Vérifier les permissions avant l'upload
- Valider les types de fichiers côté client
- Limiter la taille des uploads
Support et assistance
Pour toute question ou problème concernant l'API Documents :
- Consultez la documentation générale de l'API
- Contactez le support technique : support@devana.ai
- Reportez les bugs sur notre GitHub