> ## Documentation Index
> Fetch the complete documentation index at: https://docs.checkfu.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Base URL: https://api.checkfu.com. Current wire version: `2026-08-31` (`Checkfu-Version: 2026-08-31`).
> Mutating HTTP requests require `Authorization: Bearer $CHECKFU_API_KEY`, `Checkfu-Version: 2026-08-31`, `Content-Type: application/json`, and `Idempotency-Key` on retriable writes. Ordinary API keys are Workspace-bound; do not send a Workspace selector header.
> Core workflow: create an Agent (`POST /v1/agents`) and Environment (`POST /v1/environments`), grant `use_environment` (`POST /v1/permission-assignments`), create a Session (`POST /v1/sessions`), send events (`POST /v1/sessions/{id}/events`), stream progress (`GET /v1/sessions/{id}/events/stream`), and read the input result (`GET /v1/sessions/{id}/inputs/{input_id}/result`).
> Domain model: an Agent is mutable configuration; a Session freezes its AgentVersion and Environment at creation and owns its private workspace and ordered event history. Vault stores secret credentials; Connection links an external account; ActionApproval records human approval before an action runs.
> Capability status combines `audience`, `stability`, `availability`, evaluated prerequisites, and release evidence; check https://docs.checkfu.com/getting-started/status (`GET /v1/support/capabilities`) for live `available` status.

# Draft until it meets the rubric

> An Agent drafts, a model scores the draft against a rubric, and a failing score sends the draft and the reason back to the Agent, up to 3 times.

This recipe turns one request into a draft that meets a rubric. A webhook brings the goal and the rubric, the Writer Agent drafts, a Model block scores the draft from 1 to 10, and a score under 8 sends the draft and the reviewer's reason back to the Writer. After 3 drafts the run ends as not passed.

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
request (webhook) → draft (Writer Agent) → grade (score, pass at 8)
                         ↑                      │ fail, up to 3 times
                         └──────────────────────┘
```

> [!WARNING]
>
> The Checkfu CLI and TypeScript SDK are private-alpha artifacts with no self-service public installation channel.
> Part of this flow is behind a rollout fence; a deployment that has not enabled it refuses the request rather than running it.
> Confirm [capability status](https://docs.checkfu.com/getting-started/status.md) before making availability part of your application's contract.

## Before you start

You need:

* An API key with the `admin` or `root` role in `CHECKFU_API_KEY`.
* A service account for the Automation to run as (`RUNS_AS`, a `prin_…`), and the person who authors it (`AUTHOR`, a `prin_…`). An API key is not a person, so a create through an API key names the author.
* The Writer [Agent](https://docs.checkfu.com/concepts/agents.md) (`WRITER_AGENT`).
* The [Environment](https://docs.checkfu.com/concepts/work-environments.md) the Agent runs in (`ENVIRONMENT`). When the Workspace has exactly one, delete the `environment_id` line and leave out `ENVIRONMENT`.
* A model routing profile with the key `fast-judge`, or change `route.profile` to one you have.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
export RUNS_AS=prin_0123456789abcdef0123456789abcdef
export AUTHOR=prin_fedcba9876543210fedcba9876543210
export WRITER_AGENT=agent_0123456789abcdef0123456789abcdef
export ENVIRONMENT=env_0123456789abcdef0123456789abcdef
```

