ForHosting KIT

Tudo o que o KIT faz, em um lugar só

O ForHosting KIT é um catálogo de 7447 tarefas prontas — converter um documento, ler uma nota fiscal, transcrever áudio, validar um IBAN, gerar um QR Code — em 14 categorias. Você roda tudo aqui pela web, ou chama do seu código com um POST autenticado. Esta página é a referência completa da API: endpoints, o modelo assíncrono, o contrato do webhook, erros e preços.

Use pelo WebAPIE-mailTelegramApp em breve

O que é o KIT

Um catálogo de tarefas, não um modelo

Cada capacidade é uma tarefa: você manda a entrada, recebe o resultado. Não tem token, não tem janela de contexto, não tem engenharia de prompt. Cada tarefa tem preço publicado, unidade documentada e formato fixo.

São quatro jeitos de rodar. Web — cada capacidade tem a sua própria página e roda no navegador; as grátis não saem do seu aparelho. API — um POST autenticado, documentado aqui embaixo. E-mail e Telegram — você manda a tarefa para um endereço do KIT. A API é um canal, não o produto.

Comece por aqui

Do zero ao resultado em três chamadas

Crie a sua conta, pegue a sua chave, rode uma tarefa. Sem ligação de vendas, sem lista de espera.

1

Pegue uma chave de API

POST /signup com o seu e-mail devolve uma chave que começa com kit_live_. Ela aparece uma vez só. A gente guarda apenas o hash SHA-256 dela, então se você perder não tem como recuperar — a gente emite uma nova.

2

Escolha uma capacidade

GET /catalog lista as 7447 com preço ao vivo e unidade. Ou veja o catálogo no fim desta página.

3

Rode

Faça o POST no endpoint da capacidade. Você recebe um task_id na hora e o resultado chega no seu webhook.

Autenticação

Token Bearer, mostrado uma vez só

Toda requisição à API leva Authorization: Bearer kit_live_…. As chaves têm 48 caracteres hexadecimais depois do prefixo.

A gente guarda só o hash SHA-256 da sua chave. Isso é de propósito: um vazamento de banco de dados não entrega a credencial de ninguém — mas também quer dizer que a gente realmente não tem como mandar a sua chave de volta por e-mail. Perdeu? A gente revoga e emite outra.

Chave errada sempre devolve 401 e nunca diz o motivo. Revogada, digitada errada e nunca existiu são indistinguíveis de propósito: contar para você qual foi é contar para um atacante também.

O modelo assíncrono

Toda tarefa é assíncrona. Sem exceção.

1

Você faz o POST da tarefa

Devolve 202 com um task_id e status queued, mais quanto vai custar. O valor fica reservado, não cobrado.

2

Ela roda na borda (edge)

Menos de um segundo nas tarefas de computação; alguns segundos em IA e mídia.

3

O resultado vai atrás de você

Ele é enviado por POST para a sua webhook_url, se você tiver informado uma. Se não, GET /tasks/{id}/result. Os resultados ficam guardados conforme o tamanho: de 168 h para os pequenos (até 1 MB) a 6 h para os maiores.

4

Falha não custa nada

A tarefa é tentada até 3 vezes no total, com backoff entre as tentativas. Se ainda assim falhar, a reserva é liberada e você não paga. Nunca.

Referência da API

Todos os endpoints que o KIT responde

