# Idea capture and roundup workflows with the Capability API

Use the Capability API to persist and enrich raw inspiration with strict structured requests. `ideas.capture@3.0` owns one primary subject, keeps a reauthorized Ideas List destination separate from source fidelity, and can route the capture there. `ideas.capture.get@2.0` returns typed, application-owned clarification and retry actions without reconstructing the source or destination. `ideas.capture.retry@2.0` retries failed enrichment from the retained capture. `ideas.roundup.mutate@2.5` owns an intentional multi-item source, attaches an already-saved idea to the requested Ideas List even when research discovers the duplicate, and returns typed, application-owned next actions when scope or destination input is missing. These are private writes and reads; none contacts another person or performs an outside transaction.

Fetch [the current OpenAPI document](/docs/openapi.json) before implementing. The generated schemas and versions are authoritative when they differ from an example on this page.

These capture capabilities record **user-originated ideas**. When the user asks Domino to suggest possible places, events, or activities rather than supplying source material, use the current recommendations capability. Enrichment can make a captured result place-backed or event-backed without changing its user-originated provenance.

## Prerequisites

```sh
export DOMINO_API="https://letsdomino.io/api/v2"
export DOMINO_TOKEN="YOUR_AGENT_ACCESS_TOKEN"
```

The Agent Access token needs **Read** and **Draft** abilities. Keep it out of source control, logs, URLs, prompts, and response bodies.

Every write requires a caller-stable `Idempotency-Key` header. Read capabilities do not.

## Capture one subject

Submit exact raw source material plus optional destination context:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.capture" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: capture-20260812-001" \
  -d '{
    "version":"3.0",
    "input":{
      "raw_text":"Remember this quiet patio restaurant for Andrew",
      "subject_text":"quiet patio restaurant for Andrew",
      "source_url":"https://example.com/restaurant",
      "target_ideas_list_handle":"IDEAS_LIST_HANDLE_FROM_DOMINO"
    }
  }'
```

Provide one or more supported source fields:

- `raw_text` or `text`, up to the current generated limit;
- one `source_url`;
- current opaque `media_refs` from a supported Domino media-ingress flow.

When a URL or media is supplied, `raw_text` remains the exact source instruction. Set `subject_text` only when the user separately stated idea content or constraints that the result must preserve. Exclude capture commands and the Ideas List destination; omit `subject_text` when the artifact is the whole subject. Domino resolves the destination independently and removes a supplied subject that resolves to that same Ideas List, so a caller-model classification mistake cannot turn routing into a fidelity requirement.

Optional context includes an Ideas List handle or text selector and private person text. Use only authorized handles returned by Domino. Never pass internal numeric IDs.

## Interpret the singular response

Inspect the typed body, not only the HTTP status.

### `accepted`

The capture itself was persisted, but enrichment remains asynchronous. Retain:

- `outcome.facts.capture.public_id`;
- the newest update cursor when present;
- `outcome.next_actions`.

Poll the returned operation. Do not send a second create request.

### `needs_input`

Present the exact returned question. Obtain the user’s answer; do not infer a material place, occurrence, date, or destination merely to make the request complete.

### `failed`

Read `errors[].code` and the user-safe message. A `roundup_requires_roundup_capture` response means the source belongs to the roundup workflow below.

When `ideas.capture.get` returns a failed result with an `ideas.capture.retry` next action, retain its exact `capture_public_id`, `expected_state_version`, `execution_policy`, and `optional_input`. Do not rebuild the original URL, source text, or Ideas List selector from conversation prose.

## Poll one capture

The first read can omit `after_cursor`:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.capture.get" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "version":"2.0",
    "input":{
      "capture_public_id":"CAPTURE_PUBLIC_ID_FROM_DOMINO"
    }
  }'
```

On later reads, include only the latest returned cursor:

```json
{
  "version": "2.0",
  "input": {
    "capture_public_id": "CAPTURE_PUBLIC_ID_FROM_DOMINO",
    "after_cursor": 12
  }
}
```

Continue polling only as directed while status remains `accepted`. Respect HTTP `429` and `Retry-After`. Do not guess a rapid polling interval.

## Answer a singular clarification

Use the same capture reference but a new write key:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.capture" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: capture-20260812-clarification-001" \
  -d '{
    "version":"3.0",
    "input":{
      "capture_public_id":"CAPTURE_PUBLIC_ID_FROM_DOMINO",
      "clarification_answer":"The Lula Cafe in Chicago on Kedzie.",
      "expected_state_version":1
    }
  }'
```

Do not resend the original link, text, or media as a new capture. The clarification action accepts only the open `clarification_answer`; its retained capture reference is immutable. Resume polling the same public identifier after an accepted response.

## Retry a failed singular capture

Execute the exact optional next action only when the user asks to retry. Use a new write key and the state version Domino returned:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.capture.retry" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: capture-20260812-retry-001" \
  -d '{
    "version":"2.0",
    "input":{
      "capture_public_id":"CAPTURE_PUBLIC_ID_FROM_DOMINO",
      "expected_state_version":1,
      "additional_detail":"The place is Ping Tom Memorial Park in Chicago."
    }
  }'
```

`additional_detail` is optional and is research evidence, not a replacement subject. Include only new factual detail the user supplied—never retry commands, the retained source, or destination wording. Domino reauthorizes the persisted Ideas List and rejects a stale state version before queuing work. Resume `ideas.capture.get@2.0` after an accepted retry.

## Know when singular capture completed

Only `ideas.capture.get` terminal `completed` proves that processing reached persisted terminal state. Report the exact saved item and destination from the facts.

