---
title: "Generate draft outcomes"
method: POST
path: "/v1/interview_plan_drafts/actions/generate_outcomes"
tags: ["Interview Plan Builder"]
---

# Generate draft outcomes

`POST /v1/interview_plan_drafts/actions/generate_outcomes`

## Request

- Base URL: `https://api.yardstick.team`
- URL: `https://api.yardstick.team/v1/interview_plan_drafts/actions/generate_outcomes`
- Auth: HTTP bearer

Generate draft outcomes

**Required scopes:** `interview_plans:write`

Writes return `data.audit` with audit/event ids. Successful write events and audit rows include the resource type, public draft id, action key, request context, livemode partition, and a redacted payload summary. Use `Idempotency-Key` on retries; replayed requests return the cached response and do not duplicate draft checkpoints, audit rows, or events.

**Seeding from a Source Job.** Pass `source_job_id` (a Job in the same organization, as its `job_<base32>` display id or its raw UUID) to seed the draft's `role_context` from the Job (title, description, group_id/department_label, location, location_type). Caller-provided `role_context` keys override the seeded values per-field; overriding the department emits a non-blocking `department_mismatch` warning in the response `warnings` array. Jobs outside the caller organization, and Jobs in a department the caller cannot read, return 404 `Source Job not found`. `source_job_id` cannot be combined with `resource.id` (returns 400) and is only accepted on `generate_outcomes`; later stages return 400.

**Naming the plan.** `role_context.title` sets the plan title recruiters see in the app, and this is the only place a caller can set it — no later stage action, and no publish or modify_active input, accepts a title. Omit it and the plan falls back to a title derived from the role. It is distinct from `role_context.role_title`, which describes the role being hired for and feeds generation.

**Example (seed-only):**

```bash
curl -X POST https://api.yardstick.team/v1/interview_plan_drafts/actions/generate_outcomes \\
  -H 'Authorization: Bearer ys_sk_live_…' \\
  -H 'Content-Type: application/json' \\
  -H 'Idempotency-Key: $(uuidgen)' \\
  -d '{"action":"interview_plan.generate_outcomes","input":{"source_job_id":"00000000-0000-0000-0000-000000000123","role_context":{}}}'
```

**Example (seed + override):**

```bash
curl -X POST https://api.yardstick.team/v1/interview_plan_drafts/actions/generate_outcomes \\
  -H 'Authorization: Bearer ys_sk_live_…' \\
  -H 'Content-Type: application/json' \\
  -H 'Idempotency-Key: $(uuidgen)' \\
  -d '{"action":"interview_plan.generate_outcomes","input":{"source_job_id":"00000000-0000-0000-0000-000000000123","role_context":{"location":"Remote"}}}'
```

**Example (curl):**

```bash
curl -X POST https://api.yardstick.team/v1/interview_plan_drafts/actions/generate_outcomes \
  -H 'Authorization: Bearer ys_sk_live_…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7c3a…' \
  -d '{"action":"interview_plan.generate_outcomes","input":{"role_context":{"role_title":"Account Executive","title":"Account Executive — Enterprise"}}}'
```

**Example (TypeScript):**

```ts
await fetch("https://api.yardstick.team/v1/interview_plan_drafts/actions/generate_outcomes", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.YS_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    action: "interview_plan.generate_outcomes",
    input: {
      role_context: {
        role_title: "Account Executive",
        title: "Account Executive — Enterprise",
      },
    },
  }),
});
```

## Headers

- `Idempotency-Key` string
- `X-Request-Id` string

## Request body

- object
  - `action` 'interview_plan.generate_outcomes', required
  - `resource` object
    - `type` 'interview_plan_draft', required
    - `id` string
  - `input` object, required
    - `role_context` object, required
      - `title` string
      - `role_title` string
      - `organization_context` string
      - `additional_context` string
      - `location` string
      - `location_type` string
      - `department` string
      - `department_label` string
    - `instructions` string
    - `accepted_outcomes` object[]: Optional caller-supplied outcomes stored verbatim with no AI generation, mirroring accepted_skills/accepted_rounds. When provided, the outcomes checkpoint is written directly from this list — deterministic and LLM-free — so a draft can be bootstrapped without any generation call. Combines with source_job_id (role_context seeding is independent of generation).
      - `id` string
      - `text` string
      - `title` string
      - `description` string
      - `priority` string
      - `tag` string
    - `source_job_id` string: Optional Source Job in the same organization, given as the `job_<base32>` display id or the raw UUID. When provided, the draft's role_context is seeded from the Job (title, description, group_id/department_label, location, location_type). Caller-provided role_context keys override the seeded values per-field. Organization and department enforced — a Source Job in another organization, or in a department the caller cannot read, returns 404 with no existence leak. Only accepted on generate_outcomes; passing source_job_id to later stages returns 400. Cannot be combined with resource.id (returns 400).