As rotas não têm prefixo de versão. /v1/* continua resolvendo para clientes antigos, mas não é a forma canônica e código novo não deve usar.

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

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

MétodoRotaAuthO que faz
ANY / Pública Índice do serviço: versão, número de capacidades e a lista de endpoints que a API anuncia sobre si mesma. Sem chave, e responde a qualquer método.
POST /{alias} Chave de API Atalho por capacidade para POST /tasks com o type fixo — por exemplo POST /ocr/invoice. É a forma que cada página de capacidade mostra.
GET /account Chave de API Saldo da conta: available_usd é o saldo real da carteira, mais held_usd. Quando a carteira é gerida pela área do cliente, balance.source é "portal" e balance_endpoint aponta para o valor ao vivo.
POST /agent/ask Chave de API Em breve Não implementado — devolve 501 com chave e 401 sem ela. O assistente conversacional está sendo construído à parte; para achar uma capacidade use POST /catalog/search.
GET /catalog Pública Todas as capacidades com preço e unidade ao vivo. ?lang=en|es, ?q= para filtrar, ?limit=, ?schema=1 para o schema de entrada e ?channel= para receber o preço já ajustado àquele canal — peça o canal pelo qual você vai cobrar, ou vai mostrar um valor e cobrar outro.
POST /catalog/search Pública {query} → as capacidades que combinam, cada uma com o preço já redigido. Sem chave. Pontua por cobertura de palavra inteira com limiar, então uma busca que ele não entende devolve nada em vez de chutar — é de propósito.
POST /estimate Chave de API {type, input} → unidades, preço e detalhamento. Cota sem executar. Quando a quantidade real não dá para saber antes (o número de páginas de um PDF atrás de uma URL), a resposta avisa com estimated: true.
GET /mobile/bootstrap Pública O que o app precisa para iniciar: categorias, rótulos e os mesmos preços ajustados ao canal. Sem chave. Também não faz parte do contrato público, pelo mesmo motivo.
GET /mobile/catalog Pública Projeção do catálogo para o app, com os preços já ajustados ao canal do app. Sem chave. Não faz parte do contrato público: o formato acompanha o app e pode mudar sem aviso — programe contra GET /catalog.
GET /plans Pública Valores de recarga: currency e topup (sku, default_amount, min_amount). Nada mais — não há planos para assinar.
POST /signup Pública {email}201 com a sua api_key, mostrada uma única vez. 409 se o e-mail já existe; 429 acima de 10/h por IP.
GET /tasks Chave de API As suas tarefas. ?status=, ?limit= (25 por padrão, 100 no máximo).
POST /tasks Chave de API {type, input, webhook_url?, max_cost_usd?}202. Você paga pela unidade real da tarefa — páginas, minutos, imagens — medida durante a execução, não pela estimativa prévia. max_cost_usd é um teto duro: se o custo real passar dele, a tarefa falha e nada é cobrado. Mande Idempotency-Key para que repetir seja seguro: uma repetição devolve a tarefa original com idempotent: true.
DELETE /tasks/{id} Chave de API Cancela uma tarefa na fila e libera a reserva dela.
GET /tasks/{id} Chave de API Estado da tarefa. 10 consultas a cada 10 segundos por tarefa; acima disso, 429 com Retry-After: 1. Prefira o webhook.
GET /tasks/{id}/events Chave de API Em breve Não implementado — devolve 501. O SSE vem depois; use o webhook.
GET /tasks/{id}/result Chave de API Resultado JSON, ou o arquivo como anexo. 409 se não está pronto, 410 se expirou, 422 se falhou. A retenção depende do tamanho do resultado: 168 h para os pequenos, até 6 h para os muito grandes.
POST /tasks/{id}/retry Chave de API Recoloca na fila uma tarefa que falhou.
POST /uploads Chave de API Mande um arquivo local: corpo binário cru, com o Content-Type do arquivo. → 201 com ref: "kit://upl_…", que você depois põe onde iria uma URL: {"input": {"pdf": "kit://upl_…"}}. Um upload pode alimentar várias tarefas. Os refs vivem 24 h. Máximo 100 MiB (104.9 MB) por upload; cada capacidade aplica ainda o seu próprio limite.

Webhooks

Entrega assinada — e como conferir a assinatura

Informe webhook_url ao criar a tarefa e a gente faz o POST do resultado lá quando ficar pronto. É o caminho recomendado: custa menos que polling e chega antes.

Confira a assinatura antes de confiar no corpo. Toda entrega leva KIT-Signature: v1=<hex> e KIT-Timestamp: <segundos unix>. A assinatura é um HMAC-SHA256 sobre a string <timestamp>.<corpo cru> — o timestamp e o ponto fazem parte do payload assinado, não são enfeite. Assine os bytes crus que você recebeu, não um objeto re-serializado.

A entrega é tentada até 5 vezes, com backoff exponencial. Um 4xx vindo do seu endpoint interrompe as tentativas na hora — a gente lê isso como “o seu handler está errado”, não como “tente mais tarde”. Só 5xx e erro de rede geram nova tentativa. Depois disso, a entrega vai para a 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));
}

Erros

HTTP padrão, slug legível por máquina

Todo erro traz no corpo um slug estável em error. Trate pelo slug, não pela mensagem: as mensagens são traduzidas e podem mudar.

HTTPErroO que significa
400flow_depthUma capacidade composta aninhou mais fundo do que o permitido. Achate os passos.
400invalid_amountO valor está faltando, não é número, ou está fora da faixa permitida.
400invalid_emailO e-mail está ausente ou é inválido.
400invalid_inputFalta um campo obrigatório na entrada, ou ela não está no formato que esta tarefa espera.
400invalid_jsonO corpo da requisição não é um JSON válido.
400missing_typeFalta o campo 'type' na requisição. Consulte GET /catalog.
400unknown_opOperação desconhecida para esta capacidade. Confira o nome no catálogo.
400unsafe_urlA URL aponta para um lugar de onde não vamos baixar: um endereço interno ou não público.
401auth_requiredEste passo precisa de uma conta identificada e a requisição não traz nenhuma.
401no_keyA requisição não traz API key, ou a conta não tem nenhuma ativa.
401unauthorizedToken ausente ou inválido. Confira o header Authorization.
402account_suspendedSua conta está suspensa, normalmente pelo limite de gasto. Fale com a gente para reativá-la.
402insufficient_balanceSaldo insuficiente para esta tarefa. Faça uma recarga e tente de novo.
402max_cost_exceededA tarefa custou mais do que o max_cost_usd que você definiu. Nada foi cobrado.
403forbiddenA credencial é válida, mas não tem permissão para isso.
404input_not_foundEssa referência kit:// não existe. Envie o arquivo de novo com POST /uploads.
404not_foundNão há tarefa nem recurso nesse caminho.
404unknown_typeEsse tipo de tarefa não existe. Confira o campo type no catálogo.
409alias_takenEsse alias de e-mail de entrada é de outra pessoa. Escolha outro.
409already_acceptedEsse aceite já foi usado. Cada um vale exatamente uma vez.
409email_takenJá existe uma conta com esse e-mail.
409need_leaseOutro worker já está rodando esta tarefa. Espere terminar.
409not_cancellableA tarefa não está mais na fila, então não dá para cancelar. Só as que estão na fila.
409not_readyA tarefa ainda não terminou. Consulte o status ou aguarde o webhook.
409not_retryableSó tarefas que falharam podem ser repetidas. Esta está em outro estado.
410expiredA janela de retenção do resultado já passou e ele não fica mais guardado.
410input_expiredEssa referência kit:// expirou. Os envios duram 24 h; envie o arquivo de novo.
410quote_expiredA cotação passou da validade. Peça uma nova.
413input_too_largeA entrada passou do tamanho máximo desta tarefa. Confira os limites publicados.
413resolution_too_highA imagem ou o vídeo passam da resolução que esta capacidade aceita.
422conversion_failedNão deu para converter o arquivo. Normalmente é formato corrompido ou inesperado.
422engine_errorO motor falhou em todas as tentativas. A reserva foi liberada: você não paga.
422needs_reworkO resultado não passou no próprio controle de qualidade, então não é entregue. Não é cobrado.
429rate_limitedMuitas requisições em pouco tempo. Espere um instante e tente de novo.
500lease_errorNão deu para tomar a tarefa para executar. Ela volta para a fila.
500ledger_errorNão foi possível reservar nem liquidar o saldo. Tente de novo.
500no_holdA tarefa não tem reserva para liquidar. Não deveria acontecer; se acontecer, nos avise.
500no_resultA tarefa terminou sem produzir resultado.
501coming_soonEsta capacidade ainda não está no ar. Em breve ela chega.
501mail_not_configuredEsta capacidade manda e-mail e a conta ainda não tem remetente configurado.
501not_implementedEste endpoint ou capacidade ainda não está disponível.
501tickets_not_configuredA integração de tíquetes não está configurada para esta conta.
501unsupportedEsta operação ainda não é suportada (por exemplo, os flows não podem ser cotados).
502model_output_invalidO modelo devolveu algo que não bate com a saída declarada. Não é cobrado.
502tickets_unreachableO sistema de tíquetes não respondeu. Nada foi cobrado; tente de novo.
503all_busyTodos os workers desta capacidade estão ocupados. Tente de novo em instantes.

Preços

Publicado, por tarefa, sem créditos

Pague apenas pelo que usar. Adicione saldo à sua conta (a partir de US$ 10,00) — ele nunca expira — e cada tarefa é descontada dele pelo preço publicado por tarefa. Dólares de verdade, não pontos.

Cada tarefa custa uma taxa base mais uma taxa por unidade, as duas publicadas na página da própria capacidade e no catálogo aqui embaixo — a partir de US$ 0,002 por chamada. POST /estimate faz o orçamento da tarefa sem rodar, e max_cost_usd na tarefa recusa a execução se ela for custar mais do que você disse.

Tarefa que falha não é cobrada. As capacidades grátis rodam no seu navegador e não custam absolutamente nada.

Ferramentas grátis
US$ 0,00
Por tarefa
US$ 0,002
Pague conforme usar
Saldo
US$ 10,00

Limites

O que o serviço aplica

São três limites, e cada um conta de um jeito. Por conta: 600 requisições por minuto no total e 60 uploads por minuto. Por tarefa: 10 consultas de status a cada 10 segundos — passou de qualquer um deles, você recebe 429 com Retry-After: 1. Use o webhook em vez de ficar consultando: custa menos e chega antes. Os resultados ficam guardados conforme o tamanho: 168 h até 1 MB e 6 h para os muito grandes. GET /tasks devolve 25 por padrão e 100 no máximo. O signup é limitado a 10 contas por hora por IP.

Catálogo de capacidades

Todas as 7447, navegáveis por categoria

Cada capacidade tem a sua própria página, onde você roda, vê um exemplo de verdade e o preço publicado — o mesmo que esta API cobra. Abra o catálogo completo, ou vá direto para uma categoria.

Todas as categorias →