Source: https://docs.sogni.ai/api-reference/changelog/

# Changelog

The changelog is one public record of what changed on Sogni, for artists, developers and worker operators. These reads use `https://api.sogni.ai`, need no API key, are rate-limited, and can be called from a browser on any origin.

## [#](https://docs.sogni.ai/api-reference/changelog/#list-entries)List entries

`GET /v1/changelog` returns published entries, newest first. Every parameter is optional.

| Parameter | Values |
| --- | --- |
| `audience` | `artist`, `developer` or `worker` |
| `product` | Product ids from [Products](https://docs.sogni.ai/api-reference/changelog/#products) |
| `type` | `new`, `improved`, `fixed`, `release`, `deprecated`, `removed` or `notice` |
| `since` | Entries published at or after this time |
| `until` | Entries published before this time |
| `actionRequired` | `true` for only the entries you need to act on |
| `limit` | Entries per page, default 50; a value above 100 returns 100 |
| `cursor` | The previous page's `nextCursor` |

`audience`, `product` and `type` take one value or up to 20 separated by commas, and match entries that have any of them. When you combine parameters, an entry must match all of them. `since` and `until` take a date (`2026-11-01`, read as midnight UTC) or a date-time with a zone (`2026-11-01T17:00:00Z` or `2026-11-01T09:00:00-08:00`; encode `+` as `%2B`). Unknown parameters are ignored. An invalid value, or the same parameter given twice, returns `400`.

```
curl --fail-with-body 'https://api.sogni.ai/v1/changelog?audience=worker&limit=1'
```

```
{
  "status": "success",
  "data": {
    "entries": [
      {
        "id": "2026-11-10-fast-worker-comfy-worker-1-0-257",
        "url": "https://www.sogni.ai/changelog/2026-11-10-fast-worker-comfy-worker-1-0-257",
        "title": "Comfy Worker 1.0.257",
        "summary": "Required application update for B300 workers on the current CUDA 13 image.",
        "bodyMarkdown": "**Released:** November 10, 2026 PT · **Update:** Required application update for B300 workers on the current CUDA 13 image.\n\n- Fixes startup on B300 GPUs using the current CUDA 13 image.\n\n**Disk and settings:** About 455 MB downloads automatically. No additional model weights or settings.",
        "type": "release",
        "audiences": ["worker"],
        "products": ["fast-worker"],
        "version": "1.0.257",
        "links": [
          {
            "label": "Release notes",
            "url": "https://docs.sogni.ai/run-a-worker/fast-worker/release-notes/comfy-worker/#version-10257"
          }
        ],
        "actionRequired": false,
        "effectiveAt": null,
        "publishedAt": "2026-11-10T12:00:00.000Z",
        "updatedAt": "2026-11-10T12:00:00.000Z"
      }
    ],
    "nextCursor": "eyJwIjoiMjAyNi0xMS0xMFQxMjowMDowMC4wMDBaIiwiaSI6IjIwMjYtMTEtMTAtZmFzdC13b3JrZXItY29tZnktd29ya2VyLTEtMC0yNTcifQ"
  }
}
```

## [#](https://docs.sogni.ai/api-reference/changelog/#one-entry)One entry

`GET /v1/changelog/:id` returns one published entry as `data.entry`. An `id` with no published entry returns HTTP `404`, and the body's `errorCode` is `204`.

```
curl --fail-with-body 'https://api.sogni.ai/v1/changelog/2026-10-20-create-keep-every-take'
```

```
{
  "status": "success",
  "data": {
    "entry": {
      "id": "2026-10-20-create-keep-every-take",
      "url": "https://www.sogni.ai/changelog/2026-10-20-create-keep-every-take",
      "title": "Keep every take",
      "summary": "Regenerating an AI transition adds a new take. Preview your takes, use the one you like, and delete the rest.",
      "bodyMarkdown": "Regenerating an AI transition adds a new take. Preview your takes, use the one you like, and delete the rest.",
      "type": "new",
      "audiences": ["artist"],
      "products": ["create"],
      "version": "1.40.0",
      "links": [],
      "actionRequired": false,
      "effectiveAt": null,
      "publishedAt": "2026-10-20T11:59:34.000Z",
      "updatedAt": "2026-10-20T11:59:34.000Z"
    }
  }
}
```

## [#](https://docs.sogni.ai/api-reference/changelog/#products)Products

`GET /v1/changelog/products` returns `data.products`, in display order. Each has an `id` to use with the `product` filter, a display `label` and its `audiences`.

```
curl --fail-with-body 'https://api.sogni.ai/v1/changelog/products'
```

The response below is shortened to three products:

```
{
  "status": "success",
  "data": {
    "products": [
      { "id": "create", "label": "Sogni Create", "audiences": ["artist"] },
      { "id": "api", "label": "Sogni API", "audiences": ["developer"] },
      { "id": "fast-worker", "label": "Fast Worker", "audiences": ["worker"] }
    ]
  }
}
```

## [#](https://docs.sogni.ai/api-reference/changelog/#entry-fields)Entry fields

| Field | Type | Meaning |
| --- | --- | --- |
| `id` | string | Permanent identifier. It does not change once the entry is published. |
| `url` | string | The entry's page on sogni.ai. |
| `title` | string | Headline. |
| `summary` | string | Short summary in plain text. |
| `bodyMarkdown` | string or null | The full text in Markdown. |
| `type` | string | One of the [types](https://docs.sogni.ai/api-reference/changelog/#audiences-and-types). |
| `audiences` | string\[\] | Who the entry is for. |
| `products` | string\[\] | Product ids. |
| `version` | string or null | The product version the change shipped in. |
| `links` | object\[\] | Related pages, each with `label` and `url`. |
| `actionRequired` | boolean | `true` when you need to change something. |
| `effectiveAt` | string or null | When the change takes effect, in ISO 8601 UTC. |
| `publishedAt` | string | When the entry was published, in ISO 8601 UTC. Lists sort and filter on it. |
| `updatedAt` | string | When any field above last changed. |

Entries you need to act on, such as a model retirement or a new minimum worker version, have `actionRequired: true`. For a deprecation or a removal, `effectiveAt` is the day the old behavior stops working. Request `actionRequired=true` to list only these entries.

## [#](https://docs.sogni.ai/api-reference/changelog/#audiences-and-types)Audiences and types

| Audience | For |
| --- | --- |
| `artist` | People creating in Sogni's apps. |
| `developer` | People building on the Sogni API, SDKs and integrations. |
| `worker` | People running a worker on the Sogni Supernet. |

An entry can have more than one audience and more than one product. It has exactly one type:

| Type | Meaning |
| --- | --- |
| `new` | Something you could not do before. |
| `improved` | A change to something that already worked. |
| `fixed` | A fix. |
| `release` | A versioned release, such as a worker or SDK version. |
| `deprecated` | Still works, until `effectiveAt`. |
| `removed` | No longer available. |
| `notice` | Anything else you should know. |

## [#](https://docs.sogni.ai/api-reference/changelog/#paging)Paging

Entries are ordered by `publishedAt`, newest first, and by `id` when two share a time. While more entries match, `nextCursor` is a string: send it back as `cursor`, with the same filters, to get the next page. It is `null` on the last page. Treat the cursor as opaque. Entries published while you page do not shift the pages that follow.

```
async function listChangelog(filters) {
  const entries = [];
  let cursor = null;
  do {
    const params = new URLSearchParams({ ...filters, limit: '100' });
    if (cursor) params.set('cursor', cursor);
    const res = await fetch(`https://api.sogni.ai/v1/changelog?${params}`);
    if (!res.ok) throw new Error(`Changelog request failed: ${res.status}`);
    const { data } = await res.json();
    entries.push(...data.entries);
    cursor = data.nextCursor;
  } while (cursor);
  return entries;
}

