---
title: "Ideas API reference"
canonical_url: https://zentrik.ai/docs/api/ideas
markdown_url: https://zentrik.ai/docs/api/ideas.md
last_reviewed: 2026-10-05
---

# Ideas API reference

Ideas are the tangible solutions you're considering to address your opportunities. Track features, experiments, and improvements through their evaluation lifecycle.

- Human reference: https://zentrik.ai/docs/api/ideas
- Complete Markdown index: https://zentrik.ai/docs/api/index.md
- Base URL: `https://zentrik.ai/api`
- Authentication: `Authorization: Bearer YOUR_API_KEY`
- Shared pagination and rate limits: https://zentrik.ai/docs/api/index.md#shared-conventions

## GET /external/v1/ideas/:id/evidence — Read an Idea’s evidence

Operation ID: `get-idea-evidence`

List exact evidence directly linked to an Idea. Each record includes its relationship role (supports, qualifies, contradicts or context) and origin. A link alone does not mean the work addressed that evidence. Select the records covered by delivered work before resolving them. This endpoint does not infer evidence through related Insights or Opportunities. It needs ideas:read plus signal-evidence:read or signals:read. List responses are arrays with X-Total-Count, X-Limit, X-Offset and X-Has-More headers. Continue until X-Has-More is false; concurrent edits can shift offset pages.

Required API key scopes: `ideas:read`, `signal-evidence:read`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | uuid \| public id | Yes | Idea reference, for example IDEA-42. |
| `limit` | integer | No | 1–50; default 20. |
| `offset` | integer | No | Default 0. |
| `visibility` | enum | No | active (default) or all. |

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success | The requested data is returned. | — |
| 400 | Invalid request | Invalid ID, unsupported field, empty patch, or invalid value. | — |
| 403 | Missing scope | The key does not grant the required resource scope. | — |
| 404 | Not found | The addressed record or assignment is outside this workspace or team. | — |

### Example response

```json
[
  {
    "id": "33333333-3333-4333-8333-333333333333",
    "title": "Export duplicates rows",
    "description": "Retrying the export adds a second copy.",
    "extracts": null,
    "category": "Product bug",
    "signalId": null,
    "resolvedAt": null,
    "resolution": null,
    "resolvedByUserId": null,
    "dismissedAt": null,
    "role": "supports",
    "origin": "entity_creation",
    "signalPublicId": null
  }
]
```

---

## PATCH /external/v1/ideas/:id/status — Change an Idea status

Operation ID: `set-idea-status`

Apply the exact workspace-configured status label to one Idea. expectedCurrentStatus rejects stale writes. The configured promotion status is reserved for the promotion workflow; this operation never creates an Initiative. Task and evidence states are independent.

Required API key scopes: `ideas:write`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | uuid \| public id | Yes | Idea reference, for example IDEA-42. |

### JSON request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | string | Yes | Exact workspace status label, 1–120 characters. |
| `expectedCurrentStatus` | string | No | Optional previously observed status label. |

### Example request

```json
{
  "status": "Shipped",
  "expectedCurrentStatus": "Approved"
}
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success | The saved record is returned. | — |
| 400 | Invalid request | Invalid ID, unsupported field, empty patch, or invalid value. | — |
| 403 | Missing scope | The key does not grant the required resource scope. | — |
| 404 | Not found | The addressed record or assignment is outside this workspace or team. | — |
| 409 | Conflict | The observed status changed, the sprint is completed, or a source-managed field must be edited in Linear. | — |

### Example response

```json
{
  "id": "33333333-3333-4333-8333-333333333333",
  "publicId": "IDEA-42",
  "status": "Shipped",
  "previousStatus": "Approved",
  "changed": true
}
```

---

## GET /external/v1/ideas — List ideas

Operation ID: `list-ideas`

Get a bounded page of potential solutions and features tracked as ideas.

Required API key scopes: `ideas:read`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | number | No | Maximum number of items to return (default: 20, maximum: 100) |
| `offset` | number | No | Number of items to skip (default: 0) |
| `sourceKey` | string | No | Exact stable source namespace to match |
| `externalId` | string | No | Exact source-record identifier to match |
| `integrationId` | uuid | No | Exact connected integration identifier to match |

### Example request

```curl
curl -X GET https://zentrik.ai/api/external/v1/ideas?limit=10 \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success | List of ideas retrieved. Pagination metadata is returned in X-Total-Count, X-Limit, X-Offset, and X-Has-More headers. | Array<Idea> |

### Example response

