# StepRecord

The StepRecord object of the Kaabist API.

| Field | Type | Required | Description |
|---|---|---|---|
| `step_path` | string | yes |  |
| `iteration` | integer | yes | ≥ 0 |
| `attempt` | integer | yes | ≥ 0 |
| `action` | string | yes |  |
| `status` | `"ok"`, `"failed"`, `"skipped"`, `"parked"` | yes |  |
| `tier` | `"http"`, `"browser"`, `"stealth"` | yes |  |
| `started_at` | string (date-time) | yes |  |
| `finished_at` | string or null (date-time) | yes |  |
| `duration_ms` | integer or null | yes | ≥ 0 |
| `snapshot` | string or null | yes |  |
| `screenshot` | string or null | yes |  |
| `error` | object or null | yes |  |
| `error.code` | enum (58 values) | yes | one of `"blocked"`, `"timeout"`, `"session_expired"`, `"validation_failed"`, `"input_expired"`, `"side_effect_ambiguous"`, `"insufficient_credits"`, `"max_credits_exceeded"`, `"max_tier_exceeded"`, `"max_steps_exceeded"`, `"ssrf_blocked"`, `"target_disallowed"`, `"byo_proxy_unreachable"`, `"byo_proxy_blocked"`, `"byo_llm_auth_failed"`, `"byo_llm_rate_limited"`, `"byo_llm_quota_exceeded"`, `"byo_captcha_auth_failed"`, `"byo_captcha_balance"`, `"byo_provider_failing"`, `"byo_in_use"`, `"program_invalid"`, `"request_invalid"`, `"idempotency_conflict"`, `"session_locked_timeout"`, `"session_locked"`, `"session_engine_mismatch"`, `"job_not_waiting"`, `"fence_open"`, `"loop_exhausted"`, `"target_ambiguous"`, `"canceled"`, `"not_found"`, `"program_not_found"`, `"program_has_schedules"`, `"secret_storage_disabled"`, `"not_implemented"`, `"two_factor_required"`, `"reauth_required"`, `"rate_limited"`, `"payment_method_required"`, `"billing_unavailable"`, `"test_quota_exceeded"`, `"plan_required"`, `"plan_managed"`, `"login_flow_rate_limited"`, `"schedule_interval_too_small"`, `"live_unavailable"`, `"pdf_not_pdf"`, `"pdf_too_large"`, `"pdf_malware"`, `"pdf_scanner_unavailable"`, `"pdf_encrypted"`, `"pdf_too_complex"`, `"pdf_malformed"`, `"pdf_active_content"`, `"pdf_source_missing"`, `"internal"` |
| `error.message` | string | yes |  |
| `error.tier` | `"http"`, `"browser"`, `"stealth"`, `null` | yes |  |
| `error.retryable` | boolean | yes |  |
| `error.step` | string or null | yes |  |
| `error.snapshot` | string or null |  |  |
| `error.details` | map of any |  |  |
| `warnings` | object[] | yes |  |
| `warnings[].code` | enum (19 values) | yes | one of `"null_marker"`, `"parse_failed"`, `"out_of_range"`, `"required_missing"`, `"list_short"`, `"fill_rate_drop"`, `"escalated"`, `"healed_locator_used"`, `"obstacle_dismissed"`, `"field_empty"`, `"step_skipped"`, `"cache_hit"`, `"byo_fallback_used"`, `"pdf_source_not_extractable"`, `"pdf_no_text"`, `"pdf_pages_truncated"`, `"redirect_not_followed"`, `"pagination_incomplete"`, `"captcha_inject_navigated"` |
| `warnings[].field` | string or null |  |  |
| `warnings[].raw` | string or null |  |  |
| `warnings[].step` | string or null |  |  |
| `warnings[].message` | string |  |  |
| `warnings[].detail` | string |  |  |
| `warnings[].count` | integer |  | ≥ 1 |
| `warnings[].of` | integer |  | ≥ 0 |
| `warnings[].hint` | object |  |  |
| `warnings[].hint.date_format` | string |  |  |
| `warnings[].hint.date_formats` | string[] |  |  |
| `warnings[].hint.ambiguous` | `true` |  |  |
| `warnings[].hint.locale` | string |  |  |
| `healed` | object or null | yes |  |
| `healed.target` | string | yes |  |
| `healed.from` | map of any | yes |  |
| `healed.to` | map of any | yes |  |
| `healed.confidence` | number | yes | ≥ 0 · ≤ 1 |
| `healed.proposal_id` | string or null | yes | pattern `^prp_[0-9a-hjkmnp-tv-z]{26}$` |
| `obstacle` | object or null | yes |  |
| `result_preview` | string or null | yes |  |

## Example

```json
{
  "step_path": "steps[7]",
  "iteration": 0,
  "attempt": 0,
  "action": "extract",
  "status": "ok",
  "tier": "browser",
  "started_at": "2026-09-18T10:00:00Z",
  "finished_at": "2026-09-18T10:00:02Z",
  "duration_ms": 2000,
  "snapshot": "/v1/jobs/job_01j9zqk3q7m4n5p6r7s8t9v0wx/snapshot?step=steps[7]",
  "screenshot": null,
  "error": null,
  "warnings": [],
  "healed": {
    "target": "extract.rows[].amount",
    "from": {
      "selector": "td:nth-child(3)"
    },
    "to": {
      "css": "td[data-col=amount]"
    },
    "confidence": 0.94,
    "proposal_id": "prp_01j9zqk3q7m4n5p6r7s8t9v0wx"
  },
  "obstacle": null,
  "result_preview": null
}
```
