Browse docsshow

Task lifecycle

Every verify() or submit() call creates a task. Here's every state it can be in and what triggers each transition.

States

StatusWhat it means
pendingJust created. The verification agent hasn't run yet.
agent_runningThe LLM judge is currently evaluating. Usually completes in <2s.
human_neededAgent's confidence was below the threshold. Task is in the reviewer queue at review.tobeverified.com, waiting for a human verdict.
completedFinal verdict recorded. final_verdict, final_tier ('agent' or 'human'), and completed_at are set.

Transitions

text
pending
   ↓  (verification agent starts)
agent_running
   ↓  ┌──────────────────────────────────┐
       │ if confidence ≥ threshold         │
       ↓                                  │
   completed (final_tier='agent')        │
                                          │
       │ if confidence < threshold         │
       ↓                                  │
   human_needed                           │
       ↓  (reviewer submits verdict)     │
   completed (final_tier='human')         │
                                          ▼

Attempts

Every verification agent run is recorded as an attempt on the task. A typical completed-via-agent task has one agent attempt; a human-resolved task has one agent attempt followed by one human attempt.

json
{
  "id": "tsk_8392c01307b6ac3e",
  "status": "completed",
  "final_verdict": "yes",
  "final_tier": "human",
  "final_confidence": 1.0,
  "created_at": 1715284800.123,
  "completed_at": 1715284910.456,
  "attempts": [
    {
      "tier": "agent",
      "verdict": "yes",
      "confidence": 0.62,
      "rationale": "Customer says 'I want my money back' explicitly...",
      "created_at": 1715284800.789,
      "duration_ms": 420
    },
    {
      "tier": "human",
      "verdict": "yes",
      "confidence": 1.0,
      "rationale": "Confirmed — they're requesting a refund.",
      "reviewer_user_id": "u_abc123",
      "created_at": 1715284910.456,
      "duration_ms": 0
    }
  ]
}

Polling

The SDKs' verify() method handles polling internally. The polling loop:

  1. · Default poll interval: 1.5 sec
  2. · Default timeout: 300 sec (5 min)
  3. · Returns when status === 'completed'
  4. · Throws TBVTimeoutError if the timeout elapses (task may still be in human_needed)

For long-running flows where you don't want to hold a connection, use submit() + get() with your own polling cadence. Webhooks are coming in a later release.

Retries & idempotency

v0.5 doesn't yet support idempotency keys. Each POST /v1/tasks creates a new task; if the network fails before you get a task ID back, retrying will create a duplicate. We recommend wrapping submit() in your own deduplication if your code path is at-least-once.

Daily caps

Accounts on the preview plan are subject to a global daily task cap. If you're hitting 429 Too Many Requests, ping us — we'll raise it.