```json
[
  {
    "id": "uuid",
    "name": "Implement one-click checkout",
    "description": "Reduce friction by storing user preferences...",
    "status": "New"
  }
]
```

---

## GET /external/v1/ideas/:id — Get one idea

Operation ID: `get-idea`

Retrieve one feature idea by its internal UUID or human-readable public ID.

Required API key scopes: `ideas:read`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The internal UUID or public ID (for example, IDEA-42) |

### Example request

```curl
curl -X GET https://zentrik.ai/api/external/v1/ideas/IDEA-42 \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success |  | Idea |

---

## GET /external/v1/ideas/:id/questions — List idea questions

Operation ID: `list-idea-questions`

List the questions on an idea, whether Zentrik generated them or people added them in the app, with their current answers, by internal UUID or human-readable public ID. `reasoning` says why a question matters and `placeholder` is Zentrik's drafted answer. `status` is `pending` (open), `skipped` (set aside: still open, out of the open list), `answered`, or `rejected` (not relevant). Results use the standard pagination headers.

Required API key scopes: `ideas:read`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The internal UUID or public ID (for example, IDEA-42) |
| `limit` | number | No | Maximum number of questions to return (default: 20, maximum: 100) |
| `offset` | number | No | Number of questions to skip (default: 0) |

### Example request

```curl
curl -X GET 'https://zentrik.ai/api/external/v1/ideas/IDEA-42/questions?limit=20&offset=0' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success | Questions were retrieved. Pagination metadata is returned in X-Total-Count, X-Limit, X-Offset, and X-Has-More headers. | Array<IdeaQuestion> |
| 404 | Not found | The idea is not in the API-key workspace. | — |

### Example response

```json
[
  {
    "id": "question-uuid",
    "ideaId": "idea-uuid",
    "question": "Which workflow should ship first?",
    "answer": null,
    "placeholder": "Name the first workflow",
    "reasoning": "The rollout plan depends on which workflow users meet first.",
    "status": "pending",
    "createdAt": "2026-08-05T10:00:00.000Z",
    "updatedAt": "2026-08-05T10:00:00.000Z"
  }
]
```

---

## PATCH /external/v1/ideas/:id/questions/:questionId/answer — Answer an idea question

Operation ID: `answer-idea-question`

Answer an open or set-aside question, or revise its current answer. The idea reference is workspace-scoped and may be an internal UUID or public ID.

Required API key scopes: `ideas:write`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The internal UUID or public ID (for example, IDEA-42) |
| `questionId` | uuid | Yes | The question UUID returned by the list endpoint |

### JSON request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `answer` | string | Yes | The non-empty answer to save |

### Example request

```curl
curl -X PATCH https://zentrik.ai/api/external/v1/ideas/IDEA-42/questions/QUESTION_UUID/answer \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"answer":"Workspace setup"}'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Updated | The persisted question and answer were returned. | IdeaQuestion |
| 400 | Invalid request | The answer is empty, or questionId is not a question UUID. | — |
| 404 | Not found | The idea or question is outside the API-key workspace. | — |

### Example response

```json
{
  "id": "question-uuid",
  "ideaId": "idea-uuid",
  "question": "Which workflow should ship first?",
  "answer": "Workspace setup",
  "placeholder": "Name the first workflow",
  "reasoning": "The rollout plan depends on which workflow users meet first.",
  "status": "answered",
  "createdAt": "2026-08-05T10:00:00.000Z",
  "updatedAt": "2026-08-06T10:00:00.000Z"
}
```

---

## POST /external/v1/ideas — Create an idea

Operation ID: `create-idea`

Submit or idempotently update a feature idea or solution. Send sourceKey with externalId for a stable source identity. A repeat request with the same pair updates the existing idea, and an omitted status preserves its current workflow state.

Required API key scopes: `ideas:write`

### JSON request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | Title of the idea. Zentrik generates one from the description when omitted. |
| `description` | string | Yes | Detailed description of the solution |
| `status` | string | No | Exact workspace-configured Idea status. Omit it during an idempotent update to preserve the current status. |
| `sourceKey` | string | No | Stable source namespace. Use it with externalId for idempotent create-or-update behavior. |
| `externalId` | string | No | Stable record identifier within sourceKey. |
| `integrationId` | uuid | No | Connected integration identifier for integration-owned records. |
| `insightIds` | uuid[] | No | Insights to link to the idea. |
| `accountIds` | uuid[] | No | Accounts related to the Idea. Link only Accounts supported by its source or Evidence; the relationship does not claim current usage or endorsement. |
| `validateInsightLinks` | boolean | No | Set true only when insightIds are an explicitly confirmed evidence path. Existing confirmed links are never demoted when omitted or false. |
| `classifications` | ClassificationAssignment[] | No | Patch-style workspace taxonomy assignments. Use group keys plus option keys or labels from the active taxonomy. Each item must provide optionValues for a list group or textValue for a text group. |

### Example request

```json
{
  "name": "AI-powered search",
  "description": "Use LLMs to improve search relevance...",
  "sourceKey": "research-repository",
  "externalId": "proposal-184",
  "accountIds": [
    "account-uuid"
  ],
  "classifications": [
    {
      "groupKey": "stage",
      "optionValues": [
        "validation"
      ]
    },
    {
      "groupKey": "phi_level",
      "optionValues": [
        "high"
      ]
    }
  ]
}
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 201 | Created | The idea was successfully created. | Idea |

