curl --request POST \
--url https://api.gotrebol.com/verifications/{verification-id}/findings/run \
--header 'x-api-key: <api-key>'import requests
url = "https://api.gotrebol.com/verifications/{verification-id}/findings/run"
headers = {"x-api-key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.gotrebol.com/verifications/{verification-id}/findings/run', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gotrebol.com/verifications/{verification-id}/findings/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.gotrebol.com/verifications/{verification-id}/findings/run"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gotrebol.com/verifications/{verification-id}/findings/run")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gotrebol.com/verifications/{verification-id}/findings/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"status": "queued"
}Ejecutar la Síntesis de Dictamen bajo demanda
Encola una corrida de la Síntesis de Dictamen (findings) para la verificación, sin esperar a que un nuevo documento la dispare automáticamente.
La corrida pasa por el mismo pipeline con deduplicación que usan las corridas automáticas, así que nunca genera corridas duplicadas.
La respuesta es asíncrona. El endpoint responde 202 en cuanto la corrida queda encolada, sin esperar a que termine; la corrida tarda unos segundos y su resultado se lee en el campo findings de Obtener una verificación por su ID. Para saber que terminó, guarda el findings.computed_at que tenías antes de llamar y consulta la verificación cada 3-5 segundos hasta que ese valor cambie (o hasta que findings deje de ser null, si nunca había corrido). Un límite de ~2 minutos es holgado; si se agota, vuelve a consultar más tarde en vez de reintentar el POST, porque la corrida encolada sigue en curso.
A diferencia de las corridas automáticas, una corrida pedida por este endpoint no exige que haya cambiado algún documento: varios hallazgos dependen de la vigencia de los documentos, así que las conclusiones pueden cambiar con el calendario aunque las entradas sean idénticas. Para acotar el costo hay un periodo mínimo entre corridas manuales (300 segundos por defecto), que se reporta como recently_run.
El POST no lleva body; la verificación se identifica por la URL.
Devuelve 409 con un error_code cuando la corrida no procede. Qué hacer en cada caso:
error_code | Qué pasó | Qué hacer |
|---|---|---|
not_enabled | La cuenta no tiene habilitada la Síntesis de Dictamen. | No es activable por API: escríbenos para habilitarla. Reintentar no cambia el resultado. |
pending_documents | Hay documentos requeridos sin subir o aún en procesamiento. | Sube los que falten. Para saber cuándo reintentar, consulta la verificación y espera a que los items que lista pending_items tengan item_status: "complete"; no reintentes el POST a ciegas. |
already_scheduled | Ya hay una corrida encolada o en ejecución. | No reintentes el POST: ya vas a recibir el resultado. Pasa directo a sondear findings.computed_at, igual que tras un 202. |
recently_run | Hubo una corrida hace muy poco y sigue el periodo mínimo entre corridas manuales. | Espera los segundos que indica retry_after_seconds y vuelve a pedirla. |
Un segundo POST mientras hay una corrida en vuelo responde 409 already_scheduled, nunca un 202 que duplique la corrida.
Para los códigos de error generales de la API (401, 404, 500), consulta Errores.
Ejemplo
curl -X POST "https://api.gotrebol.com/verifications/{verification-id}/findings/run" \
-H "x-api-key: TU_API_KEY"
Sustituye {verification-id} por el id que te devolvió POST /verifications y
TU_API_KEY por tu API key. Si la corrida queda encolada, la respuesta es:
{ "status": "queued" }
Y el ciclo completo, pidiendo la corrida y esperando su resultado:
const verificationId = "c8dc41fc-c477-404e-aff7-b9074f86d6d1"; // el id de tu verificación
const headers = { "x-api-key": process.env.TREBOL_API_KEY };
const base = `https://api.gotrebol.com/verifications/${verificationId}`;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
// fetch no rechaza ante un status de error: hay que revisarlo a mano, o un
// 401 durante el sondeo se ve igual que "todavía no termina".
async function getVerification() {
const res = await fetch(base, { headers });
if (!res.ok) throw new Error(`Trébol respondió ${res.status}`);
return res.json();
}
// 1. Guarda el computed_at actual: es la referencia para saber si ya corrió.
const previous = (await getVerification()).findings?.computed_at ?? null;
// 2. Pide la corrida, reintentando cuando el cooldown lo pide.
while (true) {
const run = await fetch(`${base}/findings/run`, { method: "POST", headers });
if (run.status === 202) break;
if (run.status !== 409) throw new Error(`Trébol respondió ${run.status}`);
const { error_code, retry_after_seconds } = await run.json();
// Ya hay una corrida en vuelo: su resultado es el que esperas igual.
if (error_code === "already_scheduled") break;
// Corrió hace poco. Es el caso normal al revalidar por vigencia.
if (error_code === "recently_run") {
await sleep((retry_after_seconds ?? 60) * 1000);
continue;
}
// not_enabled y pending_documents no se resuelven reintentando.
throw new Error(`corrida rechazada: ${error_code}`);
}
// 3. Sondea hasta que computed_at cambie (~2 min es holgado).
const deadline = Date.now() + 120_000;
while (Date.now() < deadline) {
await sleep(4000);
const { findings } = await getVerification();
if (findings?.computed_at && findings.computed_at !== previous) {
return findings; // hallazgos frescos
}
}
// Se agotó la espera. La corrida sigue en curso: no es un fallo, así que
// devuelve los hallazgos que ya tenías y vuelve a consultar más tarde.
return (await getVerification()).findings;
curl --request POST \
--url https://api.gotrebol.com/verifications/{verification-id}/findings/run \
--header 'x-api-key: <api-key>'import requests
url = "https://api.gotrebol.com/verifications/{verification-id}/findings/run"
headers = {"x-api-key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.gotrebol.com/verifications/{verification-id}/findings/run', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gotrebol.com/verifications/{verification-id}/findings/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.gotrebol.com/verifications/{verification-id}/findings/run"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gotrebol.com/verifications/{verification-id}/findings/run")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gotrebol.com/verifications/{verification-id}/findings/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"status": "queued"
}Was this page helpful?