ForHosting KIT

Tutto quello che fa il KIT, in un posto solo

ForHosting KIT è un catalogo di 7447 attività pronte all’uso — converti un documento, leggi una fattura, trascrivi un audio, verifichi un IBAN, generi un codice QR — in 14 categorie. Le esegui qui dal browser, oppure le chiami dal tuo codice con un solo POST autenticato. Questa pagina è il riferimento API completo: endpoint, modello asincrono, contratto dei webhook, errori e prezzi.

Usalo da WebAPIEmailTelegramApp presto

Cos’è il KIT

Un catalogo di attività, non un modello

Ogni strumento è un’attività: mandi un input, ricevi un risultato. Niente token, niente finestre di contesto, niente prompt da ingegnerizzare. Un’attività ha un prezzo pubblicato, un’unità documentata e una forma fissa.

Quattro modi per eseguirne una. Web — ogni strumento ha la sua pagina e gira nel browser; quelli gratis non escono mai dal tuo dispositivo. API — un solo POST autenticato, documentato qui sotto. Email e Telegram — mandi l’attività a un indirizzo del KIT. L’API è un canale, non il prodotto.

Per iniziare

Da zero a un risultato in tre chiamate

Crei un account, ricevi la chiave, esegui un’attività. Niente telefonate commerciali, niente lista d’attesa.

1

Ottieni una chiave API

POST /signup con la tua email restituisce una chiave che inizia con kit_live_. La vedi una volta sola. Ne conserviamo solo l’hash SHA-256, quindi se la perdi non possiamo recuperarla — te ne emettiamo una nuova.

2

Scegli uno strumento

GET /catalog elenca tutti e 7447 gli strumenti, con prezzo e unità aggiornati. Oppure sfoglia il catalogo in fondo a questa pagina.

3

Eseguila

Fai POST sull’endpoint dello strumento. Ricevi subito un task_id e il risultato arriva al tuo webhook.

Autenticazione

Bearer token, mostrato una volta sola

Ogni richiesta all’API porta Authorization: Bearer kit_live_…. Dopo il prefisso, le chiavi sono 48 caratteri esadecimali.

Di ogni chiave conserviamo solo l’hash SHA-256. È una scelta voluta: un dump del database non consegna a nessuno le tue credenziali — ma vuol dire anche che davvero non possiamo rispedirti la chiave via email. L’hai persa? La revochiamo e ne emettiamo una nuova.

Una chiave sbagliata restituisce sempre 401 e non dice mai perché. Revocata, digitata male o mai esistita sono indistinguibili apposta: dirti quale delle tre era vuol dire dirlo anche a chi attacca.

Il modello asincrono

Ogni attività è asincrona. Senza eccezioni.

1

Fai POST dell’attività

Ricevi 202 con un task_id e stato queued, più quanto costerà. I soldi vengono bloccati, non addebitati.

2

Gira sull’edge

Sotto il secondo per le attività di calcolo; qualche secondo per IA e media.

3

Il risultato ti trova

Lo mandiamo in POST al tuo webhook_url, se ne hai indicato uno. Altrimenti GET /tasks/{id}/result. I risultati restano in base alla dimensione: da 168 h per quelli piccoli (fino a 1 MB) a 6 h per i più grandi.

4

Se fallisce non paghi

L’attività viene tentata fino a 3 volte in tutto, con backoff fra un tentativo e l’altro. Se fallisce comunque, il blocco viene rilasciato e non ti addebitiamo nulla. Mai.

Riferimento API

Tutti gli endpoint a cui il KIT risponde