## Response `200`

Success

- StagedBuilderActionResponse: Staged interview-plan builder checkpoint response, shared by the generation stages and the verbatim edit actions. `data` echoes the stored stage content (including prune reports on cascading deletes) and `checkpoint.stage_versions` carries the per-stage versions used for `source_stage` preconditions.
  - `resource` object, required
    - `type` 'interview_plan_draft' | 'interview_plan', required
    - `id` string, nullable, required
  - `action` 'interview_plan.generate_outcomes' | 'interview_plan.confirm_outcomes' | 'interview_plan.generate_competencies' | 'interview_plan.generate_skills' | 'interview_plan.generate_rounds' | 'interview_plan.add_rounds' | 'interview_plan.update_rounds' | 'interview_plan.delete_rounds' | 'interview_plan.generate_anchors' | 'interview_plan.generate_questions_directions' | 'interview_plan.add_competencies' | 'interview_plan.update_competencies' | 'interview_plan.delete_competencies' | 'interview_plan.add_skills' | 'interview_plan.update_skills' | 'interview_plan.delete_skills' | 'interview_plan.clear_outcomes' | 'interview_plan.clear_competencies' | 'interview_plan.clear_job_skills' | 'interview_plan.clear_interview_sequence' | 'interview_plan.validate_draft' | 'interview_plan.publish' | 'interview_plan.modify_active' | 'interview_plan.add_questions' | 'interview_plan.update_questions' | 'interview_plan.delete_questions' | 'interview_plan.update_round_directions' | 'interview_plan.update_anchors' | 'interview_plan.delete_anchors', required
  - `execution_mode` 'draft_write' | 'interactive_gate' | 'validate_only' | 'approval_required' | 'blocked_until_verified', required
  - `approval` object, required
    - `gate` 'none' | 'agent_confirmable' | 'dashboard_required', required
    - `required` boolean, required
    - `reason` string, required
  - `stage` string, required
  - `data` object, required
    - `status` 'checkpointed' | 'generated' | 'generation_pending' | 'validated' | 'not_ready' | 'unsupported_stage' | 'approval_required' | 'blocked', required
    - `message` string, required
    - `outcomes` object[]
    - `competencies` object[]
    - `job_skills` object[]
    - `interview_sequence` object[]
    - `questions_and_directions` object
    - `behavioral_anchors` object
    - `round_id` string
    - `questions` object[]
    - `interviewer_directions` string, nullable
    - `candidate_directions` string, nullable
    - `pruned_behavioral_anchor_ids` string[]: Item ids whose behavioral anchors were pruned because their competency was deleted in this request.
    - `pruned_question_round_ids` string[]: Round ids whose questions and directions were pruned because the round was deleted in this request.
    - `generated_round_ids` string[]
    - `generated_competency_ids` string[]
    - `preview` object
    - `affected_counts` object
    - `audit` object
      - `audit_id` string
      - `event_id` string
      - `audit_log` string, required
      - `api_event` string, required
  - `checkpoint` object
    - `stage` string, required
    - `version` integer, required
    - `stage_versions` object, required
  - `validation` object, required
    - `status` 'not_evaluated' | 'ready' | 'blocked', required
    - `publish_ready` boolean, required
    - `blockers` object[], required
      - `code` string, required
      - `message` string, required
      - `path` string
      - `next_action` string
    - `warnings` object[], required
      - `code` string, required
      - `message` string, required
      - `path` string
      - `next_action` string
  - `next_actions` string[], required
  - `web_url` string, nullable, required
  - `request_id` string, required
  - `warnings` object[]: Non-blocking signals emitted by this action (e.g., department_mismatch when source_job_id seeding produced a Department override). Omitted when empty.
    - `code` string, required: Machine-readable warning code (e.g. department_mismatch).
    - `message` string, required
    - `detail` object

## Other responses

- `400`: Invalid request
- `401`: Authentication failure
- `403`: Permission denied (scope or feature flag)
- `404`: Resource not found. The error uses the resource-specific code and param names the exact body field or path parameter that referenced it.
- `409`: Conflict (e.g. idempotency key reuse with different body)
- `429`: Rate limited
- `500`: Internal error

---

[API](https://skmtc.dev/yardstick/apis/yardstick-public-api.md) · [All operations](https://skmtc.dev/yardstick/apis/yardstick-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/yardstick/apis/yardstick-public-api/revisions/bef1d2eaaaa1?raw)