const developerUpdates = await listChangelog({ audience: 'developer', since: '2026-11-01' });
```

## [#](https://docs.sogni.ai/api-reference/changelog/#caching-and-polling)Caching and polling

Every route answers with `Cache-Control: public, max-age=300, must-revalidate` and an `ETag` that changes whenever the response body changes. Send the `ETag` back as `If-None-Match`: if nothing changed, the API answers `304 Not Modified` with no body. Each query has its own `ETag`. Poll no more often than every five minutes.

To pick up new entries, poll the first page with `If-None-Match`, or pass the newest `publishedAt` you have as `since`. `since` is inclusive, so that entry comes back too; skip ids you already have.

```
url='https://api.sogni.ai/v1/changelog?audience=developer'
curl -sS -D headers.txt -o changelog.json "$url"
etag=$(awk 'tolower($1) == "etag:" { print $2 }' headers.txt | tr -d '\r')

# Five minutes later. 304: nothing changed. 200: latest.json has the new page.
curl -sS -o latest.json -w '%{http_code}\n' -H "If-None-Match: $etag" "$url"
```

The same poll from Node.js:

```
const url = 'https://api.sogni.ai/v1/changelog?audience=developer';
let etag = null;
let entries = [];

async function poll() {
  const res = await fetch(url, { headers: etag ? { 'If-None-Match': etag } : {} });
  if (res.status === 304) return;
  if (!res.ok) throw new Error(`Changelog request failed: ${res.status}`);
  etag = res.headers.get('ETag');
  entries = (await res.json()).data.entries;
}