### Example response

```json
{
  "id": "uuid",
  "name": "AI-powered search",
  "sourceKey": "research-repository",
  "externalId": "proposal-184",
  "accountIds": [
    "account-uuid"
  ],
  "provenance": {
    "method": "external_api"
  },
  "taxonomyVersionId": "taxonomy-version-uuid",
  "classifications": [
    {
      "groupKey": "stage",
      "optionLabels": [
        "Validation"
      ]
    },
    {
      "groupKey": "phi_level",
      "optionLabels": [
        "High"
      ]
    }
  ]
}
```

---

## PATCH /external/v1/ideas/:id — Update an idea

Operation ID: `update-idea`

Modify an existing idea by its internal UUID or human-readable public ID. Classification assignments patch only the supplied workspace taxonomy groups; omitted groups remain unchanged. An idea can belong to only one Initiative: use projectId: null to detach it before attaching it to a different Initiative.

Required API key scopes: `ideas:write`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The internal UUID or public ID (for example, IDEA-42) |

### JSON request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | Updated name |
| `description` | string | No | Updated description |
| `projectId` | string \| null | No | Initiative UUID/public ID to attach this idea to, or null to detach it |
| `insightIds` | uuid[] | No | Replacement set of linked Insights. |
| `accountIds` | uuid[] | No | Replacement set of related workspace Accounts. Use only source-supported links; a relationship does not claim current usage or endorsement. |
| `validateInsightLinks` | boolean | No | Set true only to confirm the supplied insightIds as validated evidence links. |
| `classifications` | ClassificationAssignment[] | No | Workspace taxonomy assignments. Use optionValues: [] or textValue: null to mark a supplied group unassigned. |

### Example request

```curl
curl -X PATCH https://zentrik.ai/api/external/v1/ideas/IDEA-42 \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"projectId":"INITIATIVE-7","accountIds":["account-uuid"],"classifications":[{"groupKey":"category","optionValues":["workflow"]}]}'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Updated |  | Idea |
| 400 | Invalid Initiative link | The target is invalid, or the idea is already linked to another Initiative. Detach it with projectId: null before attaching the new Initiative. | — |

---

## DELETE /external/v1/ideas/:id — Delete an idea

Operation ID: `delete-idea`

Permanently delete an idea by its internal UUID or human-readable public ID.

Required API key scopes: `ideas:delete`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The internal UUID or public ID (for example, IDEA-42) |

### Example request

```curl
curl -X DELETE https://zentrik.ai/api/external/v1/ideas/IDEA-42 \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Success |  | — |

---

## DELETE /external/v1/ideas/:id/comments/:commentId — Delete an idea comment

Operation ID: `delete-idea-comment`

Delete one comment from an idea without deleting or rewriting the idea. External API keys are workspace-admin credentials because only workspace owners/admins can create them.

Required API key scopes: `ideas:delete`

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The idea's internal UUID or public ID (for example, IDEA-42) |
| `commentId` | string | Yes | The comment UUID |

### Example request

```curl
curl -X DELETE https://zentrik.ai/api/external/v1/ideas/IDEA-42/comments/COMMENT_UUID \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

### Responses

| Status | Meaning | Description | Schema |
| --- | --- | --- | --- |
| 200 | Deleted | The scoped comment was deleted. The receipt does not include comment content. | IdeaCommentDeletionReceipt |
| 404 | Not found | The idea is outside the API-key workspace, or the comment does not belong to that idea and workspace. | — |

### Example response

```json
{
  "success": true,
  "ideaId": "uuid",
  "ideaPublicId": "IDEA-42",
  "commentId": "uuid"
}
```
