Skip to content

2026.09.81 — 2026-09-30 ​

Breaking ​

  • Paginate every list endpoint with one envelope (0d43b660)

    Every endpoint that returns a collection now answers with {data, page, pageSize, count, hasNext} and takes page (1-based) and size (default 50, at most 500). Table-backed lists page in SQL (audit, broker events, request-reply flows, alert history, config applies, notification deliveries, bulk runs, plugin history); the rest slice the list they already hold. The audit, flow and alert-history page views are now the shared envelope. The message and broker-event pages keep their extra fields beside the envelope. The web UI reads the envelope, asking for size=500 where it needs a whole short list.

  • Resolve the API version from the path and send deprecation headers (57f657ea)

    The API version is now Spring's API version, read from the second path segment of /api/{version}. Controllers map only what follows the prefix, so URLs are unchanged. Only v1 is supported: any other version is a 400 invalid-api-version problem. A declared deprecation sends Deprecation, Sunset and Link headers and marks the operation deprecated in the OpenAPI document; nothing is deprecated yet. The document's info.version is now the running Studio version, and a new REST API guide covers versioning, breaking changes, errors, limits, lists and idempotency.

  • Return problem+json for every error (15d13f8c)

    Every failure now has an application/problem+json body with a stable type: 401 unauthenticated, 403 forbidden and csrf, framework errors (bad-request, not-found, method-not-allowed, not-acceptable, unsupported-media-type) and a 500 internal-error that carries a request id and hides the cause. The login-throttled and too-many-queries 429s send Retry-After. The OpenAPI document declares 4XX, 5XX and 429 problem responses on every operation.