Le rotte non hanno prefisso di versione. /v1/* continua a rispondere per i client vecchi, ma non è la forma canonica e il codice nuovo non dovrebbe usarla.

POSThttps://api.kit.forhosting.com/tasks

URL di base: https://api.kit.forhosting.com

MetodoRottaAuthCosa fa
ANY / Pubblico Indice del servizio: versione, numero di capacità e l’elenco di endpoint che l’API annuncia di sé. Senza chiave, e risponde a qualsiasi metodo.
POST /{alias} Chiave API Scorciatoia per capacità di POST /tasks con il type fisso — per esempio POST /ocr/invoice. È la forma che mostra ogni pagina di capacità.
GET /account Chiave API Saldo del conto: available_usd è il saldo reale del portafoglio, più held_usd. Quando il portafoglio è gestito dall’area cliente, balance.source vale "portal" e balance_endpoint punta al valore aggiornato.
POST /agent/ask Chiave API In arrivo Non implementato — restituisce 501 con la chiave e 401 senza. L’assistente conversazionale si sta costruendo altrove; per trovare una capacità usa POST /catalog/search.
GET /catalog Pubblico Tutte le capacità con prezzo e unità aggiornati. ?lang=en|es, ?q= per filtrare, ?limit=, ?schema=1 per lo schema di input e ?channel= per avere il prezzo già adeguato a quel canale — chiedi il canale su cui fatturerai, altrimenti mostri una cifra e ne addebiti un’altra.
POST /catalog/search Pubblico {query} → le capacità che corrispondono, ognuna con il prezzo già scritto. Senza chiave. Assegna il punteggio per copertura di parola intera con una soglia, quindi una domanda che non capisce non restituisce nulla invece di tirare a indovinare — è voluto.
POST /estimate Chiave API {type, input} → unità, prezzo e dettaglio. Preventiva senza eseguire. Quando la quantità reale non si può sapere prima (le pagine di un PDF dietro a una URL), la risposta lo dice con estimated: true.
GET /mobile/bootstrap Pubblico Quello che serve all’app per partire: categorie, etichette e gli stessi prezzi adeguati al canale. Senza chiave. Nemmeno questa fa parte del contratto pubblico, per lo stesso motivo.
GET /mobile/catalog Pubblico Proiezione del catalogo per l’app, con i prezzi già adeguati al canale dell’app. Senza chiave. Non fa parte del contratto pubblico: la sua forma segue l’app e può cambiare senza preavviso — sviluppa contro GET /catalog.
GET /plans Pubblico Importi di ricarica: currency e topup (sku, default_amount, min_amount). Nient’altro — non ci sono piani da sottoscrivere.
POST /signup Pubblico {email}201 con la tua api_key, mostrata una volta sola. 409 se l’email esiste già; 429 oltre 10/h per IP.
GET /tasks Chiave API Le tue attività. ?status=, ?limit= (25 di default, 100 al massimo).
POST /tasks Chiave API {type, input, webhook_url?, max_cost_usd?}202. Paghi l’unità reale dell’attività — pagine, minuti, immagini — misurata durante l’esecuzione, non la stima iniziale. max_cost_usd è un tetto rigido: se il costo reale lo supera, l’attività fallisce e non ti viene addebitato nulla. Manda Idempotency-Key perché riprovare sia sicuro: una ripetizione restituisce l’attività originale con idempotent: true.
DELETE /tasks/{id} Chiave API Annulla un’attività in coda e libera la sua riserva.
GET /tasks/{id} Chiave API Stato dell’attività. 10 letture ogni 10 secondi per attività; oltre, 429 con Retry-After: 1. Meglio il webhook.
GET /tasks/{id}/events Chiave API In arrivo Non implementato — restituisce 501. L’SSE arriverà; usa il webhook.
GET /tasks/{id}/result Chiave API Risultato JSON, o il file come allegato. 409 non pronto, 410 scaduto, 422 fallito. La conservazione dipende dalla dimensione del risultato: 168 h per quelli piccoli, fino a 6 h per quelli molto grandi.
POST /tasks/{id}/retry Chiave API Rimette in coda un’attività fallita.
POST /uploads Chiave API Manda un file locale: corpo binario grezzo, con il Content-Type del file. → 201 con ref: "kit://upl_…", che poi metti dove andrebbe una URL: {"input": {"pdf": "kit://upl_…"}}. Un caricamento può alimentare più attività. I ref vivono 24 h. Massimo 100 MiB (104.9 MB) per caricamento; ogni capacità applica in più il proprio limite.

Webhook

Consegna firmata, e come verificarla

Imposti webhook_url quando crei l’attività e noi mandiamo lì il risultato in POST appena è pronto. È la strada consigliata: costa meno del polling e arriva prima.

Verifica la firma prima di fidarti del corpo. Ogni consegna porta KIT-Signature: v1=<hex> e KIT-Timestamp: <secondi unix>. La firma è HMAC-SHA256 sulla stringa <timestamp>.<corpo grezzo> — il timestamp e il punto fanno parte del payload firmato, non sono decorazione. Firma i byte grezzi che hai ricevuto, non un oggetto riserializzato.

La consegna viene tentata fino a 5 volte con backoff esponenziale. Un 4xx dal tuo endpoint ferma subito i tentativi — lo leggiamo come “il tuo handler è sbagliato”, non “riprova più tardi”. Ritentiamo solo su 5xx ed errori di rete. Dopodiché la consegna finisce in dead letter.

{
  "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"
  }
}
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));
}

Errori

HTTP standard, slug leggibile dalla macchina

Ogni errore porta nel corpo uno slug error stabile. Fai il match sullo slug, non sul messaggio: i messaggi sono localizzati e possono cambiare.

HTTPErroreSignificato
400flow_depthUna capacità composta si è annidata più a fondo del consentito. Appiattisci i passi.
400invalid_amountL’importo manca, non è un numero, oppure è fuori dall’intervallo consentito.
400invalid_emailL’email manca o non è valida.
400invalid_inputAll’input manca un campo obbligatorio o non ha la forma che questa attività si aspetta.
400invalid_jsonIl corpo della richiesta non è un JSON valido.
400missing_typeManca il campo 'type' nella richiesta. Consulta GET /catalog.
400unknown_opOperazione sconosciuta per questa capacità. Controlla il nome nel catalogo.
400unsafe_urlLa URL punta a un posto da cui non scaricheremo: un indirizzo interno o non pubblico.
401auth_requiredQuesto passo richiede un account identificato e la richiesta non ne porta nessuno.
401no_keyLa richiesta non porta una API key, o l’account non ne ha nessuna attiva.
401unauthorizedChiave API mancante o non valida: controlla l'header Authorization.
402account_suspendedIl tuo account è sospeso, di solito per il tetto di spesa. Scrivici per riattivarlo.
402insufficient_balanceCredito esaurito: ricarica per continuare a eseguire attività.
402max_cost_exceededL’attività è costata più del max_cost_usd che hai impostato. Non è stato addebitato nulla.
403forbiddenLa credenziale è valida ma non è autorizzata a farlo.
404input_not_foundQuesto riferimento kit:// non esiste. Ricarica il file con POST /uploads.
404not_foundNessuna attività o risorsa a quel percorso.
404unknown_typeTipo di attività sconosciuto: controlla il campo type della richiesta.
409alias_takenQuell’alias di posta in entrata è di qualcun altro. Scegline un altro.
409already_acceptedQuell’accettazione è già stata usata. Ognuna vale esattamente una volta.
409email_takenEsiste già un account con questa email.
409need_leaseUn altro worker sta già eseguendo questa attività. Aspetta che finisca.
409not_cancellableL’attività non è più in coda, quindi non si può annullare. Solo quelle in coda si annullano.
409not_readyL’attività non è ancora finita: controlla lo stato o aspetta il webhook.
409not_retryableSi riprovano solo le attività fallite. Questa è in un altro stato.
410expiredLa finestra di conservazione del risultato è passata e non è più disponibile.
410input_expiredQuesto riferimento kit:// è scaduto. I caricamenti durano 24 h; ricarica il file.
410quote_expiredIl preventivo ha superato la sua finestra di validità. Chiedine uno nuovo.
413input_too_largeIl file o il testo inviato supera il limite di questo strumento.
413resolution_too_highL’immagine o il video superano la risoluzione che questa capacità accetta.
422conversion_failedNon è stato possibile convertire il file. Di solito è un formato corrotto o inatteso.
422engine_errorIl motore ha fallito a ogni tentativo. La riserva è stata liberata: non ti addebitiamo nulla.
422needs_reworkIl risultato non ha passato il proprio controllo di qualità, quindi non viene consegnato. Non addebitato.
429rate_limitedTroppe richieste in poco tempo: rallenta e riprova tra qualche secondo.
500lease_errorNon è stato possibile prendere in carico l’attività. Torna in coda.
500ledger_errorNon è stato possibile bloccare né liquidare il credito. Riprova.
500no_holdL’attività non ha una riserva da liquidare. Non dovrebbe succedere; se succede, faccelo sapere.
500no_resultL’attività è terminata senza produrre un risultato.
501coming_soonQuesto strumento non è ancora attivo via API: arriva presto.
501mail_not_configuredQuesta capacità manda email e l’account non ha ancora un mittente configurato.
501not_implementedQuesto endpoint o questa capacità non è ancora disponibile.
501tickets_not_configuredL’integrazione dei ticket non è configurata per questo account.
501unsupportedQuesta operazione non è ancora supportata (per esempio, i flow non si possono preventivare).
502model_output_invalidIl modello ha restituito qualcosa che non corrisponde all’output dichiarato. Non addebitato.
502tickets_unreachableIl sistema di ticket non ha risposto. Non è stato addebitato nulla; riprova.
503all_busyTutti i worker di questa capacità sono occupati. Riprova tra poco.

Prezzi

Pubblicati, per attività, senza crediti

Si paga solo ciò che si utilizza. Si aggiunge saldo al proprio account (a partire da $10.00) — non scade mai — e ogni attività vi attinge al proprio prezzo pubblicato. Dollari veri, non punti.

Ogni attività costa una tariffa base più una tariffa per unità, entrambe pubblicate sulla pagina dello strumento e nel catalogo qui sotto — da $0.002 a chiamata. POST /estimate ti dà il preventivo di un’attività senza eseguirla, e max_cost_usd sull’attività la rifiuta se costasse più di quanto hai detto.

Le attività fallite non si pagano mai. Gli strumenti gratis girano nel tuo browser e non costano proprio nulla.

Strumenti gratuiti
$0.00
A consumo
$0.002
Pagamento a consumo
Saldo
$10.00

Limiti

Cosa impone il servizio

Tre limiti, e ognuno conta per conto suo. Per account: 600 richieste al minuto in tutto e 60 caricamenti al minuto. Per attività: 10 letture di stato ogni 10 secondi — superato uno qualsiasi, ricevi 429 con Retry-After: 1. Usa il webhook invece del polling: costa meno e arriva prima. I risultati restano in base alla dimensione: 168 h fino a 1 MB e 6 h per quelli molto grandi. GET /tasks restituisce 25 elementi di default, 100 al massimo. La registrazione è limitata a 10 account l’ora per IP.

Catalogo degli strumenti

Tutti e 7447, sfogliabili per categoria

Ogni strumento ha la sua pagina, dove lo esegui, vedi un esempio vero e il prezzo pubblicato — lo stesso che fattura questa API. Apri il catalogo completo, oppure vai dritto a una categoria.

Tutte le categorie →