API Galet
Les routes publiques de Galet, générées depuis le code.
Les routes publiques de Galet. La collecte s'authentifie par la clé du canal ; la lecture par un jeton Authorization: Bearer. Les erreurs ont la forme { error, code }.
Pour essayer les routes depuis le navigateur, ouvrez la référence interactive. La spécification OpenAPI complète est publiée sur /openapi.json : importez-la dans Postman, Insomnia ou un générateur de client.
POST /v1/reports
Envoyer un retour depuis un serveur.
Crée un retour sur le canal API d'une app. À appeler depuis un serveur, jamais depuis un navigateur : quiconque connaît la clé peut envoyer des retours sur ce canal. Les URL autorisées de l'app ne s'appliquent pas à ce canal. Ni capture, ni replay, ni conversation : les champs inconnus sont ignorés. Le quota de feedbacks du plan s'applique. POST /v1/ingest, l'ancien nom de cette route, reste accepté.
Paramètres
| Nom | Où | Requis | Description |
|---|---|---|---|
idempotency-key | en-tête | non | Facultatif. Une valeur unique par retour (un UUID, par exemple). Une nouvelle tentative avec la même clé et le même corps renvoie la première réponse au lieu de créer un doublon, pendant 24 heures. La réponse rejouée porte l'en-tête Idempotent-Replayed: true. |
Corps
| Champ | Type | Requis | Description |
|---|---|---|---|
publicKey | string | oui | Clé du canal API de l'app. |
message | string | oui | Le texte du retour, 10000 caractères au plus. |
kind | problem, idea, praise, issue, bug, greeting | oui | Type du retour : problem, idea ou praise. issue, bug et greeting sont acceptés pour compatibilité. |
title | string | non | Un titre ; sinon Galet AI le rédige. |
observed | string | non | Ce qui s'est passé. |
expected | string | non | Ce qui était attendu. |
url | string | non | L'adresse concernée, gardée comme contexte. |
user | object | non | La personne qui a écrit. |
user.id | string | non | Identifiant dans votre app. |
user.email | string | non | Ignoré s'il n'a pas la forme d'un e-mail. |
user.name | string | non | Nom affiché. |
qualify | boolean | non | true : Galet AI pose d'abord les questions qui manquent (voir POST /v1/reports/{id}/answers). Le retour est enregistré quand il est assez précis. |
curl -X POST https://api.galet.dev/v1/reports \
-H "Content-Type: application/json" \
-d '{
"publicKey": "pk_live_3f9c…",
"message": "Export CSV vide",
"kind": "problem",
"url": "https://app.acme.com/exports",
"user": {
"email": "lea@acme.com"
}
}'Réponses
| Code HTTP | Description |
|---|---|
| 200 | Avec qualify : une question à poser, ou la fin sans enregistrement. |
| 201 | Retour créé. Avec qualify, quand il était déjà assez précis, la réponse porte aussi id et status: "ready". |
| 400 | invalid_json : corps illisible. invalid_ingest : champ manquant ou invalide. invalid_idempotency_key : clé vide ou trop longue. |
| 403 | channel_mismatch : la clé n'est ni celle d'un canal API ni celle d'un formulaire. channel_inactive : canal désactivé. |
| 404 | unknown_app : clé inconnue. |
| 409 | idempotency_in_progress : une requête avec la même Idempotency-Key est encore en cours. |
| 413 | message_too_long : message trop long. payload_too_large : corps de plus de 256 Ko. |
| 422 | idempotency_key_reused : la même Idempotency-Key a servi pour un autre corps. |
| 429 | rate_limited : plus de 120 requêtes par minute depuis la même adresse IP. |
| 502 | qualification_failed : Galet AI n'a pas répondu ; renvoyez le retour sans qualify. |
Corps de la réponse 200 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
id | string | oui | Identifiant de la qualification, valable 15 minutes après la dernière réponse. |
status | ask, answer, drop, restart, resolved | oui | ask : répondre à questions. answer : Galet AI répond depuis le centre d'aide ; questions demande si la réponse suffit, et sinon la qualification continue. resolved : la réponse a suffi, rien n'est enregistré. drop : hors sujet, rien n'est enregistré. restart : la personne a changé de sujet ; rien n'est enregistré, recommencez avec un nouveau retour. |
questions | objet[] | non | |
questions[].id | string | oui | |
questions[].prompt | string | oui | La question, à afficher telle quelle. |
questions[].mode | text, single, multi, yes_no, scale | oui | text : réponse libre. single, yes_no, scale : un choix. multi : un ou plusieurs choix. |
questions[].choices | object[] | non | |
questions[].choices[].id | string | oui | |
questions[].choices[].label | string | oui | |
questions[].allowTextFallback | boolean | non | Une réponse libre est aussi acceptée. |
source | object | non | answer : la page d'aide d'où vient la réponse. |
source.title | string | oui | |
source.url | string | oui | |
message | string | non | drop, restart et resolved : le message à afficher. |
Corps de la réponse 201 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
ok | true | oui | |
ticketId | string | oui | Identifiant du feedback créé. |
merged | boolean | oui | false à la création : le regroupement avec un feedback existant a lieu ensuite, en arrière-plan. |
statusId | string | non | Identifiant de suivi du retour. |
statusToken | string | non | Jeton qui donne accès à la page de suivi. |
statusUrl | string | non | Page de suivi du retour, à transmettre à la personne qui a écrit. |
id | string | non | Identifiant de la qualification. |
status | ready | non |
POST /v1/reports/{id}/answers
Répondre à une question de qualification.
Envoie la réponse de la personne à la question en attente. La réponse est soit la question suivante (200), soit le retour enregistré (201).
Paramètres
| Nom | Où | Requis | Description |
|---|---|---|---|
id | chemin | oui | L'id renvoyé par l'étape précédente. |
Corps
| Champ | Type | Requis | Description |
|---|---|---|---|
publicKey | string | oui | La clé utilisée pour créer le retour. |
text | string | non | Réponse libre. |
choiceIds | string[] | non | Identifiants des choix retenus parmi questions[].choices. |
curl -X POST https://api.galet.dev/v1/reports/{id}/answers \
-H "Content-Type: application/json" \
-d '{
"publicKey": "…"
}'Réponses
| Code HTTP | Description |
|---|---|
| 200 | Question suivante, ou fin sans enregistrement. |
| 201 | Retour qualifié et enregistré. |
| 400 | invalid_json, invalid_answer : corps invalide. missing_answer : ni text ni choiceIds. |
| 404 | qualification_not_found : identifiant inconnu, autre clé, ou qualification expirée. |
| 429 | rate_limited : trop de requêtes. |
| 502 | qualification_failed : Galet AI n'a pas répondu. |
Corps de la réponse 200 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
id | string | oui | Identifiant de la qualification, valable 15 minutes après la dernière réponse. |
status | ask, answer, drop, restart, resolved | oui | ask : répondre à questions. answer : Galet AI répond depuis le centre d'aide ; questions demande si la réponse suffit, et sinon la qualification continue. resolved : la réponse a suffi, rien n'est enregistré. drop : hors sujet, rien n'est enregistré. restart : la personne a changé de sujet ; rien n'est enregistré, recommencez avec un nouveau retour. |
questions | objet[] | non | |
questions[].id | string | oui | |
questions[].prompt | string | oui | La question, à afficher telle quelle. |
questions[].mode | text, single, multi, yes_no, scale | oui | text : réponse libre. single, yes_no, scale : un choix. multi : un ou plusieurs choix. |
questions[].choices | object[] | non | |
questions[].choices[].id | string | oui | |
questions[].choices[].label | string | oui | |
questions[].allowTextFallback | boolean | non | Une réponse libre est aussi acceptée. |
source | object | non | answer : la page d'aide d'où vient la réponse. |
source.title | string | oui | |
source.url | string | oui | |
message | string | non | drop, restart et resolved : le message à afficher. |
Corps de la réponse 201 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
ok | true | oui | |
ticketId | string | oui | Identifiant du feedback créé. |
merged | boolean | oui | false à la création : le regroupement avec un feedback existant a lieu ensuite, en arrière-plan. |
statusId | string | non | Identifiant de suivi du retour. |
statusToken | string | non | Jeton qui donne accès à la page de suivi. |
statusUrl | string | non | Page de suivi du retour, à transmettre à la personne qui a écrit. |
id | string | oui | Identifiant de la qualification. |
status | ready | oui |
GET /v1/feedbacks
Lister les feedbacks.
Les feedbacks de l'organisation, du plus récent au plus ancien, filtrés côté serveur et paginés par curseur.
Paramètres
| Nom | Où | Requis | Description |
|---|---|---|---|
status | requête | non | open (défaut), closed, all ou un statut précis. |
kind | requête | non | problem, idea, praise |
severity | requête | non | P0, P1, P2, P3 |
appId | requête | non | string |
featureId | requête | non | string |
query | requête | non | Texte cherché dans la clé, le titre, le résumé et les retours. |
limit | requête | non | 20 par défaut, 100 au plus. |
cursor | requête | non | Le nextCursor de la page précédente. |
curl https://api.galet.dev/v1/feedbacks \
-H "Authorization: Bearer $GALET_TOKEN"Réponses
| Code HTTP | Description |
|---|---|
| 200 | Une page. |
| 400 | invalid_query : filtre inconnu ou invalide. invalid_cursor : curseur illisible. |
| 401 | unauthorized : jeton absent. invalid_token : jeton inconnu, expiré ou révoqué. |
| 403 | insufficient_scope : le jeton n'a pas le scope feedbacks:read. |
Corps de la réponse 200 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
data | objet[] | oui | |
data[].key | string | oui | Clé lisible. |
data[].id | string | oui | |
data[].title | string | oui | |
data[].kind | problem, idea, praise | oui | |
data[].severity | P0, P1, P2, P3 | non | |
data[].status | triage, prioritized, in_development, fixed, delivered, dismissed | oui | |
data[].app | object | oui | |
data[].app.id | string | oui | |
data[].app.name | string | non | |
data[].feature | object | non | La fonctionnalité rattachée, avec son chemin dans la carte. |
data[].feature.id | string | oui | |
data[].feature.path | string | oui | |
data[].reports | integer | oui | Nombre de retours regroupés. |
data[].createdAt | string | oui | ISO 8601. |
data[].lastActivityAt | string | oui | Dernier retour reçu, ISO 8601. |
data[].trackerIssue | string | non | Clé du ticket Jira ou Linear lié. |
data[].url | string | oui | Le feedback dans Galet. |
nextCursor | string | null | oui | À passer en cursor pour la page suivante ; null à la dernière. |
GET /v1/feedbacks/{key}
Lire un feedback.
Un feedback, ses retours et, avec Silex, le contexte complet pour le corriger.
Paramètres
| Nom | Où | Requis | Description |
|---|---|---|---|
key | chemin | oui | Clé lisible (FIF-12) ou identifiant. |
curl https://api.galet.dev/v1/feedbacks/:key \
-H "Authorization: Bearer $GALET_TOKEN"Réponses
| Code HTTP | Description |
|---|---|
| 200 | Le feedback. |
| 401 | unauthorized : jeton absent. invalid_token : jeton inconnu, expiré ou révoqué. |
| 403 | insufficient_scope : le jeton n'a pas le scope feedbacks:read. |
| 404 | not_found : aucun feedback avec cette clé dans l'organisation. |
Corps de la réponse 200 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
key | string | oui | Clé lisible. |
id | string | oui | |
title | string | oui | |
kind | problem, idea, praise | oui | |
severity | P0, P1, P2, P3 | non | |
status | triage, prioritized, in_development, fixed, delivered, dismissed | oui | |
app | object | oui | |
app.id | string | oui | |
app.name | string | non | |
feature | object | non | La fonctionnalité rattachée, avec son chemin dans la carte. |
feature.id | string | oui | |
feature.path | string | oui | |
reports | integer | oui | Nombre de retours regroupés. |
createdAt | string | oui | ISO 8601. |
lastActivityAt | string | oui | Dernier retour reçu, ISO 8601. |
url | string | oui | Le feedback dans Galet. |
nature | string | non | |
summary | string | non | |
observed | string | non | |
expected | string | non | |
dueAt | string | non | |
owner | string | non | E-mail du responsable. |
trackerIssue | object | non | |
trackerIssue.key | string | oui | |
trackerIssue.provider | string | oui | |
trackerIssue.status | string | oui | |
trackerIssue.url | string | non | |
reportList | object[] | oui | |
reportList[].source | string | oui | widget, slack, api, form… |
reportList[].author | string | non | |
reportList[].at | string | oui | ISO 8601. |
reportList[].text | string | oui | |
fullContext | object | null | oui | Avec Silex (plans Croissance et Entreprise) : diagnostic, fonctionnalité et fichiers rattachés, conversation de qualification, page, navigateur, console, erreurs réseau, capture et replay (liens signés, valables peu de temps). null sans Silex. |
PATCH /v1/feedbacks/{key}
Changer le statut d'un feedback.
Même effet que depuis l'inbox, au nom de la personne qui a autorisé le jeton : le ticket Jira ou Linear lié suit, et delivered prévient les personnes qui suivent le feedback.
Paramètres
| Nom | Où | Requis | Description |
|---|---|---|---|
key | chemin | oui | Clé lisible (FIF-12) ou identifiant. |
Corps
| Champ | Type | Requis | Description |
|---|---|---|---|
status | triage, prioritized, in_development, fixed, delivered, dismissed | oui | triage, prioritized, in_development, fixed, delivered (prévient les personnes qui suivent le feedback) ou dismissed. |
comment | string | non | Ajouté au feedback ; pour dismissed, la raison. |
curl -X PATCH https://api.galet.dev/v1/feedbacks/{key} \
-H "Content-Type: application/json" \
-d '{
"status": "triage"
}'Réponses
| Code HTTP | Description |
|---|---|
| 200 | Le feedback à jour. |
| 400 | invalid_json, invalid_body : corps invalide. |
| 401 | unauthorized : jeton absent. invalid_token : jeton inconnu, expiré ou révoqué. |
| 403 | insufficient_scope : le jeton n'a pas le scope feedbacks:write. forbidden : le rôle Lecteur ne peut pas modifier. |
| 404 | not_found : aucun feedback avec cette clé dans l'organisation. |
Corps de la réponse 200 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
key | string | oui | Clé lisible. |
id | string | oui | |
title | string | oui | |
kind | problem, idea, praise | oui | |
severity | P0, P1, P2, P3 | non | |
status | triage, prioritized, in_development, fixed, delivered, dismissed | oui | |
app | object | oui | |
app.id | string | oui | |
app.name | string | non | |
feature | object | non | La fonctionnalité rattachée, avec son chemin dans la carte. |
feature.id | string | oui | |
feature.path | string | oui | |
reports | integer | oui | Nombre de retours regroupés. |
createdAt | string | oui | ISO 8601. |
lastActivityAt | string | oui | Dernier retour reçu, ISO 8601. |
url | string | oui | Le feedback dans Galet. |
nature | string | non | |
summary | string | non | |
observed | string | non | |
expected | string | non | |
dueAt | string | non | |
owner | string | non | E-mail du responsable. |
trackerIssue | object | non | |
trackerIssue.key | string | oui | |
trackerIssue.provider | string | oui | |
trackerIssue.status | string | oui | |
trackerIssue.url | string | non | |
reportList | object[] | oui | |
reportList[].source | string | oui | widget, slack, api, form… |
reportList[].author | string | non | |
reportList[].at | string | oui | ISO 8601. |
reportList[].text | string | oui | |
fullContext | object | null | oui | Avec Silex (plans Croissance et Entreprise) : diagnostic, fonctionnalité et fichiers rattachés, conversation de qualification, page, navigateur, console, erreurs réseau, capture et replay (liens signés, valables peu de temps). null sans Silex. |
GET /v1/apps
Lister les apps.
curl https://api.galet.dev/v1/apps \
-H "Authorization: Bearer $GALET_TOKEN"Réponses
| Code HTTP | Description |
|---|---|
| 200 | Les apps de l'organisation. |
| 401 | unauthorized : jeton absent. invalid_token : jeton inconnu, expiré ou révoqué. |
| 403 | insufficient_scope : le jeton n'a pas le scope feedbacks:read. |
Corps de la réponse 200 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
data | objet[] | oui | |
data[].id | string | oui | |
data[].name | string | oui | |
data[].kind | string | oui | |
data[].description | string | non | |
data[].version | string | non |
GET /v1/apps/{id}/features
Lister les fonctionnalités d'une app.
La carte des fonctionnalités, à plat, avec le nombre de feedbacks ouverts sur chacune.
Paramètres
| Nom | Où | Requis | Description |
|---|---|---|---|
id | chemin | oui | string |
curl https://api.galet.dev/v1/apps/:id/features \
-H "Authorization: Bearer $GALET_TOKEN"Réponses
| Code HTTP | Description |
|---|---|
| 200 | Les fonctionnalités. |
| 401 | unauthorized : jeton absent. invalid_token : jeton inconnu, expiré ou révoqué. |
| 403 | insufficient_scope : le jeton n'a pas le scope feedbacks:read. |
| 404 | not_found : app inconnue. |
Corps de la réponse 200 :
| Champ | Type | Toujours présent | Description |
|---|---|---|---|
data | objet[] | oui | |
data[].id | string | oui | |
data[].name | string | oui | |
data[].path | string | oui | |
data[].kind | string | non | |
data[].severityFloor | string | non | |
data[].cues | string[] | non | |
data[].code | objet[] | non | Fichiers de code rattachés. |
data[].openFeedbacks | integer | oui |