Skip to documentation

Products

Create and manage workspace products, their stable external sync identifiers, feature maps and images, personas, clarification questions, and portfolio metrics.

18 endpoints

GET

List all products

GET /external/v1/products

List products in the current workspace. Use `externalId` for deterministic syncs from external systems.

Requirements

API scopes required:
products:read

Request

Parameters

NameTypeDescription
limit numberMaximum number of products to return.
offset numberNumber of products to skip.
q stringCase-insensitive search across name, description, type, and externalId.
name stringExact product name match.
externalId stringExact client-side sync identifier.
include stringComma-separated: features, personas, questions, metrics.

Responses

200
Success

Products were successfully retrieved.

Schema
Array<Product>

Example Request

GET
/external/v1/products
curl
curl -X GET 'https://zentrik.ai/api/external/v1/products?externalId=prd-discovery&include=metrics' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
[
  {
    "id": "product-uuid",
    "name": "Zentrik Discovery",
    "description": "AI-assisted discovery workspace for product teams.",
    "descriptionAnalysis": null,
    "type": "SaaS",
    "stack": "NestJS, React, PostgreSQL",
    "mission": "Preserve customer intent from signal to roadmap.",
    "externalId": "prd-discovery",
    "sourceAliases": [
      {
        "value": "Zentrik DS",
        "match": "exact"
      }
    ],
    "workspaceId": "workspace-uuid",
    "kpis": [
      "Reduce insight review time",
      "Increase evidence coverage"
    ],
    "techStack": [
      {
        "name": "PostgreSQL",
        "roles": [
          "Backend Engineer"
        ]
      }
    ],
    "analysis": {},
    "createdAt": "2026-05-14T10:00:00Z",
    "updatedAt": "2026-05-14T10:00:00Z",
    "metrics": {
      "insights": 12,
      "ideas": 5,
      "opportunities": 3,
      "signals": 21
    }
  }
]
GET

Get one product

GET /external/v1/products/:id

Retrieve one product by Zentrik UUID. Add `include` to hydrate context collections.

Requirements

API scopes required:
products:read

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.
include stringComma-separated: features, personas, questions, metrics.

Responses

200
Success

The product was successfully retrieved.

Schema
Product
404
Not Found

No product found with the provided id in the current workspace.

Example Request

GET
/external/v1/products/:id
curl
curl -X GET 'https://zentrik.ai/api/external/v1/products/product-uuid?include=features,personas' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
{
  "id": "product-uuid",
  "name": "Zentrik Discovery",
  "description": "AI-assisted discovery workspace for product teams.",
  "descriptionAnalysis": null,
  "type": "SaaS",
  "stack": "NestJS, React, PostgreSQL",
  "mission": "Preserve customer intent from signal to roadmap.",
  "externalId": "prd-discovery",
  "sourceAliases": [
    {
      "value": "Zentrik DS",
      "match": "exact"
    }
  ],
  "workspaceId": "workspace-uuid",
  "kpis": [
    "Reduce insight review time",
    "Increase evidence coverage"
  ],
  "techStack": [
    {
      "name": "PostgreSQL",
      "roles": [
        "Backend Engineer"
      ]
    }
  ],
  "analysis": {},
  "createdAt": "2026-05-14T10:00:00Z",
  "updatedAt": "2026-05-14T10:00:00Z",
  "features": [
    {
      "id": "feature-uuid",
      "productId": "product-uuid",
      "name": "Signal intake",
      "description": "Bring customer evidence into Discovery.",
      "parentId": null
    }
  ],
  "personas": [
    {
      "id": "persona-uuid",
      "productId": "product-uuid",
      "name": "Product Manager",
      "description": "Owns discovery synthesis.",
      "goals": [],
      "painPoints": [],
      "useCases": []
    }
  ]
}
POST

Create a product

POST /external/v1/products

Create a product. `externalId` is optional but recommended for idempotent external syncs. Initial features and personas may be provided on create only.

Requirements

API scopes required:
products:write

Request

Request body (application/json)

namestring
Required

Product display name.

descriptionstring
Required

Product description.

externalIdstring

Stable client-side identifier, unique per workspace when present.

sourceAliasesarray

Source labels that should resolve to this product during imports.

typestring

Product category.

stackstring

Short implementation stack summary.

missionstring

Outcome or mission statement.

kpisstring[]

Outcome measures tracked for this product.

techStackarray

Structured technologies and roles.

featuresarray

Initial feature records.

personasarray

Initial persona records.

Responses

201
Created

The product was successfully created.

Schema
Product
409
Conflict

The externalId already exists in this workspace.

Example Request