await poll();
setInterval(() => poll().catch(console.error), 5 * 60 * 1000);
```

In a browser, call `fetch(url)` without that header: the browser's HTTP cache revalidates with the `ETag` on its own. Setting `If-None-Match` by hand in a browser fails the CORS preflight.

## [#](https://docs.sogni.ai/api-reference/changelog/#feeds)Feeds

`GET /v1/changelog/feed.json` serves the entries as [JSON Feed 1.1](https://www.jsonfeed.org/version/1.1/) and `GET /v1/changelog/feed.atom` serves them as Atom 1.0. Both take the same parameters as the list, `limit` and `cursor` included, so every filtered URL is a feed of its own:

| Feed | Atom URL |
| --- | --- |
| Everything | `https://api.sogni.ai/v1/changelog/feed.atom` |
| Artists | `https://api.sogni.ai/v1/changelog/feed.atom?audience=artist` |
| Developers | `https://api.sogni.ai/v1/changelog/feed.atom?audience=developer` |
| Worker operators | `https://api.sogni.ai/v1/changelog/feed.atom?audience=worker` |
| Action required | `https://api.sogni.ai/v1/changelog/feed.atom?actionRequired=true` |

Replace `feed.atom` with `feed.json` for JSON Feed. Feeds have the list's default of 50 entries per page and link the next page while more entries match: `next_url` in JSON Feed, `<link rel="next">` in Atom.

Every item carries its type, audiences and products. JSON Feed puts them in `tags` (`type:release`, `audience:worker`, `product:fast-worker`) and in a `_sogni` object, which also has the entry's `id`, `version`, `actionRequired`, `effectiveAt` and `links`. Atom uses `category` elements with the schemes `https://www.sogni.ai/changelog#type`, `#audience` and `#product`. Item text is plain text: JSON Feed's `content_text` is the Markdown body, or the summary when there is none, and Atom adds `content` when there is a body.

```
curl --fail-with-body 'https://api.sogni.ai/v1/changelog/feed.json?audience=worker&limit=1'
```

