Français
Modèles d’IA
Les routes sont relatives à <PUBLIC_BASE_URL> ; les corps de requête et de réponse sont en JSON sauf mention contraire. L’authentification, les portées, la pagination et le format des erreurs sont décrits dans les guides de l’API REST.
GET /api/v1/llm-defaults
Lire les défauts d’IA résolus
Le modèle que chaque usage obtiendra réellement sur cette instance, après le routage de l’administrateur. null pour un usage qu’aucun fournisseur ne sert. Des noms de modèles seulement : ni clé, ni catalogue.
Accès — Session de membre ou clé d’API portant connections:read.
Réponses
200 — Les défauts.
| Champ | Type | Requis |
|---|---|---|
defaults | object | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"defaults": {
"type": "object",
"properties": {
"classify": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"compose": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"extract": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"general": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"analyzer": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"assistant": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [ "classify", "compose", "extract", "general", "analyzer", "assistant" ],
"additionalProperties": false
}
},
"required": [ "defaults" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
GET /api/v1/llm-connections
Lister les connexions d’IA
Ce dont le sélecteur d’un nœud a besoin : identifiant, libellé, fournisseur et drapeau par défaut. Construit sans rien déchiffrer.
Accès — Session de membre ou clé d’API portant connections:read.
Réponses
200 — Les connexions.
| Champ | Type | Requis |
|---|---|---|
connections | object[] | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"connections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"label": { "type": "string" },
"isDefault": { "type": "boolean" }
},
"required": [ "id", "provider", "label", "isDefault" ],
"additionalProperties": false
}
}
},
"required": [ "connections" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
GET /api/v1/llm-connections/{id}/models
Lister les modèles d’une connexion d’IA
restricted dit si l’administrateur a fermé la liste (seulement ces modèles) ou s’il s’agit d’une aide à la saisie (modèles connus, les autres restent valides).
Accès — Session de membre ou clé d’API portant connections:read.
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Réponses
200 — Les modèles.
| Champ | Type | Requis |
|---|---|---|
connectionId | string (uuid) | oui |
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
models | string[] | oui |
restricted | boolean | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"models": { "type": "array", "items": { "type": "string" } },
"restricted": { "type": "boolean" }
},
"required": [ "connectionId", "provider", "models", "restricted" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.connection_not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/admin/llm/connections
Lister toutes les connexions d’IA
Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).
Réponses
200 — Les connexions.
| Champ | Type | Requis |
|---|---|---|
connections | object[] | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"connections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"label": { "type": "string" },
"isDefault": { "type": "boolean" },
"hasApiKey": { "type": "boolean" },
"apiKeyHint": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"enabledModels": {
"anyOf": [
{ "type": "array", "items": { "type": "string" } },
{ "type": "null" }
]
},
"updatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
}
},
"required": [
"id",
"provider",
"label",
"isDefault",
"hasApiKey",
"apiKeyHint",
"baseUrl",
"enabledModels",
"updatedAt"
],
"additionalProperties": false
}
}
},
"required": [ "connections" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
POST /api/v1/admin/llm/connections
Ajouter une connexion d’IA
Ajoute une clé à côté des autres pour un fournisseur (le PUT du fournisseur remplace la connexion par défaut). Le libellé est unique sur l’instance. Journalisée dans l’audit, jamais avec la clé.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
label | string | oui |
apiKey | string | non |
baseUrl | string (uri) | non |
withoutApiKey | boolean | non |
enabledModels | string[] | non |
makeDefault | boolean | non |
Schéma JSON
json
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"label": { "type": "string", "minLength": 1, "maxLength": 80 },
"apiKey": { "type": "string", "minLength": 1, "maxLength": 512 },
"baseUrl": { "type": "string", "maxLength": 2048, "format": "uri" },
"withoutApiKey": { "type": "boolean" },
"enabledModels": {
"minItems": 1,
"maxItems": 64,
"type": "array",
"items": { "type": "string", "minLength": 1, "maxLength": 128 }
},
"makeDefault": { "type": "boolean" }
},
"required": [ "provider", "label" ]
}Réponses
201 — L’état de la connexion.
| Champ | Type | Requis |
|---|---|---|
id | string (uuid) | oui |
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
label | string | oui |
isDefault | boolean | oui |
hasApiKey | boolean | oui |
apiKeyHint | string | null | oui |
baseUrl | string | null | oui |
enabledModels | string[] | null | oui |
updatedAt | string (date-time) | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"label": { "type": "string" },
"isDefault": { "type": "boolean" },
"hasApiKey": { "type": "boolean" },
"apiKeyHint": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"enabledModels": {
"anyOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "null" } ]
},
"updatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
}
},
"required": [
"id",
"provider",
"label",
"isDefault",
"hasApiKey",
"apiKeyHint",
"baseUrl",
"enabledModels",
"updatedAt"
],
"additionalProperties": false
}400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Cette opération accepte un en-tête Idempotency-Key : rejouer la même requête avec la même clé rend la réponse d’origine au lieu d’agir deux fois. Voir Idempotence.
Codes d’erreur — request.bad_request, llm.encryption_disabled, llm.invalid_base_url, llm.api_key_required, llm.connection_label_taken. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
PUT /api/v1/admin/llm/connections/{id}
Modifier une connexion d’IA
Renommer, remplacer la clé, changer l’URL ou les modèles autorisés. Une apiKey absente conserve celle en place.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
label | string | non |
apiKey | string | non |
baseUrl | string (uri) | non |
withoutApiKey | boolean | non |
enabledModels | string[] | non |
Schéma JSON
json
{
"type": "object",
"properties": {
"label": { "type": "string", "minLength": 1, "maxLength": 80 },
"apiKey": { "type": "string", "minLength": 1, "maxLength": 512 },
"baseUrl": { "type": "string", "maxLength": 2048, "format": "uri" },
"withoutApiKey": { "type": "boolean" },
"enabledModels": {
"minItems": 1,
"maxItems": 64,
"type": "array",
"items": { "type": "string", "minLength": 1, "maxLength": 128 }
}
}
}Réponses
200 — L’état de la connexion.
| Champ | Type | Requis |
|---|---|---|
id | string (uuid) | oui |
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
label | string | oui |
isDefault | boolean | oui |
hasApiKey | boolean | oui |
apiKeyHint | string | null | oui |
baseUrl | string | null | oui |
enabledModels | string[] | null | oui |
updatedAt | string (date-time) | oui |
Même schéma que POST /api/v1/admin/llm/connections.
400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — request.bad_request, llm.connection_not_found, llm.connection_label_taken, llm.invalid_base_url, llm.encryption_disabled. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
DELETE /api/v1/admin/llm/connections/{id}
Retirer une connexion d’IA
Refusée (409) tant qu’un workflow publié la référence, sauf force=true ; refusée quand c’est la connexion par défaut et que d’autres existent. 204 même si elle n’existait plus.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
force | requête | string | non |
Réponses
204 — Retirée.
400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.connection_in_use, llm.connection_is_default. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
POST /api/v1/admin/llm/connections/{id}/default
Faire d’une connexion d’IA la connexion par défaut
La connexion devient celle par défaut de son fournisseur ; l’ancienne cède la place. Journalisé dans l’audit.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
id | chemin | string | oui |
Réponses
200 — L’état de la connexion.
| Champ | Type | Requis |
|---|---|---|
id | string (uuid) | oui |
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
label | string | oui |
isDefault | boolean | oui |
hasApiKey | boolean | oui |
apiKeyHint | string | null | oui |
baseUrl | string | null | oui |
enabledModels | string[] | null | oui |
updatedAt | string (date-time) | oui |
Même schéma que POST /api/v1/admin/llm/connections.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.connection_not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/admin/llm-providers
Décrire tous les fournisseurs d’IA
L’état de chaque fournisseur (configuré ou non, catalogue, connexions) et les défauts résolus, en un appel.
Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).
Réponses
200 — Les fournisseurs.
| Champ | Type | Requis |
|---|---|---|
providers | object[] | oui |
defaults | object | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"providers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"configured": { "type": "boolean" },
"hasApiKey": { "type": "boolean" },
"apiKeyHint": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"preset": {
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"defaultBaseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrlPolicy": { "type": "string", "enum": [ "fixed", "preset", "required" ] },
"apiKey": { "type": "string", "enum": [ "required", "optional" ] },
"jsonMode": {
"type": "string",
"enum": [ "tool", "json_schema", "json_object", "none" ]
},
"supportsModelDiscovery": { "type": "boolean" },
"supportsTools": { "type": "boolean" },
"supportsVision": { "type": "boolean" },
"docsUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"provider",
"defaultBaseUrl",
"baseUrlPolicy",
"apiKey",
"jsonMode",
"supportsModelDiscovery",
"supportsTools",
"supportsVision",
"docsUrl"
],
"additionalProperties": false
},
"models": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"inputUsdPerMTok": { "anyOf": [ { "type": "number" }, { "type": "null" } ] },
"outputUsdPerMTok": { "anyOf": [ { "type": "number" }, { "type": "null" } ] },
"retentionCovered": { "type": "boolean" },
"supportsTemperature": { "type": "boolean" },
"enabled": { "type": "boolean" }
},
"required": [
"id",
"inputUsdPerMTok",
"outputUsdPerMTok",
"retentionCovered",
"supportsTemperature",
"enabled"
],
"additionalProperties": false
}
},
"enabledModels": {
"anyOf": [
{ "type": "array", "items": { "type": "string" } },
{ "type": "null" }
]
},
"defaults": {
"type": "object",
"properties": {
"classify": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"compose": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"extract": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"general": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"analyzer": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "classify", "compose", "extract", "general", "analyzer" ],
"additionalProperties": false
},
"updatedAt": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
{ "type": "null" }
]
},
"connections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"label": { "type": "string" },
"isDefault": { "type": "boolean" },
"hasApiKey": { "type": "boolean" },
"apiKeyHint": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"enabledModels": {
"anyOf": [
{ "type": "array", "items": { "type": "string" } },
{ "type": "null" }
]
},
"updatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
}
},
"required": [
"id",
"provider",
"label",
"isDefault",
"hasApiKey",
"apiKeyHint",
"baseUrl",
"enabledModels",
"updatedAt"
],
"additionalProperties": false
}
}
},
"required": [
"provider",
"configured",
"hasApiKey",
"apiKeyHint",
"baseUrl",
"preset",
"models",
"enabledModels",
"defaults",
"updatedAt",
"connections"
],
"additionalProperties": false
}
},
"defaults": {
"type": "object",
"properties": {
"classify": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"compose": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"extract": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"general": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"analyzer": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"assistant": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [ "classify", "compose", "extract", "general", "analyzer", "assistant" ],
"additionalProperties": false
}
},
"required": [ "providers", "defaults" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
GET /api/v1/admin/llm-providers/{provider}
Décrire un fournisseur d’IA
Rendu même sans clé enregistrée (configured: false), catalogue et défauts compris.
Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
provider | chemin | string | oui |
Réponses
200 — L’état du fournisseur.
| Champ | Type | Requis |
|---|---|---|
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
configured | boolean | oui |
hasApiKey | boolean | oui |
apiKeyHint | string | null | oui |
baseUrl | string | null | oui |
preset | object | oui |
models | object[] | oui |
enabledModels | string[] | null | oui |
defaults | object | oui |
updatedAt | string (date-time) | null | oui |
connections | object[] | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"configured": { "type": "boolean" },
"hasApiKey": { "type": "boolean" },
"apiKeyHint": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"preset": {
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"defaultBaseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrlPolicy": { "type": "string", "enum": [ "fixed", "preset", "required" ] },
"apiKey": { "type": "string", "enum": [ "required", "optional" ] },
"jsonMode": {
"type": "string",
"enum": [ "tool", "json_schema", "json_object", "none" ]
},
"supportsModelDiscovery": { "type": "boolean" },
"supportsTools": { "type": "boolean" },
"supportsVision": { "type": "boolean" },
"docsUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"provider",
"defaultBaseUrl",
"baseUrlPolicy",
"apiKey",
"jsonMode",
"supportsModelDiscovery",
"supportsTools",
"supportsVision",
"docsUrl"
],
"additionalProperties": false
},
"models": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"inputUsdPerMTok": { "anyOf": [ { "type": "number" }, { "type": "null" } ] },
"outputUsdPerMTok": { "anyOf": [ { "type": "number" }, { "type": "null" } ] },
"retentionCovered": { "type": "boolean" },
"supportsTemperature": { "type": "boolean" },
"enabled": { "type": "boolean" }
},
"required": [
"id",
"inputUsdPerMTok",
"outputUsdPerMTok",
"retentionCovered",
"supportsTemperature",
"enabled"
],
"additionalProperties": false
}
},
"enabledModels": {
"anyOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "null" } ]
},
"defaults": {
"type": "object",
"properties": {
"classify": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"compose": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"extract": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"general": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"analyzer": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "classify", "compose", "extract", "general", "analyzer" ],
"additionalProperties": false
},
"updatedAt": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
{ "type": "null" }
]
},
"connections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"label": { "type": "string" },
"isDefault": { "type": "boolean" },
"hasApiKey": { "type": "boolean" },
"apiKeyHint": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"enabledModels": {
"anyOf": [
{ "type": "array", "items": { "type": "string" } },
{ "type": "null" }
]
},
"updatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
}
},
"required": [
"id",
"provider",
"label",
"isDefault",
"hasApiKey",
"apiKeyHint",
"baseUrl",
"enabledModels",
"updatedAt"
],
"additionalProperties": false
}
}
},
"required": [
"provider",
"configured",
"hasApiKey",
"apiKeyHint",
"baseUrl",
"preset",
"models",
"enabledModels",
"defaults",
"updatedAt",
"connections"
],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.unsupported_provider. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
PUT /api/v1/admin/llm-providers/{provider}
Configurer un fournisseur d’IA
Pose ou remplace la connexion par défaut du fournisseur. La clé est obligatoire à la première configuration et optionnelle ensuite (absente, elle est conservée). Journalisé dans l’audit, jamais avec la clé.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
provider | chemin | string | oui |
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
apiKey | string | non |
baseUrl | string (uri) | non |
withoutApiKey | boolean | non |
enabledModels | string[] | non |
Schéma JSON
json
{
"type": "object",
"properties": {
"apiKey": { "type": "string", "minLength": 1, "maxLength": 512 },
"baseUrl": { "type": "string", "maxLength": 2048, "format": "uri" },
"withoutApiKey": { "type": "boolean" },
"enabledModels": {
"minItems": 1,
"maxItems": 64,
"type": "array",
"items": { "type": "string", "minLength": 1, "maxLength": 128 }
}
}
}Réponses
200 — L’état du fournisseur.
| Champ | Type | Requis |
|---|---|---|
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
configured | boolean | oui |
hasApiKey | boolean | oui |
apiKeyHint | string | null | oui |
baseUrl | string | null | oui |
preset | object | oui |
models | object[] | oui |
enabledModels | string[] | null | oui |
defaults | object | oui |
updatedAt | string (date-time) | null | oui |
connections | object[] | oui |
Même schéma que GET /api/v1/admin/llm-providers/{provider}.
400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.unsupported_provider, request.bad_request, llm.encryption_disabled, llm.invalid_base_url, llm.api_key_required, llm.model_not_allowed. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
DELETE /api/v1/admin/llm-providers/{provider}
Retirer la clé d’un fournisseur d’IA
204 même si rien n’était enregistré. La ligne d’audit dit si quelque chose a réellement été retiré.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
provider | chemin | string | oui |
Réponses
204 — Retirée.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.unsupported_provider. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
POST /api/v1/admin/llm-providers/{provider}/test
Tester un fournisseur d’IA
Un vrai appel, minimal. Le verdict est dans le corps avec un 200 : une clé refusée est le résultat, pas une erreur de cette API. connectionId désigne la connexion à éprouver ; absent, celle par défaut.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
provider | chemin | string | oui |
connectionId | requête | string | non |
Réponses
200 — Le verdict.
| Champ | Type | Requis |
|---|---|---|
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
ok | boolean | oui |
model | string | oui |
latencyMs | integer | oui |
error | object | non |
Schéma JSON
json
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"ok": { "type": "boolean" },
"model": { "type": "string" },
"latencyMs": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"error": {
"type": "object",
"properties": { "code": { "type": "string" }, "message": { "type": "string" } },
"required": [ "code", "message" ],
"additionalProperties": false
}
},
"required": [ "provider", "ok", "model", "latencyMs" ],
"additionalProperties": false
}400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.unsupported_provider, llm.provider_not_configured, llm.connection_not_found, llm.connection_provider_mismatch. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/admin/llm/providers/{provider}/models
Découvrir les modèles qu’une clé voit
Le demande au fournisseur lui-même, avec la clé de l’instance (cache de dix minutes). 200 même en échec, comme le test. Restent en erreur HTTP un fournisseur inconnu, un qui ne liste pas ses modèles, l’absence de clé, et une connexion d’un autre fournisseur.
Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
provider | chemin | string | oui |
connectionId | requête | string | non |
Réponses
200 — Les modèles découverts.
| Champ | Type | Requis |
|---|---|---|
provider | "anthropic" | "openai" | "mistral" | "openrouter" | "ollama" | "openai_compatible" | oui |
ok | boolean | oui |
models | object[] | oui |
cached | boolean | oui |
fetchedAt | string (date-time) | null | oui |
error | object | non |
Schéma JSON
json
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"ok": { "type": "boolean" },
"models": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"label": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"contextLength": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"inputUsdPerMTok": { "anyOf": [ { "type": "number" }, { "type": "null" } ] },
"outputUsdPerMTok": { "anyOf": [ { "type": "number" }, { "type": "null" } ] },
"known": { "type": "boolean" }
},
"required": [
"id",
"label",
"contextLength",
"inputUsdPerMTok",
"outputUsdPerMTok",
"known"
],
"additionalProperties": false
}
},
"cached": { "type": "boolean" },
"fetchedAt": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
{ "type": "null" }
]
},
"error": {
"type": "object",
"properties": { "code": { "type": "string" }, "message": { "type": "string" } },
"required": [ "code", "message" ],
"additionalProperties": false
}
},
"required": [ "provider", "ok", "models", "cached", "fetchedAt" ],
"additionalProperties": false
}400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — llm.unsupported_provider, llm.discovery_not_supported, llm.provider_not_configured, llm.connection_provider_mismatch. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/admin/llm/defaults
Lire le routage d’IA par usage
Une ligne par créneau : le choix de l’administrateur, ce que l’usage obtiendra réellement, et si le choix est devenu inapplicable (clé retirée, modèle décoché).
Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).
Réponses
200 — Le routage.
| Champ | Type | Requis |
|---|---|---|
entries | object[] | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"purpose": {
"type": "string",
"enum": [
"default",
"classify",
"compose",
"extract",
"general",
"analyzer",
"assistant"
]
},
"override": {
"anyOf": [
{
"type": "object",
"properties": {
"purpose": {
"type": "string",
"enum": [
"default",
"classify",
"compose",
"extract",
"general",
"analyzer",
"assistant"
]
},
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": {
"anyOf": [
{ "type": "string", "minLength": 1, "maxLength": 128 },
{ "type": "null" }
]
},
"temperature": {
"anyOf": [
{ "type": "number", "minimum": 0, "maximum": 2 },
{ "type": "null" }
]
},
"maxOutputTokens": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 200000
},
{ "type": "null" }
]
},
"updatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
}
},
"required": [
"purpose",
"provider",
"model",
"temperature",
"maxOutputTokens",
"updatedAt"
],
"additionalProperties": false
},
{ "type": "null" }
]
},
"resolved": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" }
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"overrideUnavailable": { "type": "boolean" }
},
"required": [ "purpose", "override", "resolved", "overrideUnavailable" ],
"additionalProperties": false
}
}
},
"required": [ "entries" ],
"additionalProperties": false
}401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
PUT /api/v1/admin/llm/defaults
Régler le routage d’IA par usage
Partiel : les créneaux absents ne bougent pas ; provider: null efface la ligne. Un choix sur un fournisseur sans clé est accepté et signalé comme pas encore applicable. Journalisé dans l’audit.
Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).
Corps de la requête (application/json)
| Champ | Type | Requis |
|---|---|---|
defaults | object[] | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"defaults": {
"minItems": 1,
"maxItems": 7,
"type": "array",
"items": {
"type": "object",
"properties": {
"purpose": {
"type": "string",
"enum": [
"default",
"classify",
"compose",
"extract",
"general",
"analyzer",
"assistant"
]
},
"provider": {
"anyOf": [
{
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
{ "type": "null" }
]
},
"model": {
"anyOf": [
{ "type": "string", "minLength": 1, "maxLength": 128 },
{ "type": "null" }
]
},
"temperature": {
"anyOf": [
{ "type": "number", "minimum": 0, "maximum": 2 },
{ "type": "null" }
]
},
"maxOutputTokens": {
"anyOf": [
{ "type": "integer", "exclusiveMinimum": 0, "maximum": 200000 },
{ "type": "null" }
]
}
},
"required": [ "purpose", "provider", "model" ]
}
}
},
"required": [ "defaults" ]
}Réponses
200 — Le routage, après écriture.
| Champ | Type | Requis |
|---|---|---|
entries | object[] | oui |
Même schéma que GET /api/v1/admin/llm/defaults.
400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — request.bad_request. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.
GET /api/v1/admin/llm-usage
Lire le rapport d’usage de l’IA
Agrégats par jour, fournisseur, modèle et contexte sur [from, to). to vaut maintenant par défaut, from trente jours plus tôt ; la fenêtre ne dépasse pas un an. total.costUsd est null quand aucune ligne n’avait de tarif.
Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).
Paramètres
| Nom | Où | Type | Requis |
|---|---|---|---|
from | requête | string | non |
to | requête | string | non |
Réponses
200 — L’usage.
| Champ | Type | Requis |
|---|---|---|
from | string (date-time) | oui |
to | string (date-time) | oui |
rows | object[] | oui |
total | object | oui |
Schéma JSON
json
{
"type": "object",
"properties": {
"from": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
"to": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"day": { "type": "string" },
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" },
"context": {
"type": "string",
"enum": [ "execution", "eval", "analyzer", "assistant" ]
},
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"inputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"outputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"costUsd": { "anyOf": [ { "type": "number" }, { "type": "null" } ] }
},
"required": [
"day",
"provider",
"model",
"context",
"calls",
"inputTokens",
"outputTokens",
"costUsd"
],
"additionalProperties": false
}
},
"total": {
"type": "object",
"properties": {
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"inputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"outputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"costUsd": { "anyOf": [ { "type": "number" }, { "type": "null" } ] }
},
"required": [ "calls", "inputTokens", "outputTokens", "costUsd" ],
"additionalProperties": false
}
},
"required": [ "from", "to", "rows", "total" ],
"additionalProperties": false
}400 — La requête ne respecte pas son schéma.
401 — Aucune session ni clé d’API valide (auth.unauthenticated).
403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).
429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.
Codes d’erreur — request.bad_request. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.