Cada detecção de imagem bem-sucedida consome créditos. Uploads em massa via ZIP cobram apenas imagens que concluem a análise; arquivos ignorados ou com falha não são cobrados.
A chave deve estar no corpo JSON das requisições (exceto endpoints só com cabeçalho, ex.: check-user-credits):
{
"key": "YOUR API KEY GOES HERE"
}
Substitua YOUR API KEY GOES HERE pela sua chave pessoal.
Limites de taxa
A API aplica para cada chave de API um orçamento de requisições por minuto. Endpoints de escrita custam mais que os de leitura. O limite padrão é 250 requisições por minuto — fale conosco se precisar de um limite maior.
Pesos por endpoint
Cada chamada desconta seu peso do orçamento por minuto:
Endpoint
Tipo
Peso
POST /detect
Escrita
1
POST /bulk-upload
Escrita
1
GET /get-presigned-url
Leitura
0.2
GET /check-user-credits
Leitura
0.2
POST /heatmap/{id}
Leitura
0.2
POST /preview/{id}
Leitura
0.2
POST /query
Leitura
Sem limite
GET /health
Leitura
Sem limite
Exemplo: com um orçamento de 250/minuto você pode enviar até 250 chamadas de escrita, até ~1.250 chamadas de leitura, ou qualquer combinação cujo total ponderado fique ≤ 250 por minuto.
Resposta limitada (HTTP 429)
Quando você ultrapassa o orçamento por minuto, a API retorna:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 250
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 3
X-RateLimit-Retry-After: 3
Content-Type: application/json
{
"error": "Too many requests"
}
Cabeçalhos de resposta de rate limit
X-RateLimit-Limit — sua capacidade por minuto.
X-RateLimit-Remaining — chamadas restantes no minuto atual (após esta requisição).
X-RateLimit-Reset — (somente em 429) segundos até você poder enviar outra requisição de escrita.
X-RateLimit-Retry-After — (somente em 429) mesmo valor de X-RateLimit-Reset, no estilo Retry-After.
Comportamento recomendado do cliente
Acompanhe X-RateLimit-Remaining nas respostas bem-sucedidas para regular o ritmo das requisições.
Em um 429, espere pelo menos X-RateLimit-Retry-After segundos antes de tentar de novo — use backoff exponencial com jitter.
Para lotes, prefira POST /bulk-upload (uma chamada processa até 50 imagens) em vez de muitas /detect em paralelo.
Detector de imagens por IA
Detectar (fluxo em 3 etapas)
O fluxo de detecção de imagens por IA consiste nas seguintes etapas:
Obter URL de upload pré-assinada
Enviar a imagem
Enviar a imagem para detecção
1. Obter URL de upload pré-assinada
Primeiro, solicite uma URL pré-assinada à API. Ela permite enviar o arquivo de imagem com segurança ao armazenamento.
Remova espaços do nome ao solicitar a URL pré-assinada.
Para PDF, apenas a primeira imagem é detectada (fluxo de arquivo único).
Use um nome .zip neste endpoint quando for enviar um ZIP em upload em lote.
Parâmetros de consulta
file_name (obrigatório) — Nome original; o servidor pode normalizar (espaços e caracteres inseguros são ajustados). Use extensão .zip para upload em lote.
expiration (opcional) — Validade da URL pré-assinada em segundos (padrão: 3600).
GET https://detect-image.truthscan.com/get-presigned-url?file_name=example.jpg
Exemplo de requisição
curl -X GET 'https://detect-image.truthscan.com/get-presigned-url?file_name=example.jpg' \
--header 'apikey: YOUR API KEY GOES HERE'
document_id é um novo UUID para esta solicitação de upload (correlação/logs). O id usado em /detect ou /bulk-upload é atribuído ao chamar esses endpoints, salvo se você passar um id opcional em /detect.
Mantenha o formato consistente durante o upload. Sucesso retorna HTTP 200.
Resposta do PUT no armazenamento
A etapa 2 é um PUT direto no armazenamento de objetos (URL pré-assinada), não na nossa API. Upload de imagem única e ZIP em massa funcionam da mesma forma.
Sucesso retorna HTTP 200 com corpo vazio — por design. Não há JSON para analisar.
Após o PUT em presigned_url: trate res.ok (status 200–299) como sucesso. Não chame response.json() em caso de sucesso — corpo vazio é esperado. Reporte erros apenas em respostas fora de 2xx.
3. Enviar imagem para detecção por IA
Após o upload, envie para detecção usando o file_path da etapa anterior. Para PDF, apenas a primeira imagem é analisada/detectada.
FILE_PATH é o caminho retornado na etapa da URL pré-assinada (ex.: uploads/...). Monte a URL completa com o host do armazenamento como no exemplo.
Parâmetros opcionais
id: UUID opcional. Se omitido, o servidor gera um novo id de documento. Se informado, não pode existir; caso contrário, erro.
generate_preview: true para gerar URL de pré-visualização (padrão: true). false pula a prévia.
document_type: Tipo de documento (padrão: Image).
email: E-mail para processamento.
generate_analysis_details: false para pular análise detalhada (padrão: true).
generate_heatmap: Quando false, pula a geração de mapa de calor por completo (padrão: true). Mapas de calor só são produzidos para imagens classificadas como IA quando true. Imagens reais nunca recebem mapa de calor.
generate_heatmap_overlayed: Controla como o mapa de calor é gerado (padrão: true). Aplica-se somente quando generate_heatmap é true e a imagem é classificada como gerada por IA. Com true, o mapa é sobreposto à imagem original; com false, retorna PNG RGBA transparente para compor na interface.
generate_heatmap_normalized: Com false, pula a normalização do mapa de ativação (padrão: true). Aplica-se somente quando generate_heatmap é true e a imagem é classificada como gerada por IA. Use junto com generate_heatmap_overlayed.
model: Dica de modelo ou roteamento (padrão: generic). Ex.: generic ou instance_id/model. instance_id inválido → 400.
user_agent: String opcional armazenada no documento para analytics/suporte.
Validação dos flags de heatmap
Se generate_heatmap for false, não defina explicitamente generate_heatmap_overlayed ou generate_heatmap_normalized como true. A API retorna 422 Unprocessable Entity com mensagens como "generate_heatmap_overlayed cannot be true when generate_heatmap is false." ou "generate_heatmap_normalized cannot be true when generate_heatmap is false."
Exemplo de requisição (heatmap habilitado, padrão)
A resposta inclui um id de imagem único para acompanhar o status.
Respostas HTTP
Status
Corpo
Quando
200
JSON: id, status (tipicamente "pending")
Job aceito — é o que a API retorna em caso de sucesso
400
{"error": "..."}
Validação (sem URL, arquivo não enviado, tamanho/tipo, id duplicado, modelo inválido, conflito de flag de heatmap, etc.)
403
{"error": "..."}
Chave inválida / créditos insuficientes
422
{"error": "..."}
Corpo da requisição inválido (ex.: generate_heatmap_overlayed true quando generate_heatmap é false)
500
{"error": "..."}
Erro no servidor
Trate qualquer resposta 2xx cujo JSON inclua id e status como sucesso — não apenas HTTP 200. Proxies ou outras pilhas HTTP podem retornar 201 ou 202 para padrões de aceitação assíncrona; valide o corpo JSON.
Consultar status e resultados da detecção
Use o endpoint /query com o id da imagem para obter status e resultados.
Autenticação: o corpo só inclui id; a API não envia chave nesta chamada. Quem souber o UUID pode consultar — trate ids de documento como sensíveis se precisar restringir acesso.
final_label_confidence: Quão certo o modelo está de `final_result`, de 0 a 100. Leia como “esta imagem é N% [rótulo]”. Por exemplo, `final_result`: `"AI Generated"` com `final_label_confidence`: `90` significa que o modelo está 90% confiante de que a imagem é gerada por IA; `final_result`: `"Real"` com `final_label_confidence`: `80` significa que o modelo está 80% confiante de que é real.
metadata: Informações extraídas dos metadados com ExifTool e Pillow.
metadata_basic_source: Pode indicar se a imagem foi capturada por um modelo de câmera, gerada por IA ou editada.
ocr: Resultado de marca d'água no campo histórico ocr. Array [rótulo, pontuação]; rótulo ex. "Gemini" ou "OCR did not detect AI"; pontuação 0–100. Resumido em warnings quando há rótulo.
ml_model: Resultados do modelo de aprendizado de máquina.
warnings: Array opcional de avisos (blur_dark, watermark, screen_recapture etc.). Pode estar vazio ou ausente. blur_dark e screen_recapture: ambos são bons candidatos a uma nova captura com o Capture em vez de uma decisão definitiva.
preview_url: URL de prévia se generate_preview foi true. Pode ser armazenamento direto ou caminho da API como https://<api-host>/preview/<document_id>.
heatmap_status: pending, ready ou failed. Omitido quando a imagem não é gerada por IA ou quando generate_heatmap era false no envio. A geração de heatmap é assíncrona e só ocorre para imagens classificadas como IA quando generate_heatmap é true.
heatmap_url: Presente quando heatmap_status é ready, a imagem foi classificada como IA e generate_heatmap estava habilitado no envio. Depende de generate_heatmap_overlayed. Direto ou API; com URLs seguras use POST /heatmap/{id} com chave.
analysis_results_status: pending, ready, skipped, failed ou analyzing. Omitido ou null se generate_analysis_details foi false.
analysis_results: Análise narrativa detalhada quando habilitada; veja embaixo.
Explicação dos resultados de análise
Quando analysis_results está pronto, costuma incluir: agreement (strong | moderate | weak | disagreement), imageTags (até cinco tags curtas), confidence (0–100), keyIndicators, detailedReasoning, visualPatterns e recommendations.
Observações
A geração de heatmap é assíncrona e só ocorre para imagens classificadas como IA quando generate_heatmap é true (padrão). Consulte /query até heatmap_status ser ready.
Análise detalhada é assíncrona salvo generate_analysis_details=false. Consulte analysis_results_status e analysis_results.
URLs seguras: heatmap_url e preview_url podem usar o host da API; busque com POST /heatmap/{id} e POST /preview/{id} com sua chave.
Chame /query novamente após o score principal para obter heatmap e analysis_results quando concluírem.
Mapa de calor e sobreposição
heatmap_url reflete generate_heatmap_overlayed e generate_heatmap_normalized de /detect (ou /bulk-upload) quando generate_heatmap era true: sobreposição padrão (true) é uma imagem normal com o mapa sobreposto; false costuma ser PNG transparente para composição. Imagens reais e requisições com generate_heatmap: false omitem heatmap_status e heatmap_url.
Exemplo de resposta (imagem IA, heatmap desabilitado no envio)
Exemplo: result ~90,24 com final_result AI Generated e detection_step 3 indica pipeline completa (metadados, OCR, ML).
Como tratar resultados sinalizados
Beta
A API devolve uma classificação e uma confiança, não uma decisão. A maioria das integrações em produção usa três faixas. Abaixo do seu limite inferior, aprove automaticamente. Acima do seu limite superior, encaminhe para revisão com o mapa de calor e analysis_results anexados. Entre os dois, peça uma nova captura ao vivo com o TruthScan Capture (beta) antes de envolver um revisor.
Um pedido de Capture cabe quando o resultado é incerto ou a própria imagem é o problema: final_label_confidence na sua faixa do meio, analysis_results.agreement weak ou disagreement, ou uma entrada de warnings blur_dark ou screen_recapture. Em cada caso, a resolução mais barata é uma foto nova tirada ao vivo no dispositivo de quem enviou, não um julgamento humano sobre uma foto ruim.
O Capture devolve um novo resultado de detecção vinculado ao id da solicitação original, para que sua camada de decisão veja os dois. Durante a beta, o Capture é habilitado por conta.
result = client.detect(image)
conf = result.result_details.final_label_confidence
if conf < LOWER: approve(result)
elif conf > UPPER: route_to_review(result)
else: # gray band, or warnings / weak agreement
capture = client.capture.request(result.request_id, contact=submitter)
# poll capture.request_id for the linked, verified result
Resultados de análise (análise profunda assíncrona)
Com generate_analysis_details true em /detect, a análise detalhada pode concluir após o score principal. Consulte /query até analysis_results_status ready (ou skipped/failed).
1. Resultado inicial pode ficar pronto antes da análise
Detecção principal (result, final_result, confidence) pode terminar com analysis_results_status ainda pending.
analysis_results.detailedReasoning: explicação breve
analysis_results.visualPatterns: padrões mais amplos
analysis_results.recommendations: próximos passos
Upload em lote (ZIP)
Envie várias imagens em uma requisição com um ZIP. Fluxo igual ao de imagem única: URL pré-assinada (nome .zip) → PUT ZIP → POST /bulk-upload → consultar /query.
1. URL pré-assinada (ZIP)
Use get-presigned-url com nome .zip (ex.: images.zip).
GET https://detect-image.truthscan.com/get-presigned-url?file_name=images.zip
Exemplo de requisição
curl -X GET 'https://detect-image.truthscan.com/get-presigned-url?file_name=images.zip' \
--header 'apikey: YOUR API KEY GOES HERE'
2. Enviar o ZIP
PUT do ZIP na URL pré-assinada com Content-Type: application/zip.
PDF dentro do ZIP não é suportado e será ignorado.
SVG é convertido para PNG antes da detecção.
3. Enviar ZIP para detecção em lote
POST /bulk-upload com key e url apontando para o caminho do ZIP enviado.
Parâmetros opcionais
generate_preview: true para gerar URLs de prévia por imagem (padrão: false).
generate_analysis_details: true para análise detalhada (padrão: false).
generate_heatmap: Quando false, pula a geração de mapa de calor por completo (padrão: true). Mapas de calor só são produzidos para imagens classificadas como IA quando true. Imagens reais nunca recebem mapa de calor.
generate_heatmap_overlayed: Mesmo comportamento de /detect (sobreposição vs RGBA transparente). Aplica-se somente quando generate_heatmap é true e a imagem é classificada como gerada por IA.
generate_heatmap_normalized: Mesmo comportamento de /detect (padrão: true). Aplica-se somente quando generate_heatmap é true e a imagem é classificada como gerada por IA.
model: Domínio do modelo: generic ou instance_id/model.
Validação dos flags de heatmap
Se generate_heatmap for false, não defina explicitamente generate_heatmap_overlayed ou generate_heatmap_normalized como true. A API retorna 422 Unprocessable Entity com mensagens como "generate_heatmap_overlayed cannot be true when generate_heatmap is false." ou "generate_heatmap_normalized cannot be true when generate_heatmap is false."
Resposta "healthy" indica que o serviço está operando normalmente.
Erros
A maioria dos erros vem de parâmetros incorretos. Revise cada chamada e use os exemplos.
Os códigos de erro seguem o padrão REST:
Código
Significado
400
Bad Request — Requisição inválida.
401
Unauthorized — Segredo do job inválido (endpoints internos) ou falha de autenticação similar.
403
Forbidden — Chave de API inválida, acesso negado ou créditos insuficientes.
404
Not Found — Recurso não encontrado.
405
Method Not Allowed — Método HTTP inválido para o recurso.
406
Not Acceptable — Formato solicitado não é JSON.
410
Gone — Recurso neste endpoint foi removido.
422
Invalid Request Body — Corpo mal formatado, inválido ou com parâmetros faltando.
429
Too Many Requests — Você ultrapassou o limite de taxa da sua chave de API (veja Limites de taxa). O corpo é {"error":"Too many requests"}; o cabeçalho X-RateLimit-Retry-After indica os segundos a aguardar antes de tentar novamente.
500
Internal Server Error — Erro no servidor; tente novamente mais tarde.
503
Service Unavailable — Manutenção ou sobrecarga; tente novamente mais tarde.
Problemas comuns e soluções
Autenticação
"User verification failed" (403)
Causa: Chave de API inválida ou expirada
Solução:
Confirme se a chave está correta
Verifique se a chave está ativa na conta
Gere uma nova chave se necessário
"Not enough credits" (403)
Causa: Créditos insuficientes para processar a imagem
Solução:
Consulte créditos restantes com /check-user-credits
Compre créditos adicionais se precisar
Validação de entrada
"Input URL cannot be empty" (400)
Causa: URL vazia ou inválida
Solução:
Garanta que url não está vazia
Remova espaços extras nos nomes de arquivo
Verifique a codificação da URL
"Input email is empty" (400)
Causa: E-mail ausente para processamento por URL
Solução:
Informe um e-mail válido ao enviar URLs
Verifique o formato do e-mail
"Unsupported image type" (400)
Causa: Formato não suportado
Solução:
Converta para um formato suportado (JPG, PNG, WebP, HEIC, HEIF, AVIF, BMP, TIFF, GIF, SVG, PDF)
Confira a extensão do arquivo
"File size is too small" (400)
Causa: Arquivo abaixo do tamanho mínimo
Solução:
Use um arquivo maior (mínimo 1 KB)
Verifique se o arquivo não corrompeu no upload
"File size exceeds limit" (400)
Causa: Arquivo muito grande
Solução:
Comprima ou redimensione; o limite em MB aparece na mensagem de erro da API
Use outro formato de imagem
"Invalid file type" (400)
Causa: Validação de tipo falhou
Solução:
Confirme que é um formato de imagem válido
Verifique se o arquivo não está corrompido
MIME type e extensão devem coincidir
Processamento
Status da imagem "failed"
Causa: Falha no processamento por diversos motivos
Solução:
Confirme formato de URL suportado
Verifique se o arquivo é válido e não corrompido
Atenda aos requisitos de tamanho
Entre em contato com o suporte se persistir
"User not found"
Causa: ID de usuário inválido
Solução:
Confirme o ID do usuário
A conta deve estar ativa
Reautentique se necessário
"File metadata could not be fetched" (500)
Causa: Não foi possível acessar o arquivo enviado
Solução:
Confirme que o upload foi concluído
A URL do arquivo deve estar acessível
Tente enviar novamente
O resultado é AI Generated, mas quem enviou diz que a foto é real
Verifique primeiro final_label_confidence e analysis_results.agreement; uma confiança na faixa do meio ou um agreement fraco significa que o modelo não tem certeza. Verifique warnings em busca de blur_dark ou screen_recapture, que muitas vezes explicam uma pontuação ruim em uma foto real. Em qualquer um dos casos, peça uma nova captura ao vivo pelo TruthScan Capture em vez de decidir de forma definitiva sobre o original. Se a nova captura também for sinalizada, encaminhe para revisão com os dois resultados anexados.
Upload
"Image upload failed" (403/400)
Causa: URL pré-assinada inválida/expirada ou problema no armazenamento
Solução:
Use a URL pré-assinada logo após recebê-la
Content-Type deve corresponder ao formato
Remova espaços do nome antes do upload
Gere nova URL pré-assinada se necessário
"Invalid pre-signed URL" (400)
Causa: Nome com espaços ou URL pré-assinada expirada/corrompida
Solução:
Remova espaços do nome antes de solicitar a URL pré-assinada
Use letras, números, hífens e sublinhados
Gere nova URL pré-assinada se necessário
Upload em lote
"URL must point to a ZIP file" (400)
Causa: A URL em /bulk-upload não aponta para um ZIP
Solução:
Use get-presigned-url?file_name=images.zip (ou outro .zip)
Envie um ZIP válido para a URL pré-assinada
Garanta que bulk-upload use a URL do ZIP enviado
"ZIP file too large" (400)
Causa: ZIP acima de 100 MB
Solução:
Reduza imagens ou comprima
Divida em vários lotes
"Too many files" (400)
Causa: ZIP com mais de 50 imagens válidas
Solução:
Limite a 50 imagens por ZIP
Divida em vários lotes
"No valid images found in ZIP" (400)
Causa: Todos os arquivos foram ignorados (formato, tamanho, caminho etc.)
Respostas às dúvidas mais comuns sobre a API de detecção de imagens por IA.
Na sua conta TruthScan (portal do desenvolvedor). A chave aparece no topo da página da conta.
JPG, JPEG, PNG, WebP, JFIF, HEIC, HEIF, AVIF, BMP, TIFF, TIF, GIF, SVG e PDF. Para PDF, apenas a primeira imagem no fluxo de arquivo único. PDF dentro de ZIP em lote é ignorado.
Arquivos únicos: mínimo 1 KB, máximo 10 MB. ZIP em lote: até 100 MB por arquivo, até 50 imagens por lote, cada imagem 1 KB–10 MB.
1) Obter URL pré-assinada, 2) Enviar com PUT e Content-Type correto, 3) POST /detect com key e url montada a partir do file_path. Use /query para consultar resultados.
Na API upstream: generate_preview padrão true; generate_analysis_details padrão true. Defina explicitamente se precisar de outro comportamento.
Solicite URL pré-assinada para .zip, envie o ZIP, POST /bulk-upload, depois consulte /query com o id retornado. PDFs no ZIP são ignorados; SVGs viram PNG.
Cada detecção bem-sucedida consome créditos. Consulte /check-user-credits. Em lote: só imagens analisadas com sucesso são cobradas.
1 = só metadados; 2 = metadados e ocr; 3 = metadados, ocr e ml_model (pipeline completa).
Com generate_analysis_details true, consulte /query para analysis_results_status. Quando ready, analysis_results inclui agreement, imageTags, confidence, keyIndicators, detailedReasoning, visualPatterns e recommendations.
Não recuse automaticamente com base em um único resultado. Encaminhe pontuações limítrofes para revisão, ou envie a quem enviou um link do TruthScan Capture para tirar a foto de novo ao vivo. Veja Como tratar resultados sinalizados.
Sim. Cada chave de API tem um orçamento de requisições por minuto — 250 por padrão. Endpoints de escrita (/detect, /bulk-upload) contam peso 1; endpoints de leitura (/get-presigned-url, /check-user-credits, /heatmap/{id}, /preview/{id}) contam peso 0,2. /query e /health não são limitados. Ao ultrapassar, você recebe HTTP 429 com X-RateLimit-Retry-After. Fale conosco se precisar de um limite maior.