API REST
Lisez les formulaires et les soumissions, déplacez les soumissions vers ou hors du spam et supprimez-les avec une clé secrète.
L'API REST permet à votre serveur de lire les formulaires et les soumissions, de déplacer les soumissions vers ou hors du spam, et de les supprimer. C'est du JSON en HTTPS à l'adresse https://ikiform.com/api/v1. Le document OpenAPI 3.1 se trouve à /api/v1/openapi.json.
/api/v1. Envoyez plutôt vers l'endpoint du formulaire avec une clé secrète ; voir Depuis un serveur.Clés API
Créez des clés dans le tableau de bord sous API keys. Une clé appartient à un seul espace de travail et ne voit que celui-ci. La clé complète n'est affichée qu'une fois ; Ikiform n'en stocke que le hachage.
| Type | Préfixe | Utilisation |
|---|---|---|
| Secrète | ik_sk_ | Pour les serveurs. Appelle l'API REST avec les portées choisies, et peut créer des soumissions. |
| Publiable | ik_pub_ | Pour les navigateurs. Peut seulement soumettre des formulaires, et uniquement depuis les domaines listés sur la clé. |
Portées
| Portée | Autorise |
|---|---|
forms:read | GET /forms, GET /forms/:formId |
submissions:read | GET /submissions, GET /submissions/:id |
submissions:write | DELETE /submissions/:id, POST /submissions/:id/spam et /not-spam, et l'envoi vers /f/:formId |
Authentification
Envoyez la clé secrète comme token Bearer. L'API fonctionne uniquement de serveur à serveur : elle n'envoie aucun en-tête CORS et répond aux preflights des navigateurs avec 405, donc une clé secrète ne peut jamais fonctionner depuis une page web.
curl https://ikiform.com/api/v1/forms \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"- Une clé absente, mal formée, inconnue, révoquée ou expirée reçoit
401 unauthorizedavecWWW-Authenticate: Bearer. - Une clé publiable reçoit
403 forbidden(Publishable keys can only submit forms.). Une clé sans la portée nécessaire reçoit403 forbiddenavec le nom de la portée dans le message. - Les réponses sont envoyées avec
Cache-Control: no-store.
Les exemples SDK ci-dessous partagent un même client :
import { createClient } from "@ikiform/sdk";
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });Compositeur de requête
curl "https://ikiform.com/api/v1/submissions?form_id=frm_xxxxxxxxxxxxxxxx&status=received&limit=50" \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Exécutez ceci depuis votre serveur. L'API REST refuse les requêtes venant du navigateur, donc cette page ne l'envoie jamais.
Endpoints
| Méthode | Chemin | Portée | Renvoie |
|---|---|---|---|
GET | /forms | forms:read | Lister les formulaires |
GET | /forms/:formId | forms:read | Récupérer un formulaire |
GET | /submissions | submissions:read | Lister les soumissions |
GET | /submissions/:id | submissions:read | Récupérer une soumission |
POST | /submissions/:id/spam | submissions:write | Marquer comme spam |
POST | /submissions/:id/not-spam | submissions:write | Marquer comme légitime |
DELETE | /submissions/:id | submissions:write | Supprimer une soumission |
GET | /openapi.json | Aucun | Le document OpenAPI |
GET | /health | Aucun | { "ok": true } |
Lister les formulaires
GET /forms avec la portée forms:read.
- Les plus récents en premier. Accepte
limit(1 à 100, 25 par défaut) etcursor.
curl "https://ikiform.com/api/v1/forms?limit=10" \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Récupérer un formulaire
GET /forms/:formId avec la portée forms:read.
- Un id de formulaire d'un autre espace de travail renvoie
404, exactement comme un id qui n'existe pas.
curl https://ikiform.com/api/v1/forms/frm_xxxxxxxxxxxxxxxx \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Lister les soumissions
GET /submissions avec la portée submissions:read.
| Paramètre | Valeurs | Par défaut |
|---|---|---|
form_id | Un id de formulaire | Tous les formulaires de l'espace de travail |
status | received ou spam | Les deux |
limit | 1 à 100 | 25 |
cursor | next_cursor de la page précédente | La première page |
- Les plus récentes en premier. Un
form_idd'un autre espace de travail renvoie une liste vide plutôt qu'une erreur, pour que les ids ne puissent pas être sondés.
curl "https://ikiform.com/api/v1/submissions?form_id=frm_xxxxxxxxxxxxxxxx&status=received&limit=50" \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Récupérer une soumission
GET /submissions/:id avec la portée submissions:read.
- Les ids d'un autre espace de travail renvoient
404, exactement comme des ids qui n'existent pas.
curl https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3 \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Marquer comme spam
POST /submissions/:id/spam avec la portée submissions:write.
- Déplace une soumission reçue vers le spam, diminue le
submission_countdu formulaire et annule ses livraisons de webhook en attente. - L'appeler sur une soumission déjà marquée comme spam la renvoie inchangée.
curl -X POST https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3/spam \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Marquer comme légitime
POST /submissions/:id/not-spam avec la portée submissions:write.
- La replace parmi les reçues, efface son score et ses raisons de spam, et envoie
submission.createdà chaque endpoint de webhook concerné. - L'appeler sur une soumission reçue la renvoie inchangée.
curl -X POST https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3/not-spam \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Supprimer une soumission
DELETE /submissions/:id avec la portée submissions:write.
- Supprime définitivement la soumission et ses livraisons de webhook. Impossible d'annuler. Une nouvelle suppression renvoie
404.
curl -X DELETE https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3 \
-H "Authorization: Bearer $IKIFORM_SECRET_KEY"Objets
Les objets sont du JSON en snake_case avec un champ object. Les horodatages sont en ISO 8601 UTC avec les millisecondes. Les ids de soumission sont triés par date (sub_ suivi de 26 caractères) ; les ids de formulaire sont aléatoires (frm_ suivi de 16 caractères).
| Champ du formulaire | Description |
|---|---|
status | active, paused ou disabled |
submission_count | Soumissions reçues, hors spam |
| Champ de la soumission | Description |
|---|---|
status | received ou spam |
fields | Les valeurs stockées |
meta | user_agent, origin, referrer, country, subject, reply_to. Chaque clé est présente et n'importe quelle valeur peut être null. Le hachage de l'IP n'est jamais renvoyé |
spam.score, spam.reasons | Le score et les raisons de spam, comme honeypot ou origin_mismatch |
Pagination
Les listes commencent par les plus récents et utilisent des curseurs opaques.
- Faites une requête sans curseur.
- Si
has_morevaut true, envoyeznext_cursordanscursoravec les mêmes filtres. - Arrêtez quand
next_cursorvautnull.
Les pages restent stables pendant l'arrivée de nouvelles soumissions : les nouvelles apparaissent sur la première page, jamais en double plus loin. Ne construisez pas et n'analysez pas les curseurs vous-même ; un curseur invalide renvoie 400 invalid_request.
for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx" })) {
console.log(submission.id, submission.fields);
}Erreurs
Les erreurs utilisent la même enveloppe que les soumissions de formulaire. Chaque réponse a un en-tête X-Request-Id, que les erreurs reprennent en request_id.
{
"ok": false,
"error": { "code": "forbidden", "message": "This API key is missing the forms:read scope." },
"request_id": "req_01k7v2c9t3e8m5q4x6z0a1b2c3"
}| Statut | Code | Quand |
|---|---|---|
| 400 | invalid_request | limit, status, form_id ou cursor est invalide ; le message indique lequel |
| 401 | unauthorized | Clé absente ou invalide |
| 403 | forbidden | Clé publiable, ou portée manquante |
| 404 | not_found | Route ou id inconnu, ou id d'un autre espace de travail |
| 405 | method_not_allowed | Un preflight de navigateur |
| 429 | rate_limited | Limite de débit par clé dépassée |
| 500 | server_error | Une erreur de notre côté ; indiquez le request_id |
Limite de débit
Chaque clé peut faire 100 requêtes par tranche de 60 secondes. Au-delà, l'API renvoie 429 rate_limited avec un en-tête Retry-After en secondes. Le SDK l'expose dans error.retryAfter.