Entity reference · v1
releases
REL-NNNNNNtable releasessoft deleteVersioned release bundles with AI-generated notes and channel targeting.
A release is a versioned bundle of work that ships together. This page covers what the field table below can't tell you: how a release records its scope, and the difference between a linked feature and a free-text item.
What a release ships
A release's scope has two parts, stored in two places.
| Part | Where it lives | Use it for |
|---|---|---|
| Linked features | the features junction (release_features) | Work tracked as a feature. The link follows the feature: rename it and the release shows the new title; delete it and the link goes with it. |
| Other changes | the items field, an array of strings | Lines that shipped but aren't tracked as features, such as "Fixed crash when exporting to CSV". |
Link a feature
curl "https://productos.ca/api/v1/releases/REL-000012/links/features" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ids": ["FEAT-000123", "FEAT-000124"]}'Linking is idempotent: posting a feature that's already linked is a no-op. Remove a link with DELETE /api/v1/releases/{id}/links/features/{featureId}.
A release can only link features from its own workspace. An id from another workspace is rejected with 404 not_found, including a bare UUID.
Which release ships this feature
The same junction is exposed from the feature side:
curl "https://productos.ca/api/v1/features/FEAT-000123/links/releases" \
-H "Authorization: Bearer $TOKEN"Write free-text items
curl "https://productos.ca/api/v1/releases/REL-000012" \
-X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"items": ["Fixed crash when exporting to CSV", "Faster dashboard loads"]}'items replaces the whole list on every write. Each line is trimmed, blank lines are dropped, and exact repeats collapse to the first one.
Initiatives
The initiatives junction records which initiatives a release serves. It is independent of the features junction: linking a feature doesn't link its initiatives, and linking an initiative doesn't pull in its features.
Status
Release status is set explicitly. ProductOS doesn't derive it from the status of the linked features, and changing a release's status doesn't change theirs. The release dialog shows how many linked features have shipped and their average progress, so readiness is visible without being automated.
Public changelog
A release with is_public = true and a status of scheduled, published or shipped appears on the workspace's public changelog. Each entry lists the linked features by title, then the free-text items. Draft and trashed features are left off.
The auto-generated endpoint, field, and junction reference is below.
Endpoints
/api/v1/releases/api/v1/releases/api/v1/releases/{id}/api/v1/releases/{id}/api/v1/releases/{id}/api/v1/releases/{id}/restore/api/v1/releases/{id}/links/features/api/v1/releases/{id}/links/features/api/v1/releases/{id}/links/features/{targetId}/api/v1/releases/{id}/links/initiatives/api/v1/releases/{id}/links/initiatives/api/v1/releases/{id}/links/initiatives/{targetId}Writable fields
* required on create. PATCH treats every field as optional.
| Field | Type | Constraints | Notes |
|---|---|---|---|
| version* | string | ||
| title | string | ||
| description | text | ||
| release_notes | text | ||
| ai_generated_notes | text | ||
| status | string | draft | scheduled | published | planned | in-progress | shipped | |
| date | date | ||
| items | string[] | Free-text release lines that are not tracked as features. Link features through /links/features instead. | |
| channels | json | ||
| targeting | string | ||
| is_public | boolean | ||
| is_draft | boolean | ||
| metadata | json |
Listing & filtering
- Pagination:
?limit=50&offset=0· max limit 200 - Default sort:
?sort=date&order=desc - Sortable fields: created_at · updated_at · date · version · id_number
- Search (?q=): title, description, version, release_notes
- Filters: ?status= ?is_public= ?is_draft= , repeat any filter to OR multiple values
- Trash: hidden by default; pass
?include_deleted=true - Expand:
?expand=features,initiatives
Examples
curl 'https://productos.ca/api/v1/releases?limit=10' \
-H "Authorization: Bearer $TOKEN"Try it out
Paste a token and hit a real endpoint. The request goes from your browser straight to /api/v1/releases. The token is held in this page only for the request and is never stored.
Issue tokens in Settings → API tokens. Token never leaves this page.
GET/api/v1/releases?limit=3