Tout ce que fait le KIT, au même endroit
ForHosting KIT est un catalogue de 7447 tâches prêtes à l’emploi — convertir un document, lire une facture, transcrire un enregistrement, valider un IBAN, générer un QR code — réparties en 14 catégories. Vous les exécutez ici même, sur le web, ou vous les appelez depuis votre code avec un seul POST authentifié. Cette page est la référence complète de l’API : endpoints, modèle asynchrone, contrat de webhook, erreurs et tarifs.
Ce qu’est le KIT
Un catalogue de tâches, pas un modèle
Chaque capacité est une tâche : vous envoyez une entrée, vous obtenez un résultat. Ni tokens, ni fenêtre de contexte, ni prompt engineering. Une tâche a un prix publié, une unité documentée et une forme fixe.
Quatre façons d’en exécuter une. Web — chaque capacité a sa propre page et s’exécute dans le navigateur ; les gratuites ne quittent jamais votre appareil. API — un seul POST authentifié, documenté ci-dessous. E-mail et Telegram — envoyez la tâche à une adresse KIT. L’API est un canal, pas le produit.
Démarrage rapide
De rien à un résultat en trois appels
Créez un compte avec votre adresse e-mail et créditez du solde quand vous en avez besoin. Sans abonnement, sans rendez-vous commercial.
Obtenir une clé API
POST /signup avec votre adresse renvoie une clé qui commence par kit_live_. Elle ne s’affiche qu’une fois. Nous n’en conservons que le hachage SHA-256 : si vous la perdez, nous ne pouvons pas la retrouver — nous en émettons une nouvelle.
Choisir une capacité
GET /catalog les liste toutes les 7447, avec leur prix en vigueur et leur unité. Ou parcourez le catalogue au bas de cette page.
L’exécuter
Envoyez un POST à l’endpoint de la capacité. Vous recevez immédiatement un task_id et le résultat arrive sur votre webhook.
Authentification
Jeton Bearer, affiché une seule fois
Chaque requête à l’API porte Authorization: Bearer kit_live_…. Les clés comptent 48 caractères hexadécimaux après le préfixe.
Nous ne conservons que le hachage SHA-256 de votre clé. C’est délibéré : un vidage de la base de données ne remet vos identifiants à personne — mais cela veut dire aussi que nous ne pouvons sincèrement pas vous la renvoyer. Perdue ? Nous la révoquons et nous en émettons une autre.
Une mauvaise clé renvoie toujours 401, et ne dit jamais pourquoi. Révoquée, mal saisie ou jamais existé sont indiscernables ; c’est voulu : vous dire laquelle des trois, ce serait le dire aussi à un attaquant.
Le modèle asynchrone
Chaque tâche est asynchrone. Sans exception.
Vous envoyez la tâche en POST
Retour 202 avec un task_id et le statut queued, plus ce qu’elle coûtera. Le montant est bloqué, pas débité.
Elle s’exécute en bordure de réseau
Moins d’une seconde pour les tâches de calcul ; quelques secondes pour l’IA et le média.
Le résultat vient à vous
Il est envoyé en POST à votre webhook_url si vous en avez indiqué un. Sinon, GET /tasks/{id}/result. Les résultats sont conservés selon leur taille : de 168 h pour les petits (jusqu’à 1 Mo) à 6 h pour les plus volumineux.
Un échec ne coûte rien
Une tâche est tentée jusqu’à 3 fois au total, avec un délai croissant entre les tentatives. Si elle échoue malgré tout, le blocage est levé et vous n’êtes pas facturé. Jamais.
Référence de l’API
Tous les endpoints auxquels le KIT répond
Les routes ne portent aucun préfixe de version. /v1/* résout encore pour les anciens clients, mais ce n’est pas la forme canonique et un nouveau code ne devrait pas l’utiliser.
URL de base: https://api.kit.forhosting.com
| Méthode | Route | Auth | Ce qu’elle fait |
|---|---|---|---|
ANY |
/ |
Public | Index du service : version, nombre de capacités et la liste d’endpoints que l’API annonce sur elle-même. Sans clé, et elle répond à n’importe quelle méthode. |
POST |
/{alias} |
Clé API | Raccourci par capacité pour POST /tasks avec le type figé — par exemple POST /ocr/invoice. C’est la forme que montre chaque page de capacité. |
GET |
/account |
Clé API | Solde du compte : available_usd est le solde réel de votre portefeuille, plus held_usd. Lorsque le portefeuille est géré par l’espace client, balance.source vaut "portal" et balance_endpoint pointe vers la valeur en direct. |
POST |
/agent/ask |
Clé API Bientôt | Non implémenté — renvoie 501 avec une clé, 401 sans. L’assistant conversationnel se construit ailleurs ; pour trouver une capacité, utilisez POST /catalog/search. |
GET |
/catalog |
Public | Toutes les capacités avec leur prix et leur unité en vigueur. ?lang=en|es, ?q= pour filtrer, ?limit=, ?schema=1 pour le schéma d’entrée, et ?channel= pour obtenir le prix déjà ajusté à ce canal — demandez le canal sur lequel vous allez facturer, sinon vous afficherez un montant et en facturerez un autre. |
POST |
/catalog/search |
Public | {query} → les capacités qui correspondent, chacune avec son prix déjà rédigé. Sans clé. Le score se calcule par couverture de mots entiers avec un seuil : une requête qu’elle ne comprend pas ne renvoie rien plutôt que de deviner — c’est délibéré. |
POST |
/estimate |
Clé API | {type, input} → unités, prix et détail. Établit un devis sans exécuter. Lorsque la quantité réelle ne peut pas être connue à l’avance (le nombre de pages d’un PDF derrière une URL), la réponse le signale avec estimated: true. |
GET |
/mobile/bootstrap |
Public | Ce dont l’application mobile a besoin pour démarrer : catégories, libellés et les mêmes prix ajustés au canal. Sans clé. Ne fait pas partie du contrat public non plus, pour la même raison. |
GET |
/mobile/catalog |
Public | Projection du catalogue pour l’application mobile, avec les prix déjà ajustés au canal de l’app. Sans clé. Ne fait pas partie du contrat public : sa forme suit l’app et peut changer sans préavis — développez contre GET /catalog. |
GET |
/plans |
Public | Montants de rechargement : currency et topup (sku, default_amount, min_amount). Rien d’autre — il n’y a aucun forfait auquel s’abonner. |
POST |
/signup |
Public | {email} → 201 avec votre api_key, affichée une seule fois. 409 si l’e-mail existe déjà ; 429 au-delà de 10/h par IP. |
GET |
/tasks |
Clé API | Vos tâches. ?status=, ?limit= (25 par défaut, 100 au maximum). |
POST |
/tasks |
Clé API | {type, input, webhook_url?, max_cost_usd?} → 202. Vous êtes facturé sur l’unité réelle de la tâche — pages, minutes, images — mesurée pendant l’exécution, et non sur l’estimation préalable. max_cost_usd est un plafond ferme : si le coût réel le dépasse, la tâche échoue et rien n’est facturé. Envoyez Idempotency-Key pour que réessayer soit sans risque : un rejeu renvoie la tâche d’origine avec idempotent: true. |
DELETE |
/tasks/{id} |
Clé API | Annule une tâche en file d’attente et libère sa réservation. |
GET |
/tasks/{id} |
Clé API | État de la tâche. 10 lectures toutes les 10 secondes par tâche ; au-delà, 429 avec Retry-After: 1. Préférez le webhook. |
GET |
/tasks/{id}/events |
Clé API Bientôt | Non implémenté — renvoie 501. Le SSE arrivera ; utilisez le webhook. |
GET |
/tasks/{id}/result |
Clé API | Résultat JSON, ou le fichier en pièce jointe. 409 pas prêt, 410 expiré, 422 échoué. La conservation dépend de la taille du résultat : 168 h pour les petits, jusqu’à 6 h pour les très volumineux. |
POST |
/tasks/{id}/retry |
Clé API | Remet en file une tâche qui a échoué. |
POST |
/uploads |
Clé API | Envoyez un fichier local : corps binaire brut, avec le Content-Type du fichier. → 201 avec ref: "kit://upl_…", que vous placez ensuite là où irait une URL : {"input": {"pdf": "kit://upl_…"}}. Un même envoi peut alimenter plusieurs tâches. Les refs vivent 24 h. Maximum 100 MiB (104.9 MB) par envoi ; chaque capacité applique en plus sa propre limite. |
Webhooks
Livraison signée, et comment la vérifier
Indiquez webhook_url à la création de la tâche et nous y envoyons le résultat en POST dès qu’il est prêt. C’est la voie recommandée : elle coûte moins cher que l’interrogation et arrive plus tôt.
Vérifiez la signature avant d’accorder votre confiance au corps. Chaque livraison porte KIT-Signature: v1=<hex> et KIT-Timestamp: <secondes unix>. La signature est un HMAC-SHA256 calculé sur la chaîne <timestamp>.<corps brut> — l’horodatage et le point font partie de la charge signée, ce ne sont pas des décorations. Signez les octets bruts que vous avez reçus, pas un objet re-sérialisé.
La livraison est tentée jusqu’à 5 fois, avec un délai exponentiel. Un 4xx renvoyé par votre endpoint arrête les tentatives immédiatement — nous le lisons comme « votre gestionnaire est faux », pas comme « réessayez plus tard ». Seuls les 5xx et les erreurs réseau sont réessayés. Passé ce cap, la livraison est abandonnée et mise en file de rebut.
Ce que nous envoyons
{
"event": "task.completed",
"created_at": "2026-07-16T10:31:04.120Z",
"data": {
"task_id": "tsk_a1b2c3d4e5f6",
"type": "ocr.invoice",
"status": "done",
"units": 1,
"price_usd": 0.021,
"result_url": "https://api.kit.forhosting.com/tasks/tsk_a1b2c3d4e5f6/result"
}
}{
"event": "task.failed",
"created_at": "2026-07-16T10:31:04.120Z",
"data": {
"task_id": "tsk_a1b2c3d4e5f6",
"type": "ocr.invoice",
"status": "failed",
"error": {
"code": "engine_error",
"message": "Upstream timed out after 3 attempts."
},
"charged": false
}
}Vérifier la signature
const crypto = require("crypto");
// req.body tiene que ser el cuerpo CRUDO, no un objeto re-serializado.
function verify(rawBody, headers, secret) {
const sig = (headers["kit-signature"] || "").replace(/^v1=/, "");
const ts = headers["kit-timestamp"];
const mine = crypto.createHmac("sha256", secret)
.update(ts + "." + rawBody) // el timestamp va firmado
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(mine));
}import hmac, hashlib
def verify(raw_body: bytes, headers, secret: str) -> bool:
sig = headers["KIT-Signature"].removeprefix("v1=")
ts = headers["KIT-Timestamp"]
mine = hmac.new(secret.encode(),
f"{ts}.".encode() + raw_body, # el timestamp va firmado
hashlib.sha256).hexdigest()
return hmac.compare_digest(sig, mine)Erreurs
HTTP standard, slug lisible par machine
Chaque erreur porte dans le corps un slug error stable. Testez le slug, pas le message : les messages sont localisés et peuvent changer.
| HTTP | Erreur | Signification |
|---|---|---|
400 | flow_depth | Une capacité composée s’est imbriquée plus profondément que permis. Aplatissez les étapes. |
400 | invalid_amount | Le montant est absent, n’est pas un nombre, ou sort de la plage autorisée. |
400 | invalid_email | L’adresse e-mail est absente ou invalide. |
400 | invalid_input | L’entrée manque un champ requis ou n’a pas la forme attendue par cette tâche. |
400 | invalid_json | Le corps de la requête n’est pas un JSON valide. |
400 | missing_type | Champ « type » absent de la requête. Consultez GET /catalog. |
400 | unknown_op | Opération inconnue pour cette capacité. Vérifiez son nom dans le catalogue. |
400 | unsafe_url | L’URL pointe vers un endroit d’où nous ne téléchargerons pas : une adresse interne ou non publique. |
401 | auth_required | Cette étape exige un compte identifié et la requête n’en fournit aucun. |
401 | no_key | La requête ne porte pas de clé API, ou le compte n’en a aucune active. |
401 | unauthorized | Clé API absente ou invalide : vérifiez l’en-tête Authorization. |
402 | account_suspended | Votre compte est suspendu, en général à cause du plafond de dépense. Écrivez-nous pour le réactiver. |
402 | insufficient_balance | Solde insuffisant : rechargez votre compte pour lancer cette tâche. |
402 | max_cost_exceeded | La tâche a coûté plus que le max_cost_usd que vous avez fixé. Rien n’a été facturé. |
403 | forbidden | La crédential est valide mais n’a pas le droit de faire cela. |
404 | input_not_found | Cette référence kit:// n’existe pas. Renvoyez le fichier avec POST /uploads. |
404 | not_found | Aucune tâche ni ressource à ce chemin. |
404 | unknown_type | Type de tâche inconnu : vérifiez le champ type de votre requête. |
409 | alias_taken | Cet alias d’e-mail entrant appartient à quelqu’un d’autre. Choisissez-en un autre. |
409 | already_accepted | Cette acceptation a déjà servi. Chacune ne vaut qu’une seule fois. |
409 | email_taken | Un compte existe déjà avec cette adresse e-mail. |
409 | need_lease | Un autre worker exécute déjà cette tâche. Attendez qu’il termine. |
409 | not_cancellable | La tâche n’est plus en file d’attente, elle ne peut donc pas être annulée. Seules les tâches en attente le peuvent. |
409 | not_ready | La tâche n’est pas encore terminée : interrogez son statut ou attendez le webhook. |
409 | not_retryable | Seules les tâches en échec peuvent être relancées. Celle-ci est dans un autre état. |
410 | expired | La fenêtre de conservation du résultat est écoulée : il n’est plus stocké. |
410 | input_expired | Cette référence kit:// a expiré. Les envois durent 24 h ; renvoyez le fichier. |
410 | quote_expired | Le devis a dépassé sa fenêtre de validité. Demandez-en un nouveau. |
413 | input_too_large | Entrée trop volumineuse : consultez la limite de taille de cette capacité. |
413 | resolution_too_high | L’image ou la vidéo dépasse la résolution acceptée par cette capacité. |
422 | conversion_failed | Le fichier n’a pas pu être converti. C’est généralement un format corrompu ou inattendu. |
422 | engine_error | Le moteur a échoué à toutes les tentatives. La réservation a été libérée : rien ne vous est facturé. |
422 | needs_rework | Le résultat n’a pas passé son propre contrôle qualité : il n’est pas livré, et pas facturé. |
429 | rate_limited | Trop de requêtes : ralentissez la cadence, puis réessayez. |
500 | lease_error | La tâche n’a pas pu être prise en charge pour exécution. Elle retourne en file. |
500 | ledger_error | Le solde n’a pu être ni réservé ni débité. Réessayez. |
500 | no_hold | La tâche n’a aucune réservation à solder. Cela ne devrait pas arriver ; si c’est le cas, dites-le-nous. |
500 | no_result | La tâche s’est terminée sans produire de résultat. |
501 | coming_soon | Cette capacité arrive bientôt : elle n’accepte pas encore de tâches. |
501 | mail_not_configured | Cette capacité envoie des e-mails et le compte n’a pas encore d’expéditeur configuré. |
501 | not_implemented | Ce point d’accès ou cette capacité n’est pas encore disponible. |
501 | tickets_not_configured | L’intégration des tickets n’est pas configurée pour ce compte. |
501 | unsupported | Cette opération n’est pas encore prise en charge (par exemple, les flows ne peuvent pas être estimés). |
502 | model_output_invalid | Le modèle a renvoyé quelque chose qui ne correspond pas à la sortie déclarée. Non facturé. |
502 | tickets_unreachable | Le système de tickets n’a pas répondu. Rien n’a été facturé ; réessayez. |
503 | all_busy | Tous les workers de cette capacité sont occupés. Réessayez sous peu. |
Tarifs
Publiés, par tâche, sans crédits
Ne payez que ce que vous utilisez. Créditez du solde sur votre compte (dès $10.00) — il n’expire jamais — et chaque tâche s’y règle à son prix affiché par tâche. De vrais dollars, pas des points.
Chaque tâche coûte un tarif de base plus un tarif par unité, tous deux publiés sur la page de la capacité et dans le catalogue ci-dessous — dès $0.002 par appel. POST /estimate chiffre une tâche sans l’exécuter, et max_cost_usd sur une tâche la refuse si elle devait coûter plus que ce que vous avez annoncé.
Une tâche en échec n’est jamais facturée. Les capacités gratuites s’exécutent dans votre navigateur et ne coûtent rigoureusement rien.
Limites
Ce que le service applique
Trois plafonds, comptés séparément. Par compte : 600 requêtes par minute au total, et 60 envois de fichiers par minute. Par tâche : 10 lectures d’état toutes les 10 secondes — au-delà de l’un d’eux, vous recevez 429 avec Retry-After: 1. Utilisez le webhook plutôt que l’interrogation : il coûte moins cher et arrive plus tôt. Les résultats sont conservés selon leur taille : 168 h jusqu’à 1 Mo, et 6 h pour les très volumineux. GET /tasks en renvoie 25 par défaut, 100 au maximum. La création de compte est limitée à 10 comptes par heure et par IP.
Catalogue des capacités
Les 7447, à parcourir par catégorie
Chaque capacité a sa propre page, où vous pouvez l’exécuter, voir un exemple réel et le prix publié — celui-là même que cette API facture. Ouvrez le catalogue complet, ou allez directement à une catégorie.
Aucune garantie
Ce que nous ne promettons pas
Le KIT est fourni « en l’état » : aucune garantie, aucun engagement de disponibilité, aucun SLA (une infrastructure dédiée avec SLA est une option payante) et aucune assistance garantie. Voir les Conditions pour la clause KIT complète.