POST
/external/v1/products
json
{
  "name": "Zentrik Discovery",
  "description": "AI-assisted discovery workspace for product teams.",
  "externalId": "prd-discovery",
  "sourceAliases": [
    {
      "value": "Zentrik DS",
      "match": "exact"
    }
  ],
  "mission": "Preserve customer intent from signal to roadmap.",
  "features": [
    {
      "name": "Signal intake",
      "description": "Bring customer evidence into Discovery."
    }
  ],
  "personas": [
    {
      "name": "Product Manager",
      "description": "Owns discovery synthesis."
    }
  ]
}

Example Response

201 Created
json
{
  "id": "product-uuid",
  "name": "Zentrik Discovery",
  "description": "AI-assisted discovery workspace for product teams.",
  "descriptionAnalysis": null,
  "type": "SaaS",
  "stack": "NestJS, React, PostgreSQL",
  "mission": "Preserve customer intent from signal to roadmap.",
  "externalId": "prd-discovery",
  "sourceAliases": [
    {
      "value": "Zentrik DS",
      "match": "exact"
    }
  ],
  "workspaceId": "workspace-uuid",
  "kpis": [
    "Reduce insight review time",
    "Increase evidence coverage"
  ],
  "techStack": [
    {
      "name": "PostgreSQL",
      "roles": [
        "Backend Engineer"
      ]
    }
  ],
  "analysis": {},
  "createdAt": "2026-05-14T10:00:00Z",
  "updatedAt": "2026-05-14T10:00:00Z"
}
PATCH

Update a product

PATCH /external/v1/products/:id

Update core product fields. Nested features, personas, and questions are rejected here; use the dedicated subresource endpoints.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Request body (application/json)

namestring

Updated product name.

descriptionstring

Updated product description.

externalIdstring | null

Update or clear the external sync identifier.

sourceAliasesarray | null

Replace source labels used for product import matching.

missionstring | null

Updated mission statement.

kpisstring[] | null

Replace product KPIs.

Responses

200
Updated

The product was successfully updated.

Schema
Product

Example Request

PATCH
/external/v1/products/:id
curl
curl -X PATCH https://zentrik.ai/api/external/v1/products/product-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"sourceAliases":[{"value":"Legacy Discovery","match":"exact"}]}'
DELETE

Delete a product

DELETE /external/v1/products/:id

Delete a product from the current workspace.

Requirements

API scopes required:
products:delete

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Responses

200
Deleted

The product was successfully deleted.

Example Request

DELETE
/external/v1/products/:id
curl
curl -X DELETE https://zentrik.ai/api/external/v1/products/product-uuid \
  -H 'Authorization: Bearer YOUR_API_KEY'
GET

Get portfolio summary

GET /external/v1/products/portfolio-summary

Return products plus aggregate counts used by portfolio views.

Requirements

API scopes required:
products:read

Responses

200
Success

Portfolio summary was successfully retrieved.

Example Request

GET
/external/v1/products/portfolio-summary
curl
curl -X GET https://zentrik.ai/api/external/v1/products/portfolio-summary \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
{
  "products": [
    {
      "id": "product-uuid",
      "name": "Zentrik Discovery",
      "description": "AI-assisted discovery workspace for product teams.",
      "descriptionAnalysis": null,
      "type": "SaaS",
      "stack": "NestJS, React, PostgreSQL",
      "mission": "Preserve customer intent from signal to roadmap.",
      "externalId": "prd-discovery",
      "sourceAliases": [
        {
          "value": "Zentrik DS",
          "match": "exact"
        }
      ],
      "workspaceId": "workspace-uuid",
      "kpis": [
        "Reduce insight review time",
        "Increase evidence coverage"
      ],
      "techStack": [
        {
          "name": "PostgreSQL",
          "roles": [
            "Backend Engineer"
          ]
        }
      ],
      "analysis": {},
      "createdAt": "2026-05-14T10:00:00Z",
      "updatedAt": "2026-05-14T10:00:00Z"
    }
  ],
  "metrics": {
    "product-uuid": {
      "insights": 12,
      "ideas": 5,
      "opportunities": 3,
      "signals": 21
    }
  },
  "meta": {
    "signalsLookbackDays": 7
  }
}
GET

Get product metrics

GET /external/v1/products/:id/metrics

Return aggregate metrics for a single product.

Requirements

API scopes required:
products:read

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Responses

200
Success

Product metrics were successfully retrieved.

Example Request

GET
/external/v1/products/:id/metrics
curl
curl -X GET https://zentrik.ai/api/external/v1/products/product-uuid/metrics \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

200 OK
json
{
  "contextPersonas": 2,
  "contextFeatureMapNodes": 8,
  "initiativesTotal": 3,
  "insights": 12,
  "signals": 21,
  "opportunities": 3,
  "ideas": 5
}
GET

List product features

GET /external/v1/products/:id/features

List feature map nodes for a product.

Requirements

