---
title: "POST /uploads/{id}/factor-agent/jobs/{documentJobId}/context"
method: POST
path: "/uploads/{id}/factor-agent/jobs/{documentJobId}/context"
tags: ["Uploads"]
---

# POST /uploads/{id}/factor-agent/jobs/{documentJobId}/context

`POST /uploads/{id}/factor-agent/jobs/{documentJobId}/context`

The post-read dialog's answers to an analyze job waiting in awaiting_context. They are validated against the job's questions, stored with the job's id and the caller, and the job resumes at once (queued, no awaitingContext). Answers may be empty or partial.

## Path parameters

- `id` integer, required
- `documentJobId` string, required

## Request body

- DocumentJobContextAnswerRequest
  - `answers` LedgerContextAnswer[] — May be empty or partial; an unanswered question takes the deadline's rule.
    - `choice` string, required — One of the question's choices.
    - `exclusionReason` 'transfer_or_subvention' | 'financial_charges' | 'payroll_or_pension' | 'student_or_member_support' | 'fees_and_registration' | 'water' | 'waste_billed_separately' | 'tax_or_levy' | 'internal_or_balancing' | 'insurance_or_protection' | 'other'
    - `questionId` string, required
  - `note` string

## Response `200`

The job, queued again without awaitingContext

- DocumentJobResponse
  - `data` DocumentJob, required
    - `cancelRequested` boolean — A cancel stands for this live job: its delivery ends it cancelled between units. Absent once the job has ended, and on a job never asked to stop.
    - `createdAt` string, date-time, required
    - `error` string
    - `errorCode` string — Why a failed job failed, e.g. ANALYSIS_ALREADY_STARTED, ANALYSIS_CHANGED, CONFIRMATION_REQUIRED, NOTHING_TO_SUBMIT, PROMPT_REQUIRED, PROMPT_TOO_LONG, FACTOR_AGENT_FAILED, ANALYSIS_FAILED, INVALID_STATE, NOT_FOUND, INTERRUPTED (three deliveries ended without a word), RETRIES_EXHAUSTED (six failures worth retrying in a row), DISPATCH_FAILED (no delivery came for 30 minutes), DOCUMENT_TOO_LARGE (an analysis of a document over 25,000 rows, or whose extracted data is over 64 MiB; the message says which), ROW_EXCLUDED (a submit job that met a row a reviewer excluded), SOURCE_TOTAL_UNRECONCILED (a submit of an analysis whose money does not tie, or of a ledger one of whose non-carbon records was deleted since its analysis: the message names how many; nothing is submitted), MONEY_UNRECONCILED (money that does not tie in a ledger: a ledger store whose stored rows do not hold the read's money, or a ledger submit whose records and unsubmitted rows do not add up to its total, the message naming any missing records; the committed rows stay, and the upload reads unsubmitted), LEDGER_CATEGORIES_OVER_LIMIT (a factor catalog over the 500 categories a ledger's account decisions take). A regroup job's own: ROW_SUBMITTED (a row it would move, or of the account it would exclude, was submitted), UPLOAD_SUBMITTED, ANALYSIS_NOT_REVIEWABLE, INVALID_REGROUP (the include or exclude no longer applies to the analysis); a regroup that fails before its rows moved gives the analysis back its status and message, one that fails after leaves it "error" (Re Analysis mends it). A cancelled job's is CANCELLED, with the error "Cancelled".
    - `finishedAt` string, date-time
    - `jobId` string, required
    - `kind` 'analyze' | 'submit' | 'regroup', required
    - `progress` DocumentJobProgress
      - `awaitingContext` DocumentJobAwaitingContext — An analyze job parked for answers (status queued, phase awaiting_context).
        - `currency` string, required
        - `deadline` string, date-time, required — When the job goes on without answers.
        - `questions` LedgerContextQuestion[], required
          - `choices` string[], required
          - `code` string, required
          - `confidence` 'high' | 'medium' | 'low', required
          - `exclusionReason` 'transfer_or_subvention' | 'financial_charges' | 'payroll_or_pension' | 'student_or_member_support' | 'fees_and_registration' | 'water' | 'waste_billed_separately' | 'tax_or_levy' | 'internal_or_balancing' | 'insurance_or_protection' | 'other'
          - `id` string, required — "journal|RACCR", "account|2915", "creditor|CXHLG01".
          - `label` string, required
          - `meaning` string
          - `name` string
          - `netCents` integer, required
          - `proposal` string, required — The pre-selected choice.
          - `reason` string
          - `rows` integer, required
          - `subject` 'journal' | 'account' | 'creditor', required
        - `secondsLeft` integer, required — Whole seconds to the deadline by the server's clock when it answered; a client counts down from this, not from deadline against its own clock.
      - `done` integer, required — Rows done.
      - `message` string
      - `phase` string, required — awaiting_context: an analyze job (status queued) waits for the post-read dialog's answers, in awaitingContext, until its deadline (POST .../jobs/{documentJobId}/context answers them). A regroup job's phases and their messages, in order: regroup_classify "Deciding the new keys", regroup_apply "Moving the rows", regroup_match "Matching emission factors", regroup_duplicates "Checking duplicate spend lines", regroup_finish "Finishing the review"; its done and total count the rows it moves (a job not yet past its first unit has no progress).
      - `total` integer, required — Rows to do.
    - `result` object — A finished job's result. A submit job's is the submit result, whose emission counts only the emission rows the job inserted (the synchronous submit's counts every row it submitted).
    - `startedAt` string, date-time
    - `status` 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled', required
    - `uploadId` integer, required

## Other responses

- `400` — VALIDATION_ERROR: an unknown questionId, a question answered twice, a choice the question does not offer, an exclusionReason not of the ten or on anything but an account answered exclude, or more than 50 answers (details.field "answers"); a note over 1,000 characters (details.field "note").
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `409` — CONTEXT_CLOSED: the job no longer waits (the deadline delivery claimed it, it finished, or it never waited); nothing is stored.

## Changes

- **2026-10-04** `77d466d0e73d` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/greentally/apis/esgai-api/changes/uploads/:id/factor-agent/jobs/:documentJobId/context/post.md)

---

[API](https://skmtc.dev/greentally/apis/esgai-api.md) · [All operations](https://skmtc.dev/greentally/apis/esgai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/greentally/apis/esgai-api/revisions/77d466d0e73d?raw)
