Votre premier appel
L'API Ultineo Reasoning est une API JSON sur HTTPS. Vous vous authentifiez avec une clé API de projet, vous appelez un chemin sous /v1/, et vous lisez le résultat dans une enveloppe de réponse unique. Tout ce qu'une clé peut atteindre appartient au seul projet dans lequel elle a été créée. Créez d'abord une clé depuis l'espace de travail, comme décrit dans Clés API du projet, puis revenez ici.
Adresse de base
Chaque requête est adressée à l'hôte API de ce projet :
https://api.think.ultineo.com Seul HTTPS est servi. Une requête en http:// reçoit une redirection 301 vers le même chemin en https://, et chaque réponse HTTPS porte un en-tête Strict-Transport-Security.
Important — Votre clé circule dans un en-tête de requête : une seule tentative en clair la divulgue entièrement. Appelez toujours l'URL
https://directement plutôt que de compter sur la redirection.
Il existe un appel anonyme qui permet de vérifier que l'hôte répond :
curl https://api.think.ultineo.com/health {
"code": 200,
"title": "OK",
"response": "api gateway"
} S'authentifier
Envoyez votre clé comme jeton Bearer à chaque appel :
| En-tête | Valeur |
|---|---|
Authorization | Bearer sk-project-… |
Content-Type | application/json (uniquement lorsque vous envoyez un corps) |
C'est la clé qui délimite le projet : elle est rattachée à un consommateur et à un projet, et chaque requête exécutée par l'API est filtrée sur ce couple. Une clé ne peut jamais lire ni modifier les données d'un autre projet, quoi que vous mettiez dans l'URL.
Seule l'empreinte SHA-256 de votre clé est conservée : une clé perdue ne peut pas être retrouvée, supprimez-la et créez-en une nouvelle. Une clé possède également un statut et une date d'expiration facultative : une clé désactivée et une clé expirée sont toutes deux refusées.
Passer l'appel
Celui-ci lit le projet auquel la clé appartient :
curl https://api.think.ultineo.com/v1/project \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "proj_3f6c1d90ab77e2415c08",
"object": "project",
"name": "Acme",
"description": "Acme's reasoning workspace",
"country": "us",
"default_locale": "eng",
"is_verified": true,
"team_total": 4,
"status": "activated",
"created_at": 1751328000,
"updated_at": 1754205600
}
} L'enveloppe de réponse
Chaque appel répond avec les mêmes trois clés, en cas de succès comme en cas d'échec. Lisez le code de statut HTTP, puis lisez response.
| Champ | Type | Description |
|---|---|---|
code | entier | Le code de statut HTTP, répété dans le corps. |
title | chaîne | L'intitulé court du statut, par exemple OK ou Not Found. |
response | objet, tableau ou chaîne | Le résultat en cas de succès ; un message explicatif en cas d'échec. |
Un appel qui renvoie un seul objet place cet objet directement dans response, avec un champ object qui nomme son type. Un appel qui renvoie une collection encapsule ses lignes :
{
"code": 200,
"title": "OK",
"response": {
"object": "list",
"data": [],
"total": 0
}
} total compte toutes les lignes correspondantes, et non le nombre de lignes renvoyées dans data : servez-vous en pour piloter la pagination.
Note —
GET /v1/catalog/publicest la seule exception : il ne demande aucune clé et répond{"ok": true, "data": [...]}au lieu de l'enveloppe. Voir Catalogue.
Deux formes d'URL
Les appels se répartissent en deux familles, et le chemin vous indique laquelle vous appelez.
| Forme | Exemple | Utilisée par |
|---|---|---|
/v1/<ressource> | /v1/project | Les ressources de projet : consumer, event, feedback, file, key, project, team, usage. |
/v1/<module>/<action> | /v1/app/list | Les ressources de module : app, catalog, run, run-usage. |
Les deux familles acceptent un identifiant en dernier segment de chemin lorsque l'appel porte sur un seul enregistrement : /v1/team/pjin_… et /v1/run/detail/runi_….
Chaque identifiant est une chaîne opaque préfixée — proj_ pour un projet, mapp_ pour une application, runi_ pour une exécution — et il faut la traiter comme une valeur opaque plutôt que de l'analyser.
Portées
Une clé porte une liste de portées, et chaque appel en exige une. La grammaire comporte trois formes :
| Portée | Accorde |
|---|---|
* | Toutes les actions sur toutes les ressources. |
<ressource>:* | Toutes les actions sur cette seule ressource, par exemple team:*. |
<ressource>:<action> | Une action sur une ressource, par exemple team:read. |
La lecture exige l'action :read, et créer, modifier ou supprimer exige :write. Chaque sujet de cette référence nomme la portée qu'exigent ses appels. Appelez GET /v1/key/current pour voir les portées que votre clé détient réellement. Un appel dont la portée est insuffisante est refusé par un 403 accompagné d'un message nommant ce qui manquait.
Pagination
Les collections de module acceptent deux paramètres d'URL :
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
limit | entier | 50 | Nombre de lignes à renvoyer, de 1 à 100. Une valeur hors de cet intervalle retombe sur le défaut, et toute valeur supérieure à 100 est ramenée à 100. |
offset | entier | 0 | Nombre de lignes à ignorer. Une valeur négative est traitée comme 0. |
Les collections de projet n'acceptent aucun paramètre : elles renvoient les 100 lignes les plus récentes, avec le décompte réel dans total.
Dates et valeurs vides
Chaque horodatage est un nombre entier de secondes depuis l'époque Unix, en UTC. Un horodatage qui n'a pas encore eu lieu vaut null plutôt que 0 : ainsi "expires_at": null signifie que la clé n'expire jamais. Un champ texte qui n'a jamais été renseigné vaut une chaîne vide plutôt que null.
Corps de requête
Envoyez les corps de POST et de PATCH sous forme d'objet JSON avec Content-Type: application/json. Un corps qui n'est pas du JSON valide, ou qui n'est pas un objet JSON, est refusé par un 400 accompagné du message Invalid JSON. Un corps de plus de 200 000 octets est refusé par un 413.
Un PATCH ne touche que les champs que vous envoyez. N'envoyer aucun champ reconnu est une erreur plutôt qu'un succès silencieux : un 200 signifie donc que votre modification a bien été appliquée.