API scopes required:
products:read

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Responses

200
Success

Features were successfully retrieved.

Schema
Array<ProductFeature>

Example Response

200 OK
json
[
  {
    "id": "feature-uuid",
    "productId": "product-uuid",
    "name": "Signal intake",
    "description": "Bring customer evidence into Discovery.",
    "parentId": null
  }
]
POST

Create a product feature

POST /external/v1/products/:id/features

Create one product feature. `parentId` may reference an existing feature in the same product.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Request body (application/json)

namestring
Required

Feature name.

descriptionstring
Required

Feature description.

parentIduuid | null

Optional parent feature.

Responses

201
Created

The feature was successfully created.

Schema
ProductFeature

Example Request

POST
/external/v1/products/:id/features
json
{
  "name": "Signal intake",
  "description": "Bring customer evidence into Discovery."
}
PATCH

Update a product feature

PATCH /external/v1/products/:id/features/:featureId

Update one product feature. The feature must belong to the requested product.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.
featureId *uuidThe feature UUID.

Request body (application/json)

namestring

Updated feature name.

descriptionstring

Updated feature description.

parentIduuid | null

Updated parent feature.

Responses

200
Updated

The feature was successfully updated.

Schema
ProductFeature
DELETE

Delete a product feature

DELETE /external/v1/products/:id/features/:featureId

Delete one product feature.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.
featureId *uuidThe feature UUID.

Responses

200
Deleted

The feature was successfully deleted.

POST

Attach an image to a product feature

POST /external/v1/products/:id/features/:featureId/images

Attach an image to an existing feature as multipart/form-data. The file field name must be `file`; stored object keys are never exposed.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.
featureId *uuidThe feature UUID.

Request body (application/json)

filefile
Required

PNG, JPEG, WebP, or GIF image up to 10 MB.

Responses

201
Created

The image was attached to the feature.

Schema
ProductFeatureImage
400
Bad Request

The file is empty, too large, or not a supported image type.

404
Not Found

The product or feature was not found in the API key workspace.

Example Request

POST
/external/v1/products/:id/features/:featureId/images
curl
curl -X POST https://zentrik.ai/api/external/v1/products/product-uuid/features/feature-uuid/images \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -F 'file=@feature-overview.png'

Example Response

201 Created
json
{
  "id": "image-uuid",
  "productId": "product-uuid",
  "featureId": "feature-uuid",
  "fileName": "feature-overview.png",
  "mimeType": "image/png",
  "size": 184320,
  "createdAt": "2026-07-24T10:00:00Z",
  "updatedAt": "2026-07-24T10:00:00Z"
}
GET

List product personas

GET /external/v1/products/:id/personas

List personas for a product.

Requirements

API scopes required:
products:read

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Responses

200
Success

Personas were successfully retrieved.

Schema
Array<ProductPersona>

Example Response

200 OK
json
[
  {
    "id": "persona-uuid",
    "productId": "product-uuid",
    "name": "Product Manager",
    "description": "Owns discovery synthesis.",
    "goals": [],
    "painPoints": [],
    "useCases": []
  }
]
POST

Create a product persona

POST /external/v1/products/:id/personas

Create one product persona.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Request body (application/json)

namestring
Required

Persona name.

descriptionstring
Required

Persona description.

goalsstring[]

Persona goals.

painPointsstring[]

Persona pain points.

useCasesstring[]

Persona use cases.

Responses

201
Created

The persona was successfully created.

Schema
ProductPersona
PATCH

Update a product persona

PATCH /external/v1/products/:id/personas/:personaId

Update one product persona.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.
personaId *uuidThe persona UUID.

Request body (application/json)

namestring

Updated persona name.

descriptionstring

Updated persona description.

goalsstring[]

Replacement goals.

painPointsstring[]

Replacement pain points.

useCasesstring[]

Replacement use cases.

Responses

200
Updated

The persona was successfully updated.

Schema
ProductPersona
DELETE

Delete a product persona

DELETE /external/v1/products/:id/personas/:personaId

Delete one product persona.

Requirements

API scopes required:
products:write

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.
personaId *uuidThe persona UUID.

Responses

200
Deleted

The persona was successfully deleted.

GET

List product questions

GET /external/v1/products/:id/questions

List product clarification questions. This API is read-only for questions.

Requirements

API scopes required:
products:read

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.

Responses

200
Success

Questions were successfully retrieved.

Schema
Array<ProductQuestion>
GET

Get a product question

GET /external/v1/products/:id/questions/:questionId

Retrieve one product clarification question.

Requirements

API scopes required:
products:read

Request

Parameters

NameTypeDescription
id *uuidThe product UUID.
questionId *uuidThe question UUID.

Responses

200
Success

The question was successfully retrieved.

Schema
ProductQuestion