The CLI examples use [CLI access](https://docs.checkfu.com/getting-started/cli-access.md) and the TypeScript examples use the [TypeScript SDK](https://docs.checkfu.com/reference/typescript-sdk.md).

## 1. Create the draft

Save the recipe as `outcomes.yaml`. It is the published [`outcomes.yaml`](https://docs.checkfu.com/automation-recipes/outcomes.yaml) with `created_by_principal_id` added:

```yaml outcomes.yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
# yaml-language-server: $schema=https://docs.checkfu.com/openapi.json#/components/schemas/CreateBlockAutomation
name: Draft until it meets the rubric
runs_as: "${RUNS_AS}"
environment_id: "${ENVIRONMENT}"
created_by_principal_id: "${AUTHOR}"
blocks:
  - id: request
    type: trigger
    trigger: { type: webhook, dedupe_pointer: /id }
  - id: draft
    type: agent
    agent: "${WRITER_AGENT}"
    prompt: |
      {{request.goal}}
      Your previous draft (empty on the first try): {{draft.output}}
      Reviewer feedback (empty on the first try): {{grade.reason}}
  - id: grade
    type: model
    route: { profile: fast-judge }
    prompt: "Score this draft against the rubric. Rubric: {{request.rubric}} Draft: {{draft.output}}"
    format: { type: score, levels: 10, pass_at: 8 }
wires:
  - { from: request, to: draft }
  - { from: draft, to: grade }
  - { from: grade, port: fail, to: draft, max_attempts: 3 }
```

The draft is saved paused and unpublished.

```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu automations validate -f outcomes.yaml --var RUNS_AS=$RUNS_AS --var AUTHOR=$AUTHOR \
  --var WRITER_AGENT=$WRITER_AGENT --var ENVIRONMENT=$ENVIRONMENT
checkfu automations create -f outcomes.yaml --var RUNS_AS=$RUNS_AS --var AUTHOR=$AUTHOR \
  --var WRITER_AGENT=$WRITER_AGENT --var ENVIRONMENT=$ENVIRONMENT
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/automations \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Idempotency-Key: $(uuidgen)" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Draft until it meets the rubric",
    "runs_as": "'"$RUNS_AS"'",
    "created_by_principal_id": "'"$AUTHOR"'",
    "environment_id": "'"$ENVIRONMENT"'",
    "blocks": [
      { "id": "request", "type": "trigger", "trigger": { "type": "webhook", "dedupe_pointer": "/id" } },
      {
        "id": "draft",
        "type": "agent",
        "agent": "'"$WRITER_AGENT"'",
        "prompt": "{{request.goal}}\nYour previous draft (empty on the first try): {{draft.output}}\nReviewer feedback (empty on the first try): {{grade.reason}}\n"
      },
      {
        "id": "grade",
        "type": "model",
        "route": { "profile": "fast-judge" },
        "prompt": "Score this draft against the rubric. Rubric: {{request.rubric}} Draft: {{draft.output}}",
        "format": { "type": "score", "levels": 10, "pass_at": 8 }
      }
    ],
    "wires": [
      { "from": "request", "to": "draft" },
      { "from": "draft", "to": "grade" },
      { "from": "grade", "port": "fail", "to": "draft", "max_attempts": 3 }
    ]
  }'
```

```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { Checkfu, recipes } from "@checkfu/sdk"

const checkfu = new Checkfu({ apiKey: process.env.CHECKFU_API_KEY })

const document = recipes.outcomes({
  runsAs: process.env.RUNS_AS!,
  environmentId: process.env.ENVIRONMENT,
  agent: process.env.WRITER_AGENT!,
  route: { profile: "fast-judge" },
  maxAttempts: 3,
})

const automation = await checkfu.automations.create(
  {
    ...document,
    created_by_principal_id: process.env.AUTHOR,
  },
  { idempotencyKey: crypto.randomUUID() },
)
```

Keep the `auto_…` id it returns:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
export AUTOMATION=auto_0123456789abcdef0123456789abcdef
```

## 2. Grant what it needs

The service account needs `act_as` on the Writer and `use_model` on the route. List what the draft needs and what is missing:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl https://api.checkfu.com/v1/automations/$AUTOMATION/access \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31"
```

Each entry has a `status` of `granted` or `missing`, the blocks that need it and a plain `message`. Grant a missing one with a [PermissionAssignment](https://docs.checkfu.com/concepts/tenancy-and-governance.md):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/permission-assignments \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Idempotency-Key: $(uuidgen)" \
  --header "Content-Type: application/json" \
  --data '{
    "subject": { "type": "principal", "id": "'"$RUNS_AS"'" },
    "resource": { "type": "agent", "id": "'"$WRITER_AGENT"'" },
    "permission": "act_as"
  }'
```

A grant that already exists answers `409`.

## 3. Test the draft

A test is a real run of the draft with a sample request. It starts real Sessions and lists them as its effects, but registers no trigger.

```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu automations test $AUTOMATION \
  --event '{"id":"req-1","goal":"Write a two-line release note for v2.","rubric":"Names the version and fits in two lines."}'
checkfu automations trace afire_0123456789abcdef0123456789abcdef
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/automations/$AUTOMATION/test \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Content-Type: application/json" \
  --data '{
    "event": {
      "id": "req-1",
      "goal": "Write a two-line release note for v2.",
      "rubric": "Names the version and fits in two lines."
    }
  }'
```

```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const test = await checkfu.automations.test(automation.id, {
  event: {
    id: "req-1",
    goal: "Write a two-line release note for v2.",
    rubric: "Names the version and fits in two lines.",
  },
})
console.log(test.run.id, test.effects.map((effect) => effect.description))
```

## 4. Publish

Publishing makes the draft the live version and returns the webhook URL and its signing secret. The secret is shown once; store it where your sender can sign with it.

```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu automations publish $AUTOMATION
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/automations/$AUTOMATION/publish \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Content-Type: application/json" \
  --data '{}'
```

```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const publication = await checkfu.automations.publish(automation.id, {})
console.log(publication.summary, publication.webhook_secret)
```

The summary says what publishing did, for example "Listens for signed webhooks at POST /v1/ingest/automations/auto\_…". Rotate the secret with `POST /v1/automations/{id}/webhook-secret`.

## 5. Run it and read the result

A signed webhook starts a run. You can also run the live version now with the same request:

```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu automations run $AUTOMATION \
  --event '{"id":"req-2","goal":"Write a two-line release note for v2.","rubric":"Names the version and fits in two lines."}'
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/automations/$AUTOMATION/run \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Idempotency-Key: $(uuidgen)" \
  --header "Content-Type: application/json" \
  --data '{
    "event": {
      "id": "req-2",
      "goal": "Write a two-line release note for v2.",
      "rubric": "Names the version and fits in two lines."
    }
  }'