Added ​

  • Serve the diagnostics endpoints under the API version (8f77ce42)

    The support bundle and bug-report summary endpoints no longer spell /api/v1 in their mappings; the version prefix is added like for every other controller. Their errors were already problems, and the OpenAPI document now lists the 4XX, 5XX and 429 responses on them.

  • Paginate every list endpoint with one envelope (0d43b660)

    Every endpoint that returns a collection now answers with {data, page, pageSize, count, hasNext} and takes page (1-based) and size (default 50, at most 500). Table-backed lists page in SQL (audit, broker events, request-reply flows, alert history, config applies, notification deliveries, bulk runs, plugin history); the rest slice the list they already hold. The audit, flow and alert-history page views are now the shared envelope. The message and broker-event pages keep their extra fields beside the envelope. The web UI reads the envelope, asking for size=500 where it needs a whole short list.

  • Resolve the API version from the path and send deprecation headers (57f657ea)

    The API version is now Spring's API version, read from the second path segment of /api/{version}. Controllers map only what follows the prefix, so URLs are unchanged. Only v1 is supported: any other version is a 400 invalid-api-version problem. A declared deprecation sends Deprecation, Sunset and Link headers and marks the operation deprecated in the OpenAPI document; nothing is deprecated yet. The document's info.version is now the running Studio version, and a new REST API guide covers versioning, breaking changes, errors, limits, lists and idempotency.

  • Accept Idempotency-Key on every mutating endpoint (bc1432ef)

    A POST, PUT, PATCH or DELETE under /api/v1 may now carry an Idempotency-Key header (1 to 255 printable ASCII characters). Within 24 hours a repeat of the same request (method, path, query and body) by the same user returns the first status and body without applying the mutation again, marked Idempotent-Replayed: true. Keys belong to the calling user; tokens and sessions of one user share them. A request without the header behaves as before, and the plugin gateway (/api/v1/p/, /api/v1/clusters/*/p/) is left to the plugins.

    Refusals, all application/problem+json:

    • 422 idempotency-key-reused: the key was used for a different request (a dryRun=true preview and the real run are different requests, so send a new key for the real run).
    • 409 idempotency-in-progress with Retry-After: 1: the first request is still running.
    • 400 idempotency-unsupported: a multipart upload, or a body over 8 MiB, carried a key.
    • 400 invalid-idempotency-key: the key is empty, over 255 characters or not printable ASCII.

    A 5xx answer, an exception, and a 401, 403 or 429 are not recorded, so the retry runs. Other 4xx answers are, so a corrected request needs a new key.

    Keys are stored in the new idempotency_record table (applied on startup) and listed on the Data page as "Idempotency keys", with a 24 hour retention that cannot be shortened.

  • Return problem+json for every error (15d13f8c)

    Every failure now has an application/problem+json body with a stable type: 401 unauthenticated, 403 forbidden and csrf, framework errors (bad-request, not-found, method-not-allowed, not-acceptable, unsupported-media-type) and a 500 internal-error that carries a request id and hides the cause. The login-throttled and too-many-queries 429s send Retry-After. The OpenAPI document declares 4XX, 5XX and 429 problem responses on every operation.

  • Publish generated TypeScript and Java clients (dcb4bea1)

    Every release now publishes two clients generated from that release's OpenAPI document: @artemis-studio/client on npm (typed openapi-fetch client with bearer auth and a typed ProblemError for problem+json answers) and io.github.sudoitir:artemis-studio-client on Maven Central (java.net.http and Jackson). The release also attaches artemis-studio-<version>.openapi.json with its checksum and provenance.

Fixed ​

  • Serve Studio's health under the API version like every endpoint (3f966e49)

  • Spell the plural of address in the resource lists (3b481cf0)

    The empty state and the pager read "No addresss" and "addresss".

  • Report the page size the message browser actually serves (0a2e531f)

    The broker serves at most 200 messages a page. A larger size is now reported as 200, and hasNext is worked out from it, so a client asking for 500 is told that more messages follow rather than that the queue ends. The UI's full-list reads also stop at an empty page.

  • Accept only the canonical v1 spelling of the API version (74e12ca8)

    /api/1/..., /api/V1/... and /api/1.0/... are refused with 400 invalid-api-version. Before, Spring's version parser read them as version 1, so they reached the v1 endpoints past the checks that match the /api/v1/ prefix, such as a disabled feature.

  • Expire idempotency keys and recover abandoned ones (7a9528f4)

    An Idempotency-Key whose first request never finished (a crash or a lost connection) is taken over after a 10 minute lease instead of answering 409 until the purge. A key older than 24 hours is forgotten even before the data lifecycle removes it, and a new request claims it. A replay now also carries the original Location and ETag headers, never a cookie. A response over 8 MiB is not recorded, so the retry runs. The table (idempotency_record, unreleased) gains a headers column.

  • Ship the JSON Schema validator the MCP server needs (c759b372)

    The contract tests declared com.networknt:json-schema-validator test-scoped, which also removed the copy the MCP server reads at runtime from the jar, so the packaged application failed to start with NoClassDefFoundError. It is now a normal dependency.

  • Load every page of a list the UI shows in full (2dbc0988)

    requestAll stopped at one page of 500, so a list longer than that showed its first rows and read as complete. It now follows hasNext and joins the pages.

  • Document every response field the API returns (943dd2e6)

    The OpenAPI document now describes every member a problem response can carry, marks the fields that are null when unknown as nullable, and documents the optional Idempotency-Key header on every mutating operation.

  • Send the wait for a refused query in the problem body (d634bf68)

    The console's stream reports too-many-queries as a failed frame inside a 200, which cannot carry a Retry-After header, so the problem now also has a retryAfter property with the same wait.

Security ​

  • Accept a caller's X-Request-Id only when it is a plain token (6df8a75c)

    A request id with line breaks or other characters outside letters, digits, dot, dash and underscore (up to 64) is replaced by a generated one before it reaches the logs, the audit trail or an error body, so it cannot forge log lines.

Apache-2.0. Apache ActiveMQ and Apache ActiveMQ Artemis are trademarks of the Apache Software Foundation. Artemis Studio is an independent project, not produced by, endorsed by, or affiliated with the ASF.