Get Validation Results (v2)
curl --request GET \
--url https://api.example.com/api/v2/jobs/{job_id}import requests
url = "https://api.example.com/api/v2/jobs/{job_id}"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v2/jobs/{job_id}', 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.example.com/api/v2/jobs/{job_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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.example.com/api/v2/jobs/{job_id}"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v2/jobs/{job_id}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v2/jobs/{job_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "processing",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"progress": { "step": "verify" }
}
{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "completed",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"progress": { "step": "synthesize" },
"model": "anthropic/claude-sonnet-4-6",
"extracted_text": "Hey, the quarterly board meeting just wrapped...",
"result": {
"overall_status": "do not send",
"summary": { "critical": 3, "major": 0, "medium": 0, "minor": 0 },
"revalidation_recommended": true,
"email_profile": {
"communication_intent": "advisory",
"tone": "urgent",
"audience_signals": [
"Recipient's family holds a position in the sender's company stock",
"Sender has fiduciary or insider access to material non-public information"
],
"claims": {
"forward_looking": ["Full-year guidance will be revised downward by 10%"],
"performance": ["Company missed quarterly revenue targets by $15 million"],
"promissory": [],
"comparative": []
},
"disclosures_present": [],
"data_cited": ["$15 million revenue shortfall versus quarterly targets"]
},
"violations": [
{
"signal_id": "signal_mnpi_leak",
"signal_name": "Material Non-Public Information (AI)",
"severity": "Critical",
"confidence": "high",
"quote": "Sell before the official press release drops on Tuesday.",
"char_from": 229,
"char_to": 285,
"page": 1,
"reasoning": "This is an explicit trading instruction predicated entirely on MNPI...",
"verifier_note": "Quote appears verbatim and constitutes an explicit, time-bound trading instruction predicated on MNPI.",
"fix": {
"action": "replace",
"suggested_text": "Remove this sentence entirely. Trading recommendations must never be based on material non-public information.",
"fix_note": "May contain material non-public information (MNPI). Violation of SEC Rule 10b-5 and FINRA Rule 2010."
}
}
]
}
}
{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "failed",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"error": "LLM provider unavailable"
}
{
"api_version": "v2",
"error": { "code": "not_found", "message": "Job a1b2c3d4e5f6 not found" }
}
Validation (v2)
Get Validation Results (v2)
Retrieve the result of an agentic email-validation job
GET
/
api
/
v2
/
jobs
/
{job_id}
Get Validation Results (v2)
curl --request GET \
--url https://api.example.com/api/v2/jobs/{job_id}import requests
url = "https://api.example.com/api/v2/jobs/{job_id}"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v2/jobs/{job_id}', 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.example.com/api/v2/jobs/{job_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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.example.com/api/v2/jobs/{job_id}"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v2/jobs/{job_id}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v2/jobs/{job_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "processing",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"progress": { "step": "verify" }
}
{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "completed",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"progress": { "step": "synthesize" },
"model": "anthropic/claude-sonnet-4-6",
"extracted_text": "Hey, the quarterly board meeting just wrapped...",
"result": {
"overall_status": "do not send",
"summary": { "critical": 3, "major": 0, "medium": 0, "minor": 0 },
"revalidation_recommended": true,
"email_profile": {
"communication_intent": "advisory",
"tone": "urgent",
"audience_signals": [
"Recipient's family holds a position in the sender's company stock",
"Sender has fiduciary or insider access to material non-public information"
],
"claims": {
"forward_looking": ["Full-year guidance will be revised downward by 10%"],
"performance": ["Company missed quarterly revenue targets by $15 million"],
"promissory": [],
"comparative": []
},
"disclosures_present": [],
"data_cited": ["$15 million revenue shortfall versus quarterly targets"]
},
"violations": [
{
"signal_id": "signal_mnpi_leak",
"signal_name": "Material Non-Public Information (AI)",
"severity": "Critical",
"confidence": "high",
"quote": "Sell before the official press release drops on Tuesday.",
"char_from": 229,
"char_to": 285,
"page": 1,
"reasoning": "This is an explicit trading instruction predicated entirely on MNPI...",
"verifier_note": "Quote appears verbatim and constitutes an explicit, time-bound trading instruction predicated on MNPI.",
"fix": {
"action": "replace",
"suggested_text": "Remove this sentence entirely. Trading recommendations must never be based on material non-public information.",
"fix_note": "May contain material non-public information (MNPI). Violation of SEC Rule 10b-5 and FINRA Rule 2010."
}
}
]
}
}
{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "failed",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"error": "LLM provider unavailable"
}
{
"api_version": "v2",
"error": { "code": "not_found", "message": "Job a1b2c3d4e5f6 not found" }
}
Retrieve the status and result of a v2 validation job. Poll this endpoint until
status is completed or failed. The result is read-only and returns the
full agentic output, including any fields that were offloaded to storage for
large responses.
Path Parameters
The
job_id returned by
Validate Email (v2).Response
Always
v2.Unique identifier for the validation job.
Job status:
queued, processing, completed, or failed.ISO 8601 UTC timestamp when the job was created, e.g.
2026-06-25T12:00:00.123456+00:00.Current pipeline step (while processing, when available).
Show progress properties
Show progress properties
Current graph node, e.g.
analyze_email, evaluate_batch, verify,
synthesize.The provider/model used, e.g.
anthropic/claude-sonnet-4-6 (present when
completed).The email text the validator evaluated (present when completed).
The validation result (present when
status is completed).Show result properties
Show result properties
Overall assessment:
approved, needs_changes, or do not send. Note:
do not send contains spaces — this matches the API response exactly.The agent’s structured read of the email — intent, tone, claims, audience
signals, disclosures present, data cited, products referenced.
Signal-based findings from the agentic engine.
Show violation properties
Show violation properties
Signal identifier, e.g.
signal_mnpi_leak.Human-readable signal name, e.g.
Material Non-Public Information (AI).Critical, Major, Medium, or Minor.Confidence after adversarial verification:
high, medium, or low.The offending text, verbatim.
Start character offset of the quote.
End character offset of the quote.
Page number where the quote appears.
The model’s explanation of why the text violates the signal.
The adversarial verifier’s note (confirms or downgrades the finding).
Signal and regex findings merged into one list.
Deterministic
REGEX / REQUIRE_NEAR rule findings only.True when more than one fix is found, suggesting a re-scan after applying fixes.
Compliant rewrite (only when the rewrite loop is enabled and produced one).
Number of rewrite iterations (present with
rewritten_text).Array of strings — non-fatal warning messages for this run. Currently emitted when your account’s
custom rules could not be loaded and were therefore not evaluated — surfaced so a partial
evaluation is never invisible. Omitted (or empty) when there are no warnings.
Whether your account’s custom rules were evaluated this run:
true when they
were applied (or there were none to apply), false when custom-rule loading
failed (paired with a warnings entry). Absent for requests with no customer
context (no custom-rule load attempted).Error detail. The shape depends on the error class:
- Job failure (HTTP
200,status=failed): a string message, e.g."LLM provider unavailable". - Request error (HTTP
400/404/500): an object{ "code": string, "message": string }— see the error table and the 404 example below.
Status Values
| Status | Description |
|---|---|
queued | Job created and queued for processing |
processing | Agentic validation in progress |
completed | Validation completed successfully |
failed | Validation failed with error |
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | missing_job_id | job_id is required |
| 404 | not_found | No job exists for the given job_id |
| 500 | internal_error | Unexpected server error |
{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "processing",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"progress": { "step": "verify" }
}
{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "completed",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"progress": { "step": "synthesize" },
"model": "anthropic/claude-sonnet-4-6",
"extracted_text": "Hey, the quarterly board meeting just wrapped...",
"result": {
"overall_status": "do not send",
"summary": { "critical": 3, "major": 0, "medium": 0, "minor": 0 },
"revalidation_recommended": true,
"email_profile": {
"communication_intent": "advisory",
"tone": "urgent",
"audience_signals": [
"Recipient's family holds a position in the sender's company stock",
"Sender has fiduciary or insider access to material non-public information"
],
"claims": {
"forward_looking": ["Full-year guidance will be revised downward by 10%"],
"performance": ["Company missed quarterly revenue targets by $15 million"],
"promissory": [],
"comparative": []
},
"disclosures_present": [],
"data_cited": ["$15 million revenue shortfall versus quarterly targets"]
},
"violations": [
{
"signal_id": "signal_mnpi_leak",
"signal_name": "Material Non-Public Information (AI)",
"severity": "Critical",
"confidence": "high",
"quote": "Sell before the official press release drops on Tuesday.",
"char_from": 229,
"char_to": 285,
"page": 1,
"reasoning": "This is an explicit trading instruction predicated entirely on MNPI...",
"verifier_note": "Quote appears verbatim and constitutes an explicit, time-bound trading instruction predicated on MNPI.",
"fix": {
"action": "replace",
"suggested_text": "Remove this sentence entirely. Trading recommendations must never be based on material non-public information.",
"fix_note": "May contain material non-public information (MNPI). Violation of SEC Rule 10b-5 and FINRA Rule 2010."
}
}
]
}
}
{
"api_version": "v2",
"job_id": "a1b2c3d4e5f6",
"status": "failed",
"submitted_at": "2026-06-25T12:00:00.123456+00:00",
"error": "LLM provider unavailable"
}
{
"api_version": "v2",
"error": { "code": "not_found", "message": "Job a1b2c3d4e5f6 not found" }
}
Example
curl "https://{api-url}/api/v2/jobs/a1b2c3d4e5f6" \
-H "x-api-key: YOUR_API_KEY"
import requests
import time
API_KEY = "YOUR_API_KEY"
API_BASE = "https://{api-url}"
def get_results(job_id):
while True:
response = requests.get(
f"{API_BASE}/api/v2/jobs/{job_id}",
headers={"x-api-key": API_KEY}
)
result = response.json()
if result["status"] in ("completed", "failed"):
return result
time.sleep(2)
results = get_results("a1b2c3d4e5f6")
print(results)
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
const API_BASE = 'https://{api-url}';
async function getResults(jobId) {
while (true) {
const response = await axios.get(
`${API_BASE}/api/v2/jobs/${jobId}`,
{ headers: { 'x-api-key': API_KEY } }
);
if (['completed', 'failed'].includes(response.data.status)) {
return response.data;
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
const results = await getResults('a1b2c3d4e5f6');
console.log(results);
⌘I