```
{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Sogni changelog",
  "home_page_url": "https://www.sogni.ai/changelog",
  "feed_url": "https://api.sogni.ai/v1/changelog/feed.json?audience=worker",
  "next_url": "https://api.sogni.ai/v1/changelog/feed.json?audience=worker&limit=1&cursor=eyJwIjoiMjAyNi0xMS0xMFQxMjowMDowMC4wMDBaIiwiaSI6IjIwMjYtMTEtMTAtZmFzdC13b3JrZXItY29tZnktd29ya2VyLTEtMC0yNTcifQ",
  "language": "en",
  "authors": [{ "name": "Sogni" }],
  "items": [
    {
      "id": "https://www.sogni.ai/changelog/2026-11-10-fast-worker-comfy-worker-1-0-257",
      "url": "https://www.sogni.ai/changelog/2026-11-10-fast-worker-comfy-worker-1-0-257",
      "title": "Comfy Worker 1.0.257",
      "content_text": "**Released:** November 10, 2026 PT · **Update:** Required application update for B300 workers on the current CUDA 13 image.\n\n- Fixes startup on B300 GPUs using the current CUDA 13 image.\n\n**Disk and settings:** About 455 MB downloads automatically. No additional model weights or settings.",
      "summary": "Required application update for B300 workers on the current CUDA 13 image.",
      "date_published": "2026-11-10T12:00:00.000Z",
      "date_modified": "2026-11-10T12:00:00.000Z",
      "tags": ["type:release", "audience:worker", "product:fast-worker"],
      "_sogni": {
        "id": "2026-11-10-fast-worker-comfy-worker-1-0-257",
        "type": "release",
        "audiences": ["worker"],
        "products": ["fast-worker"],
        "version": "1.0.257",
        "actionRequired": false,
        "effectiveAt": null,
        "links": [
          {
            "label": "Release notes",
            "url": "https://docs.sogni.ai/run-a-worker/fast-worker/release-notes/comfy-worker/#version-10257"
          }
        ]
      }
    }
  ]
}
```

```
curl --fail-with-body 'https://api.sogni.ai/v1/changelog/feed.atom?audience=worker&limit=1'
```

```
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<id>https://api.sogni.ai/v1/changelog/feed.atom?audience=worker</id>
<title type="text">Sogni changelog</title>
<updated>2026-11-10T12:00:00.000Z</updated>
<link rel="self" type="application/atom+xml" href="https://api.sogni.ai/v1/changelog/feed.atom?audience=worker"/>
<link rel="alternate" type="text/html" href="https://www.sogni.ai/changelog"/>
<link rel="next" type="application/atom+xml" href="https://api.sogni.ai/v1/changelog/feed.atom?audience=worker&amp;limit=1&amp;cursor=eyJwIjoiMjAyNi0xMS0xMFQxMjowMDowMC4wMDBaIiwiaSI6IjIwMjYtMTEtMTAtZmFzdC13b3JrZXItY29tZnktd29ya2VyLTEtMC0yNTcifQ"/>
<author><name>Sogni</name></author>
<entry>
<id>https://www.sogni.ai/changelog/2026-11-10-fast-worker-comfy-worker-1-0-257</id>
<title type="text">Comfy Worker 1.0.257</title>
<link rel="alternate" type="text/html" href="https://www.sogni.ai/changelog/2026-11-10-fast-worker-comfy-worker-1-0-257"/>
<link rel="related" href="https://docs.sogni.ai/run-a-worker/fast-worker/release-notes/comfy-worker/#version-10257" title="Release notes"/>
<published>2026-11-10T12:00:00.000Z</published>
<updated>2026-11-10T12:00:00.000Z</updated>
<summary type="text">Required application update for B300 workers on the current CUDA 13 image.</summary>
<content type="text">**Released:** November 10, 2026 PT · **Update:** Required application update for B300 workers on the current CUDA 13 image.

- Fixes startup on B300 GPUs using the current CUDA 13 image.

**Disk and settings:** About 455 MB downloads automatically. No additional model weights or settings.</content>
<category scheme="https://www.sogni.ai/changelog#type" term="release"/>
<category scheme="https://www.sogni.ai/changelog#audience" term="worker"/>
<category scheme="https://www.sogni.ai/changelog#product" term="fast-worker" label="Fast Worker"/>
</entry>
</feed>
```

## [#](https://docs.sogni.ai/api-reference/changelog/#status-codes)Status codes

| Status | When |
| --- | --- |
| `200` | Success. |
| `304` | `If-None-Match` matches the current `ETag`. There is no body. |
| `400` | A parameter is invalid or repeated. `message` names it. |
| `404` | No published entry has that `id`. |
| `429` | Too many requests; see [rate limits](https://docs.sogni.ai/api-reference/getting-started/#rate-limits). |
| `503` | The changelog is temporarily unavailable. Wait for `Retry-After`. |

Errors use the API's [error envelope](https://docs.sogni.ai/api-reference/getting-started/#errors).
