Docs API reference
Markdown Get an API key

API referenceResources

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.

#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
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"
  }
}

#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"
    }
  }
}

#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"] }
    ]
  }
}

#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.
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.

#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.

#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' });

#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.

#Feeds

GET /v1/changelog/feed.json serves the entries as JSON Feed 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>

#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.
503 The changelog is temporarily unavailable. Wait for Retry-After.

Errors use the API's error envelope.