```

```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const run = await checkfu.automations.run(
  automation.id,
  {
    event: {
      id: "req-2",
      goal: "Write a two-line release note for v2.",
      rubric: "Names the version and fits in two lines.",
    },
  },
  { idempotencyKey: crypto.randomUUID() },
)
```

List the runs and their status:

```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu automations runs $AUTOMATION --limit 5
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl "https://api.checkfu.com/v1/automation-runs?automation_id=$AUTOMATION&limit=5" \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31"
```

```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const runs = await checkfu.automationRuns.list({ automation_id: automation.id, limit: 5 })
```

A run that passed ends `completed`. A run whose third draft still failed ends as not passed, and the `automation_run.completed` [webhook event](https://docs.checkfu.com/guides/receive-webhooks.md) carries `result: "not_passed"`.

## Pause and resume

Pause stops webhooks from starting runs; a manual run still works. Resume turns triggers back on.

```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu automations pause $AUTOMATION
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/automations/$AUTOMATION/pause \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Content-Type: application/json" \
  --data '{}'
```

```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
await checkfu.automations.pause(automation.id, {})
```

```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
checkfu automations resume $AUTOMATION
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/automations/$AUTOMATION/resume \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Content-Type: application/json" \
  --data '{}'
```

```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
await checkfu.automations.resume(automation.id, {})
```

## Change it

Edit the document and replace the draft with `PATCH /v1/automations/{id}` and its `expected_draft_revision`, then test and publish again. Each run records the version it used, and `checkfu automations versions $AUTOMATION` lists them. See [Automations](https://docs.checkfu.com/concepts/automations.md) for every block and field.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.