These are not terminal proof:

- HTTP `200` or `202` by itself;
- `status: "accepted"`;
- a review URL;
- a candidate object;
- a confirmed `idea_capture_persistence` effect while `idea_capture_enrichment` remains unconfirmed.

## Create an intentional roundup

Use one roundup operation for a source whose requested outcome contains several distinct ideas:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.roundup.mutate" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: roundup-20260812-001" \
  -d '{
    "version":"2.5",
    "input":{
      "operation":"create",
      "source_url":"https://example.com/restaurants",
      "source_text":"Save the restaurants in this article for Date Nights",
      "target_ideas_list_handle":"IDEAS_LIST_HANDLE_FROM_DOMINO"
    }
  }'
```

The create input needs a source URL, source text, or at least two structured `items`. Structured items are appropriate only when the caller already has verified titles and optional evidence; they are not a shortcut for invented extraction.

Retain `outcome.facts.operation.public_id`, `current_generation`, status, update cursor, selectable item references, and the exact typed next action. Its `input` is application-owned and generation-bound; supply only the fields named by `required_input` and use authorized handles for `required_references`.

If an Ideas List text selector cannot be matched uniquely, the typed next action retains the exact original capture or roundup input and requires `target_ideas_list_handle`. Select an existing authorized Ideas List or call the listed prerequisite capability to create the specifically requested one, even when the result also offers similar existing choices. Then execute the retained next action with a new idempotency key. Do not reconstruct source material, selected items, or the destination from conversation prose. Hosted SMS and Assistant API can perform this continuation conversationally; MCP and Capability API callers receive the same typed action and execute it with their own model or application logic.

## Resolve roundup scope

A response with `awaiting_scope` asks whether to:

- use `all` for the matching extracted items;
- use `general_source` to keep the roundup itself as one idea;
- use `named_items` for only explicitly named items.

Make the next mutation with a new key and the latest generation:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.roundup.mutate" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: roundup-20260812-scope-001" \
  -d '{
    "version":"2.5",
    "input":{
      "operation":"resolve_scope",
      "public_id":"ROUNDUP_PUBLIC_ID_FROM_DOMINO",
      "expected_generation":0,
      "scope":"all",
      "selection_policy":"curated"
    }
  }'
```

Use `selection_policy: "save_all"` only when the user explicitly requested every eligible result.

## Assign a roundup destination

When status is `awaiting_destination`, resolve an authorized Ideas List and use its opaque handle:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.roundup.mutate" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: roundup-20260812-destination-001" \
  -d '{
    "version":"2.5",
    "input":{
      "operation":"assign_destination",
      "public_id":"ROUNDUP_PUBLIC_ID_FROM_DOMINO",
      "expected_generation":1,
      "target_ideas_list_handle":"IDEAS_LIST_HANDLE_FROM_DOMINO"
    }
  }'
```

If the user did not request an Ideas List and the current outcome supports the owner library, preserve that result rather than inventing a list.

## Select roundup items

Use only exact selectable item references returned by the current operation:

```sh
curl -sS "$DOMINO_API/capabilities/ideas.roundup.mutate" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: roundup-20260812-items-001" \
  -d '{
    "version":"2.5",
    "input":{
      "operation":"select_items",
      "public_id":"ROUNDUP_PUBLIC_ID_FROM_DOMINO",
      "expected_generation":2,
      "selected_items":["ITEM_REFERENCE_1","ITEM_REFERENCE_2"]
    }
  }'
```

Do not reconstruct item references from titles or earlier generations.

`named_items` can never begin processing with an empty selection. A create request that supplies explicit structured items may omit `selected_items`; Domino derives the exact selection from those structured items. Other named-item transitions must supply at least one current selectable item reference.

## Poll a roundup

```sh
curl -sS "$DOMINO_API/capabilities/ideas.roundup.get" \
  -H "Authorization: Bearer $DOMINO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "version":"1.0",
    "input":{
      "public_id":"ROUNDUP_PUBLIC_ID_FROM_DOMINO",
      "after_cursor":8
    }
  }'
```

The read creates no write receipt and needs no idempotency header. Follow returned state through `ready`, `processing`, `needs_input`, `completed`, or `archived`.

## Retry, archive, and stale generations

For unresolved valid work, call `ideas.roundup.mutate` with:

```json
{
  "operation": "retry",
  "public_id": "ROUNDUP_PUBLIC_ID_FROM_DOMINO",
  "expected_generation": 3
}
```

Use `operation: "archive"` to close the operation. Both writes require a new idempotency header.

If an outcome contains `stale_generation`, stop. Read current state with `ideas.roundup.get`, inspect what changed, and make a new mutation only when the user’s intent still applies. Do not blindly substitute the latest generation into an old decision.

## Media-reference boundary

`media_refs` are current opaque Domino references, not arbitrary URLs, local file paths, filenames, or base64 payloads. The public Capability API does not document a general bearer-token file-upload operation for manufacturing those references.

When the integration has no supported current media reference:

- use public `source_url` or exact text when sufficient;
- return the web **Create → Create idea → Add screenshot** path; or
- use the supported SMS/MMS flow.

Never publish private media to work around this boundary.

## Completion and idempotency checklist

- A changed write needs a new idempotency key.
- An exact retry uses the original key and exact original body.
- Changed input under an old key must be treated as a conflict.
- Poll existing accepted work rather than creating another operation.
- Every roundup mutation uses the latest exact generation.
- Terminal roundup reporting distinguishes added, already seen, unselected, unresolved, omitted, and failed items.
- Only typed terminal facts authorize a claim that an idea or roundup item was saved.
