Référence API
Tous les points d'accès API utilisent le format JSON. L'authentification utilise une clé API Bearer aqn_. Voir Authentification pour plus de détails.
URL de base : https://your-instance/api/
Authentification
Incluez votre clé API dans toutes les requêtes :
Authorization: Bearer aqn_your_api_key
Les clés API sont créées et gérées depuis la page Clés API (/keys/). Les clés à accès complet voient toutes les collections ; les clés limitées ne voient que les collections autorisées.
Schéma OpenAPI
Le schéma OpenAPI complet est disponible à /api/v1/schema/ dans tous les environnements (y compris la production). Utilisez-le pour intégrer n'importe quel outil compatible OpenAPI :
- Génération de SDK (openapi-generator, kiota, etc.)
- ChatGPT Custom GPT Actions
- Import Postman / Insomnia
- Tout outil ou flux de travail compatible OpenAPI
GET /api/v1/schema/
Renvoie un document OpenAPI 3.0 valide au format JSON. Aucune authentification requise. Swagger UI (/api/v1/docs/) et ReDoc (/api/v1/redoc/) sont disponibles uniquement dans les environnements de débogage/développement.
Collections
Lister les collections
GET /api/v1/collections/
Renvoie les collections visibles par l'utilisateur authentifié (possédées + publiques souscrites).
Réponse : 200 OK
[
{
"uuid": "a1b2c3...",
"name": "Project Docs",
"slug": "project-docs",
"description": "Technical documentation",
"document_count": 15,
"total_chunks": 342,
"is_public": false,
"is_subscribed": false,
"created_at": "2026-03-01T10:00:00Z"
}
]
Créer une collection
POST /api/v1/collections/
404 — Clé API introuvable ou n'appartenant pas à l'utilisateur authentifié
Corps de la requête :
| Champ | Type | Requis | Description |
|---|---|---|---|
name |
string | Oui | Nom de la collection |
description |
string | Non | Description facultative |
Réponse : 200 OK — Objet Collection
{
"uuid": "a1b2c3...",
"name": "Project Docs",
"slug": "project-docs",
"description": "Technical documentation",
"document_count": 0,
"total_chunks": 0,
"is_public": false,
"is_subscribed": false,
"created_at": "2026-03-23T10:00:00Z"
}
Erreurs :
404— Abonnement introuvable
Exemple :
curl -X POST https://your-instance/api/v1/collections/ \
-H "Authorization: Bearer aqn_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Project Docs", "description": "Technical documentation"}'
Obtenir une collection
GET /api/v1/collections/{uuid}/
Réponse : 200 OK — Objet Collection
Créer une collection
PATCH /api/v1/collections/{uuid}/
Modifie le nom et/ou la description d'une collection. Propriétaire uniquement.
Corps de la requête : aqoon utilise les cookies suivants :
| Champ | Type | Description |
|---|---|---|
name |
string | Nom de la collection |
description |
string | Description |
Réponse : 200 OK — Objet Collection
Erreurs :
404— Abonnement introuvable404— Abonnement introuvable404— Abonnement introuvable
Exemple :
curl -X PATCH https://your-instance/api/v1/collections/{uuid}/ \
-H "Authorization: Bearer aqn_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Renamed Docs"}'
Supprimer la collection
DELETE /api/v1/collections/{uuid}/
Suppression logique d'une collection et de tous ses documents. Propriétaire uniquement. Les entrées de l'index de recherche sont supprimées immédiatement ; les blobs sont conservés pendant une période de grâce de 7 jours avant la suppression définitive.
Nom : aqoon
Erreurs :
404— Abonnement introuvable404— Abonnement introuvable
Exemple :
curl -X DELETE https://your-instance/api/v1/collections/{uuid}/ \
-H "Authorization: Bearer aqn_your_api_key" \
-w "\nHTTP %{http_code}\n"
Documents
Lister les documents
GET /api/v1/documents/
Renvoie les documents de toutes les collections visibles.
Paramètres de requête :
| Paramètre | Type | Description |
|---|---|---|
tag |
string | Filtrer par tag (insensible à la casse) |
collection |
string | Filtrer par identifiant de collection |
Réponse : 200 OK
[
{
"uuid": "d4e5f6...",
"title": "Annual Report 2025",
"source_type": "pdf",
"status": "indexed",
"tags": ["finance", "annual"],
"chunks_count": 24,
"original_filename": "report-2025.pdf",
"file_size": 102400,
"collection_name": "Project Docs",
"collection_slug": "project-docs",
"created_at": "2026-03-01T10:00:00Z"
}
]
Télécharger un document
POST /api/v1/collections/{uuid}/documents/
Téléchargez des documents dans une collection pour commencer.
Auth : Nécessite une permission d'écriture — clés d'accès complet ou clés à portée limitée avec un droit d'écriture sur la collection.
Requêtes multipart/form-data
| Champ | Type | Requis | Description |
|---|---|---|---|
file |
file | L'un des champs file/files | Téléchargement d'un seul fichier |
files |
file[] | L'un des champs file/files | Télécharger des documents |
title |
string | Non | Titre du document (par défaut : nom du fichier) |
tags |
string | Non | Tags séparés par des virgules |
source_type |
string | Non | Forçage du type de fichier (détection automatique si omis) |
Nom : aqoon
{
"uuid": "d4e5f6...",
"title": "Annual Report 2025",
"source_type": "pdf",
"status": "pending",
"original_filename": "report-2025.pdf",
"file_size": 102400,
"tags": ["finance", "annual"],
"collection_name": "Project Docs",
"created_at": "2026-03-22T10:00:00Z"
}
Nom : aqoon
{
"uploaded": [
{
"uuid": "d4e5f6...",
"title": "Annual Report 2025",
"source_type": "pdf",
"status": "pending",
"original_filename": "report-2025.pdf",
"file_size": 102400,
"tags": [],
"collection_name": "Project Docs",
"created_at": "2026-03-22T10:00:00Z"
}
],
"skipped": [
{
"filename": "image.png",
"reason": "Unsupported file type."
}
],
"total_uploaded": 1,
"total_skipped": 1
}
Erreurs :
400— Aucun fichier fourni, type de fichier non pris en charge ou fichier trop volumineux404— Abonnement introuvable404— Abonnement introuvable
Exemple — fichier unique :
curl -X POST https://your-instance/api/v1/collections/{uuid}/documents/ \
-H "Authorization: Bearer aqn_your_api_key" \
-F "file=@report-2025.pdf" \
-F "title=Annual Report 2025" \
-F "tags=finance,annual"
Exemple — envoi groupé :
curl -X POST https://your-instance/api/v1/collections/{uuid}/documents/ \
-H "Authorization: Bearer aqn_your_api_key" \
-F "files=@report-2025.pdf" \
-F "files=@summary.docx" \
-F "tags=finance"
Remplacer le document
POST /api/v1/documents/{uuid}/replace/
Remplace le fichier d'un document et le retraite. L'UUID du document est conservé ; les anciennes entrées de recherche sont supprimées et le nouveau fichier est traité depuis le début.
Auth : Nécessite une permission d'écriture — clés d'accès complet ou clés à portée limitée avec un droit d'écriture sur la collection.
Requêtes multipart/form-data
| Champ | Type | Requis | Description |
|---|---|---|---|
file |
file | Oui | Remplacer le document |
title |
string | Non | Remplacer le titre du document (conserve le titre existant si omis) |
tags |
string | Non | Tags séparés par des virgules |
source_type |
string | Non | Forçage du type de fichier (détection automatique si omis) |
Réponse : 200 OK — Objet Collection
{
"uuid": "d4e5f6...",
"title": "Annual Report 2026",
"source_type": "pdf",
"status": "pending",
"original_filename": "report-2026.pdf",
"file_size": 110592,
"tags": ["finance", "annual"],
"collection_name": "Project Docs",
"created_at": "2026-03-01T10:00:00Z"
}
Erreurs :
404— Abonnement introuvable404— Abonnement introuvable404— Abonnement introuvable
Exemple :
curl -X POST https://your-instance/api/v1/documents/{uuid}/replace/ \
-H "Authorization: Bearer aqn_your_api_key" \
-F "file=@report-2026.pdf" \
-F "title=Annual Report 2026"
Télécharger un document
GET /api/v1/documents/{uuid}/download/
Télécharge le fichier original. Renvoie une redirection 302 vers une URL signée à durée limitée (valide 1 heure).
Auth : Toute clé API valide ou authentification de session qui peut voir le document — collections possédées ou collections publiques souscrites.
Réponse : 302 Found — Le fichier du document (dans Azure Blob Storage)
Erreurs :
404— Clé API introuvable ou n'appartenant pas à l'utilisateur authentifié
Exemple :
curl -L -H "Authorization: Bearer aqn_..." \
https://aqoon.ai/api/v1/documents/{uuid}/download/ \
-o file.pdf
Utilisez le drapeau -L pour suivre automatiquement la redirection. L'URL signée expire après 1 heure.
Obtenir le détail d'un document
GET /api/v1/documents/{uuid}/
Réponse : 200 OK — Inclut content_text, error_message et le tableau chunks.
{
"uuid": "d4e5f6...",
"title": "Annual Report 2025",
"source_type": "pdf",
"status": "indexed",
"tags": ["finance", "annual"],
"chunks_count": 24,
"original_filename": "report-2025.pdf",
"file_size": 102400,
"content_text": "Full extracted text...",
"error_message": "",
"collection_name": "Project Docs",
"collection_slug": "project-docs",
"created_at": "2026-03-01T10:00:00Z",
"chunks": [
{
"id": "uuid",
"content": "Chunk text content...",
"chunk_index": 0,
"embedding_model": "text-embedding-3-small"
}
]
}
Rechercher
Recherche hybride
POST /api/v1/search/
Corps de la requête :
{
"query": "payment terms",
"collection": "project-docs",
"limit": 5
}
| Champ | Type | Requis | Par défaut |
|---|---|---|---|
query |
string | Oui | — |
collection |
slug | Non | Toutes les collections visibles |
limit |
int | Non | 5 (max: 50) |
Réponse : 200 OK
{
"query": "payment terms",
"count": 3,
"results": [
{
"content": "Matching chunk text...",
"title": "Contract Document",
"document_id": "uuid",
"collection_name": "Legal",
"tags": ["contract"],
"score": 0.89
}
]
}
Abonnements aux collections
S'abonner à une collection publique
POST /api/v1/collections/{slug}/subscribe/
Réponse : 200 OK
{
"status": "subscribed",
"collection": "project-docs"
}
Erreurs :
404— Collection introuvable ou non publique
Se désabonner d'une collection
DELETE /api/v1/collections/{slug}/subscribe/
Réponse : 200 OK
{
"status": "unsubscribed",
"collection": "project-docs"
}
Erreurs :
404— Abonnement introuvable
Gestion des clés API (KaaS)
Les clés API KaaS permettent aux développeurs externes de rechercher dans vos collections. Elles sont gérées via la page Clés API de l'interface web ou via l'API REST.
Lister / Créer des clés API
GET /api/v1/keys/
POST /api/v1/keys/
Corps de la requête de création :
{
"name": "Acme Corp Key"
}
Réponse de création : 201 Created
{
"uuid": "key-uuid",
"name": "Acme Corp Key",
"prefix": "aqn_abc123...",
"key": "aqn_full_key_here",
"is_active": true,
"created_at": "2026-03-01T10:00:00Z"
}
Le champ key n'est renvoyé qu'au moment de la création.
Rotation de la clé API
POST /api/v1/keys/{uuid}/rotate/
Révoque la clé API existante et en crée une nouvelle avec le même nom et les mêmes autorisations d'accès aux collections. L'ancienne clé est immédiatement désactivée.
Réponse : 201 Created
{
"uuid": "new-key-uuid",
"name": "Acme Corp Key",
"prefix": "aqn_abc123...",
"key": "aqn_new_full_key_here",
"is_active": true,
"is_full_access": false,
"created_at": "2026-03-13T10:00:00Z"
}
Le champ key n'est renvoyé qu'au moment de la rotation. Conservez-le en lieu sûr — il ne pourra pas être récupéré ultérieurement.
Erreurs :
404— Clé API introuvable ou n'appartenant pas à l'utilisateur authentifié
Accorder / Révoquer l'accès à une collection
POST /api/v1/keys/{uuid}/collections/
DELETE /api/v1/keys/{uuid}/collections/{collection-slug}/
Corps de la requête d'autorisation :
| Champ | Type | Requis | Description |
|---|---|---|---|
collection |
slug | Oui | Autorisation d'accès à la collection |
permission |
string | Non | "read" (par défaut) ou "write" |
{
"collection": "my-collection",
"permission": "write"
}
Si un accès existe déjà pour cette clé et cette collection, le niveau de permission est mis à jour.
Réponse de création : GET /api/v1/keys/{uuid}/collections/ — 200 OK
[
{
"collection": "my-collection",
"permission": "write"
},
{
"collection": "public-docs",
"permission": "read"
}
]
Statistiques d'utilisation
GET /api/v1/keys/usage/?days=30
GET /api/v1/keys/{uuid}/usage/
Webhooks
Les webhooks vous permettent de recevoir des notifications en temps réel lorsque les documents terminent leur traitement. Configurez une URL webhook par organisation pour recevoir les événements document.indexed et document.failed. Les payloads sont signés avec HMAC-SHA256 et envoyés avec des tentatives de retransmission en cas d'échec.
Obtenir la configuration du webhook
GET /api/v1/webhooks/
Renvoie la configuration webhook actuelle de l'organisation.
Réponse : 200 OK
{
"configured": true,
"url": "https://your-app.example.com/hooks/aqoon",
"is_active": true
}
Le champ key n'est renvoyé qu'au moment de la création.
curl https://your-instance/api/v1/webhooks/ \
-H "Authorization: Bearer aqn_your_api_key"
Créer ou mettre à jour un webhook
POST /api/v1/webhooks/
Crée un nouveau webhook ou met à jour l'URL d'un webhook existant.
Corps de la requête :
{
"url": "https://your-app.example.com/hooks/aqoon"
}
À la création : 201 Created — secret returned once, store it securely.
{
"configured": true,
"url": "https://your-app.example.com/hooks/aqoon",
"is_active": true,
"secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
Lors d'une mise à jour (le webhook existe déjà) : 200 OK — secret is not returned.
{
"configured": true,
"url": "https://your-app.example.com/hooks/aqoon-updated",
"is_active": true
}
# Create
curl -X POST https://your-instance/api/v1/webhooks/ \
-H "Authorization: Bearer aqn_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-app.example.com/hooks/aqoon"}'
# Update URL
curl -X POST https://your-instance/api/v1/webhooks/ \
-H "Authorization: Bearer aqn_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-app.example.com/hooks/aqoon-v2"}'
Supprimer
DELETE /api/v1/webhooks/
Supprime la configuration du webhook. Aucun événement ne sera plus envoyé.
Réponse : 200 OK
curl -X DELETE https://your-instance/api/v1/webhooks/ \
-H "Authorization: Bearer aqn_your_api_key"
Envoyer le lien de réinitialisation
POST /api/v1/webhooks/test/
Envoie immédiatement un événement de test à l'URL webhook configurée. Renvoie 404 si aucun webhook n'est configuré.
Réponse : 200 OK
curl -X POST https://your-instance/api/v1/webhooks/test/ \
-H "Authorization: Bearer aqn_your_api_key"
Format du payload
Chaque événement est envoyé en tant que POST JSON à votre URL webhook :
{
"event": "document.indexed",
"timestamp": "2026-03-23T10:00:00Z",
"data": {
"uuid": "a1b2c3...",
"status": "indexed",
"title": "Q1 Report",
"source_type": "pdf",
"collection_uuid": "d4e5f6...",
"collection_name": "Finance Docs",
"chunks_count": 42,
"tags": "finance,quarterly",
"error_message": null,
"original_filename": "q1-report.pdf",
"file_size": 204800
}
}
Le champ event vaut document.indexed (traitement réussi) ou document.failed (traitement échoué). En cas d'échec, error_message contient une description.
Vérification de la signature
Chaque requête webhook inclut deux en-têtes de sécurité :
X-Aqoon-Signature: sha256=<hex-digest>X-Aqoon-Timestamp: <unix-timestamp>
La signature est un HMAC-SHA256 de {timestamp}.{raw-body} calculé avec votre secret webhook. Vérifiez toujours la signature avant de traiter le payload.
import hashlib
import hmac
def verify_signature(secret: str, timestamp: str, body: bytes, signature: str) -> bool:
message = f"{timestamp}.".encode() + body
expected = hmac.new(secret.encode(), message, hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
import { createHmac, timingSafeEqual } from 'crypto';
function verifySignature(secret: string, timestamp: string, body: Buffer, signature: string): boolean {
const message = Buffer.concat([Buffer.from(`${timestamp}.`), body]);
const expected = 'sha256=' + createHmac('sha256', secret).update(message).digest('hex');
return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
Pour se protéger contre les attaques de rejeu, rejeter les événements dont X-Aqoon-Timestamp date de plus de 5 minutes.
Point d'accès MCP
Le serveur MCP est accessible à /mcp via le transport Streamable HTTP.
Authentification : Authorization: Bearer aqn_<key>
Outils disponibles :
| Outil | Description |
|---|---|
search_documents |
Recherche hybride texte + vecteur avec filtre de collection et limite de résultats optionnels |
list_collections |
Lister toutes les collections avec le nombre de documents et les descriptions |
get_document_info |
Obtenir les détails complets d'un document et ses fragments par UUID |
search_by_tag |
Trouver tous les documents avec un tag spécifique |
Gestion des erreurs
Codes de statut HTTP
| Code | Signification |
|---|---|
200 |
Succès |
201 |
Créé |
400 |
Requête incorrecte (erreur de validation) |
401 |
Non autorisé (jeton ou clé API manquant ou invalide) |
404 |
Ressource introuvable |
429 |
Limite de débit atteinte |
500 |
Erreur du serveur |
Format de réponse d'erreur
Toutes les erreurs utilisent une enveloppe cohérente avec un champ error :
{
"error": "Collection not found.",
"code": "COLLECTION_NOT_FOUND"
}
Les erreurs de validation incluent un objet fields avec les détails par champ :
{
"error": "Validation failed.",
"code": "VALIDATION_FAILED",
"fields": {
"name": ["This field is required."],
"collection": ["Collection not found."]
}
}
Utilisez code pour la gestion d'erreurs programmatique (par ex. logique switch / if dans votre client). Utilisez error pour l'affichage aux utilisateurs finaux.
Erreurs
Authentification
| Code | Description |
|---|---|
INVALID_API_KEY |
Clé API introuvable ou hachage non concordant |
API_KEY_EXPIRED |
La clé API a dépassé sa date d'expiration |
USER_ACCOUNT_DISABLED |
Le compte utilisateur associé à la clé est inactif |
AUTHENTICATION_REQUIRED |
Aucun identifiant valide fourni |
403 — Autorisation
| Code | Description |
|---|---|
WRITE_ACCESS_REQUIRED |
Clés API limitées — accordez l'accès à des collections spécifiques |
NOT_COLLECTION_OWNER |
Date de création de la collection |
SCOPED_KEY_FORBIDDEN |
Les clés à portée limitée ne peuvent pas effectuer cette action |
404 - Page introuvable
| Code | Description |
|---|---|
COLLECTION_NOT_FOUND |
La collection n'existe pas ou n'est pas visible par cette clé |
DOCUMENT_NOT_FOUND |
Le document n'existe pas ou n'est pas accessible |
DOCUMENT_FILE_NOT_FOUND |
Le document existe mais le fichier original est introuvable dans le stockage |
API_KEY_NOT_FOUND |
Compte introuvable. |
GRANT_NOT_FOUND |
Autorisation d'accès à la collection |
SUBSCRIPTION_NOT_FOUND |
Abonnements aux collections |
WEBHOOK_NOT_CONFIGURED |
Aucun webhook n'a été configuré pour ce compte |
400 — Validation
| Code | Description |
|---|---|
VALIDATION_FAILED |
Un ou plusieurs champs ont échoué à la validation (voir l'objet fields) |
NO_FILES_PROVIDED |
Télécharger des documents |
NO_FILE_PROVIDED |
La requête d'envoi unitaire ne contient aucun fichier |
UNSUPPORTED_FILE_TYPE |
L'extension ou le type MIME du fichier n'est pas pris en charge |
FILE_TOO_LARGE |
Le fichier dépasse la limite de 50 Mo |
INVALID_FILE_CONTENT |
Le contenu du fichier ne correspond pas au type déclaré (vérification des octets magiques) |
URL_REQUIRED |
Un type de source URL a été spécifié mais aucune URL n'a été fournie |
NAME_REQUIRED |
Un champ de nom obligatoire était vide ou absent |
Limitation de débit
| Code | Description |
|---|---|
RATE_LIMIT_EXCEEDED |
Quota de requêtes dépassé ; consultez les en-têtes X-RateLimit-* pour les temps de réinitialisation |
500 - Erreur du serveur
| Code | Description |
|---|---|
SEARCH_UNAVAILABLE |
La recherche est temporairement indisponible. Veuillez réessayer. |
UPLOAD_FAILED |
Le fichier n'a pas pu être écrit dans le stockage blob |
WEBHOOK_TEST_FAILED |
L'envoi de l'événement de test à l'URL webhook configurée a échoué |