NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
the open source API testing client
Last release 2 days ago
12 Oct 2026
Ships on a steady schedule
a new release about every 2 weeks
Most releases are documented
notes for 53 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
568 releases · first in 2023
One column per quarter.
### Minor Changes - #10555: Show empty optional fields of expanded object query parameters in a searchable Add parameter picker. ### Patch Changes - #
zh-TW, including case and underscore variants, across API Reference, API Client, and schema blocks.### Minor Changes - #10483: Add a request body schema view to the API Client so users can inspect all writable fields alongside custom examples withou
#backdrop slot on ScalarDropdown, ScalarPopover, ScalarListbox, and ScalarCombobox is removed; style the floating element with class instead. ScalarFloatingBackdrop, --scalar-lifted-brightness, and the brightness-lifted utility are deprecated in favor of bg-b-1 dark:bg-b-1.5. ScalarFloatingBackdrop itself now uses the same surface styles, so it no longer clips its slot or draws a real border. A new inset-shadow-border utility draws the hairline border so it can stack with shadow-* without taking up layout space; Tailwind's default inset-shadow-* sizes are reset, matching the other theme namespaces.### Patch Changes - #10463: Fix large request bodies rendering blank gaps in the code editor. - #10431: Keep explicit authentication field clears sepa
The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via operation.codeSample) so screen r
operation.codeSample) so screen readers announce it when it receives focus### Patch Changes - #10422: Avoid allocating unused character match ranges during document search. - #10402: Keep failed requests visible in the respo
Two findings from an accessibility audit, both programmatic only with no change to how anything renders:
#10369: fix: correct the semantics of the authentication card and of nested schema lists
Two findings from an accessibility audit, both programmatic only with no change to how anything renders:
#10371: fix: tidy the client modal header at narrow widths
The method label and copy button now stay inside the address bar at every width instead of moving to a floating row of their own, and the send button spans the full width once it wraps. Below the lg breakpoint, where the address bar fills the header row and its method chip reaches the panel edge, the sidebar toggle moves onto the backdrop as a circle that mirrors the close button in the opposite corner. At wider widths it keeps its original place inside the panel.
#10374: fix: resolve accessibility audit findings in the client modal
aria-controls, so screen readers announce each tab once when arrowing through them#10369: fix: address a batch of screen reader and keyboard accessibility findings
Corrects programmatic semantics only, with no change to how anything renders:
the current sidebar item now reports aria-current, the single content type
readout leaves the tab order, collapsible sections no longer announce their
title twice, the password toggle reports its state through aria-pressed, the
two document download buttons get distinct accessible names, response status
tabs announce what each code means, and the client picker and its search field
get accessible names.
#10361: Preserve configured OAuth redirect URLs when changing credentials or clearing tokens, and hide refresh controls when no refresh token is available.
Previously saved redirect overrides, including empty strings and prefilled page origins, remain unchanged because they cannot be distinguished from intentional user choices. Users affected by the earlier bug must enter the intended redirect URL again.
The public @scalar/workspace-store OAuth secrets types now expose x-scalar-secret-redirect-uri as optional (string | undefined). Consumers must handle an absent override separately from an explicit empty string.
#10363: Avoid duplicate available OAuth2 entries when scopes are selected, and apply configured default scopes when selecting an available scheme.
Generate XML examples from schema metadata, preserving attributes, namespaces, array wrappers, repeated elements, and OpenAPI 3.2 text and CDATA nodes
#10350: Keep long response bodies scrollable inside the body panel in narrow API client layouts.
#10192: Mock-server XML response bytes now use the shared schema-aware serializer instead of json2xml, including attributes, namespaces, and root naming. Existing XML response snapshots may need updating. Supplied serialized XML remains unchanged.
Generate XML examples from schema metadata, preserving attributes, namespaces, array wrappers, repeated elements, and OpenAPI 3.2 text and CDATA nodes. Use the same XML serialization for request bodies, code snippets, response examples, mock responses, and Markdown documentation. Preserve serialized media examples and escape schema string examples as element text.
Explain XML generation failures in response example panels, including the serialized-example escape hatch for large payloads. Expose XML generation failures in mock response headers with X-Scalar-XML-Error, containing the first error diagnostic code. Report diagnostics to other consumers through a callback or the developer console, and format element-only descendants within mixed content without changing text values.
#10334: Include optional form fields when selecting files or editing values, while preserving explicitly unchecked fields.
Non-form whole-query content, including JSON delimiters, is percent-encoded in request URLs and code samples. Use an example with serializedValue on t
#10189: Support OpenAPI 3.2 in: querystring parameters, including content-based serialization, editing the entire query string, schema rendering, and generated request URLs.
Non-form whole-query content, including JSON delimiters, is percent-encoded in request URLs and code samples. Use an example with serializedValue on the parameter itself for URI-ready query content that must retain its existing encoding.
Preserve the encoding of named query values when they coexist with whole-query content in generated code samples, while encoding query authentication values once.
Explain why the whole-query editor disables adding named parameters. Existing named parameters follow the whole-query value, preserving duplicate keys for the server to interpret.
#10186: Support OpenAPI 3.2 additionalOperations in operation storage, navigation, documentation, callbacks, and the API client. Preserve custom HTTP method spelling when displaying and sending requests and generating code samples.
Traversed operation and webhook methods now use the exported OperationMethod type, which accepts custom strings while retaining known-method editor completion. Consumers must handle unknown methods; this open type cannot provide exhaustive checking over the fixed HTTP method set. Unknown method presentation uses colorClass and colorVar, matching known methods. Preserve uppercase and mixed-case additional operation names consistently.
#10186: Show a clear error when a request uses a Fetch-forbidden method (CONNECT, TRACE, or TRACK), including methods changed by pre-request scripts, instead of throwing while building the request.
#10186: Include the current document-defined custom method in the request method picker and preserve its spelling when selected.
Keep QUERY operation chunk names aligned with their references when additional operations are supported.
#10313: Render data table rows inside a tbody so server-rendered tables hydrate. The HTML parser inserts a tbody around rows that sit directly under a table, so markup rendered without one handed the client a tbody where the component tree held the row, and the table — an auth form, for example — was discarded and rebuilt after hydration.
#10186: Preserve request bodies for extension HTTP methods such as QUERY and PROPFIND in the browser client.
#10322: Use OpenAPI 3.2 dataValue and serializedValue examples for named parameters in the editor, outgoing requests, and code samples. Preserve already serialized values without encoding them twice.
Optional parameters with dataValue or serializedValue examples are now enabled by default, matching legacy value examples. Explicitly disabled examples remain disabled.
Parameter-level serializedValue examples remain editable as raw wire text, including parameter names and percent encoding (for example, term=hello rather than hello). Media-level cookie examples are percent-encoded when sent, matching generated snippets. Generating snippets no longer modifies the input cookies.
#10189: Translate the whole-query editor label and explanation in all supported API Client locales.
#10310: Connect SDK code samples to named request body examples using optional example and contentType fields. Keep the example switcher available for static samples and use the selected request example in API client snippets. Display unavailable linked samples as a localized status message in all supported languages.
JSON Lines responses (including application/jsonl and application/x-ndjson), JSON Sequences (application/json-seq and +json-seq) and multipart/mixed o
#10207: Display JSON Lines, JSON Sequences, and multipart response parts as they arrive instead of waiting for the complete response. Preserve cancellation and show malformed records, incomplete multipart responses, and bounded display limits.
JSON Lines responses (including application/jsonl and application/x-ndjson), JSON Sequences (application/json-seq and +json-seq) and multipart/mixed or multipart/x-mixed-replace responses now use the streaming text viewer, including finite responses. Other multipart subtypes, such as multipart/form-data, retain the buffered viewer. Nested parts use hierarchical labels, such as Part 1.1.
The streaming viewer shows received bytes and offers Copy text and Download text for the displayed transcript, including after completion, cancellation, or a framing error. These exports contain formatted records and multipart labels/base64 rather than the original wire body. Streams retain at most 16 MiB of displayed text and reject records/parts above 8 MiB; preview plugins and virtualized raw-body rendering remain available only in the buffered viewer. HTTP status, headers, and declared Content-Length remain visible.
#10175: Support API Client UI translations through localization.translations.apiClient, including the client embedded in API Reference. Ship client translations for English, Russian, Spanish, French, German, Simplified Chinese, Arabic, and Portuguese to match API Reference. Preserve English fallbacks across package providers and react to locale, direction, and translation updates.
#10191: Support OpenAPI 3.2 OAuth device authorization with verification codes, cancellable token polling, stored credentials, and OAuth metadata discovery. Add mock device authorization and approval endpoints with pending, denial, expiry, and polling backoff responses.
Use consistent form-encoded Basic credentials and environment substitution across OAuth token and refresh flows. Allow HTTP metadata and verification links on local development hosts and reserved test domains, coerce discovery fields consistently, and report device-code expiry clearly.
#10178: Support OpenAPI 3.2 streaming item schemas in the workspace store, request body examples, and API reference schema views. Frame generated and structured examples as JSON Lines, JSON Sequence, or server-sent events while preserving explicit wire-format strings.
Preserve generated falsy request examples (0, false, and empty strings) for non-streaming bodies as well.
Use cURL --data-binary for supported streaming media types, making framed body handling explicit. Authored arrays and objects are framed as stream records; authored wire-format strings remain unchanged. SSE records with no valid fields are safely omitted with one console warning per serialization call reporting the omitted count, including when all records are omitted.
#10177: Use OpenAPI 3.2 schemas throughout workspace-store consumers, stories, tests, and type generation. Update the app editor to offer OpenAPI 3.2 validation and completion while continuing to accept existing 3.1 documents.
Preserve OpenAPI 3.2 fields in the loose workspace schema, including tag hierarchy, streaming media types, nested encoding, additional operations, and OAuth device authorization.
The editor intentionally offers the 3.2 field set to documents declaring 3.1 as well; it does not flag 3.2-only fields solely because the declared version is 3.1. This does not certify conformance to the declared version or automatically update it. Before using 3.2-only fields, migrate and explicitly declare OpenAPI 3.2, and verify support in other validators and generators. Remove the unused 3.1 loose-schema generator to prevent schema drift.
Migration: the OpenAPI 3.1 loose-schema generator (@scalar/workspace-store/schemas/v3.1/openapi, published through the wildcard as @scalar/workspace-store/schemas/v3.1/openapi/index) and its @scalar/workspace-store/schemas/v3.1/openapi/reference helpers have been removed. Import the generator from @scalar/workspace-store/schemas/v3.2/openapi/index and the reference helpers from @scalar/workspace-store/schemas/v3.2/openapi/reference instead. The ./schemas/* wildcard and the 3.1 strict-schema exports remain available; the explicit 3.2 strict-schema exports are additive. Locally generated types now use the OpenAPIV3_2 namespace instead of OpenAPIV3_1.
Inline the editor path-extension reference so Monaco retains the leading-slash path pattern and does not report valid paths as unknown properties.
Document ingestion continues to upgrade only to OpenAPI 3.1, so existing inline XML bodies without xml.name remain loadable. This schema migration does not opt consumers into the stricter OpenAPI 3.2 XML upgrade.
#10284: Load the API client modal on its first open request instead of downloading it when the API reference or agent chat mounts. Preserve the requested operation, example, and request-body variant while loading. Show loading feedback and retry guidance if the request editor cannot be downloaded.
#10281: Fix duplicate rows and lost focus when entering request headers, cookies, and query parameters, and remove unchecked parameters cleanly.
#10208: Share OpenAPI 3.2 example-value selection across request bodies, response examples, and code snippets. Preserve serialized payloads verbatim, serialize structured JSON strings correctly, retain falsy values, and replace original example sources after body edits. Keep dataValue and serializedValue during document ingestion.
Editing a request body, including form fields, discards its authored externalValue URL and replaces it with the edited inline value in the workspace and exported API description. Rendering or focusing a form field preserves the external source.
Form editors prefer structured dataValue when both example fields exist, while raw editors, requests, and code snippets preserve serializedValue as wire text. Structured examples now affect generated request payloads and snippets; XML remains raw-only in the request editor.
#10303: Preserve parameter edits when another parameter changes, including parameters displaying downloaded examples. Keep downloaded values out of the document until explicitly edited, and use examples and defaults from resolved schema references when building requests.
Optional parameters (headers, query params, cookies) start disabled by default. When the API description provides a default or enum value for such a p
#10255: fix(api-client): auto-enable optional header/query/cookie rows that have a pre-populated value
Optional parameters (headers, query params, cookies) start disabled by default. When the API
description provides a default or enum value for such a parameter (e.g. x-scenario-id with an enum),
the row was rendered with its checkbox unchecked even though a value was already selected — so the
parameter was silently dropped from every request until the user manually checked it.
The fix auto-enables any row that is only disabled by default (no explicit x-disabled: true) and
already carries a non-empty value, mirroring the existing behaviour when a user types a value into
a previously-empty row.
Use the same enablement rules for the parameter editor, outgoing requests, and generated code snippets.
#10240: Load external examples on demand when their selected preview is visible or Test Request opens, instead of downloading every payload while loading the API description. Share and cache downloads, preserve relative URL origins, and show loading and retry states while preventing incomplete requests from being sent.
Nothing published for this version
For local development, Scalar deliberately relaxes the OpenAPI 3.2 TLS requirement: metadata URLs and discovered endpoints may use HTTP for local deve
#10229: Fix the API client modal getting stuck on "Select an operation to view details" for a document's first operation after its active document re-syncs. The reference used to hand the modal a route to a nonexistent path and method during that re-sync; the modal now leaves the current operation in place instead.
#9912: add line wrapping toggle for request and response bodies
#10179: Support OpenAPI 3.2 OAuth2 metadata URLs in workspace schemas and the shared authentication UI. Fetch HTTPS authorization server metadata or HTTP metadata from local development URLs to discover flows or fill missing endpoints while preserving explicit configuration.
For local development, Scalar deliberately relaxes the OpenAPI 3.2 TLS requirement: metadata URLs and discovered endpoints may use HTTP for local development URLs recognized by the shared isLocalUrl helper, including loopback hosts, 0.0.0.0, and reserved development domains such as *.test and *.example. Other hosts require HTTPS.
Discovery leaves refreshUrl unchanged. Token refresh already falls back to the flow's token URL when no refresh URL is configured, so a discovered token endpoint also supports refresh without overriding an explicit refresh URL.
#9852: Render OpenAPI 3.2 response summaries, server names in the server selectors, and a strikethrough on deprecated security schemes.
#9889: feat: add a copy button to the request body editor
The raw request body editor now shows a copy-to-clipboard button (revealed on hover, matching the response panel) so you can grab the whole body without selecting the text by hand. The editor stays fully editable at any size.
#10231: Trim surrounding whitespace from OAuth2 client IDs and client secrets when authorizing and refreshing tokens.
#10238: Display responses with vendor +xml media types as XML text and use .xml for downloads.
Narrow DOM elements and caught errors before accessing their properties. Correct header lookup to include missing values and handle them during PowerS
#10123: Fall back to the requested URL when a custom fetch returns a response without one. Errors raised while reading the response body are now returned as an error result instead of escaping the request helper.
#10086: Enable optional query parameters when their value is entered.
#10080: Fix the Test Request body showing schema defaults instead of the example on first open. This happened for the first operation when its body used oneOf/anyOf and had a named example.
#10160: Pass request duration to post-response scripts as pm.response.responseTime in milliseconds and enable the response-time example.
#10072: Add a "generate example from schema" button to the request body, so the schema-generated fields stay reachable once an operation ships custom examples
#10081: Keep the mutualTLS security scheme type instead of turning it into an apiKey form, and show read-only authentication guidance for mutual TLS and unsupported browser broker credentials.
#10167: fix: hide the code snippet section when all clients are hidden
#10170: Keep form fields checked for composed body schemas so the initial form matches the fields sent in the request.
#10148: Typing a value into an unchecked optional form body row now enables that row, so the value is sent with the request. This matches how optional query parameters already behave.
#10136: Restore modal and single-file reference tests, update layout selectors, and remove stale comments. Named-resource resolution remains unsupported and is tested explicitly.
#10140: Replace redundant type assertions with compiler-checked annotations, typed accumulators, and existing guards across helpers, API conversion, request handling, and schema rendering.
Narrow DOM elements and caught errors before accessing their properties. Correct header lookup to include missing values and handle them during PowerShell snippet generation.
Validate release-note provider responses, represent unresolved references and absent groups in helper return types, and require narrowing merged object values. Preserve AsyncAPI broker credentials separately from HTTP authentication schemes.
#10149: Keep focus while editing request body field names by saving name changes on blur.
#10142: Send multipart array properties as separate parts with the same field name, applying encoding to each item. Preserve JSON item content types, uploaded files, and array values after form edits, and generate matching code snippets.
Send JSON form fields without an upload filename and preserve fields and files in request history.
Rename the RestSharp snippet's internal getMethod helper so it no longer clashes with the getMethod that Nitro bundles into server builds (the new multipart imports shifted chunking and surfaced the collision).
### Minor Changes - #9937: Add a way to open the request body editor in the Form view by default. Set the defaultRequestBodyView: 'form' config option
defaultRequestBodyView: 'form' config option, or the x-scalar-default-request-body-view extension in your OpenAPI document (which also works per source). Defaults to raw, and falls back to raw when a body cannot be shown as a form.multipart/form-data and application/x-www-form-urlencoded properties now start unchecked and are left out of the request unless you enable them, matching how optional parameters already behave. Required properties are unaffected.feat: test OpenAPI webhooks from the API reference and API client
zod catalog to ^4.4.3 so the standalone bundle ships a single zod instead of two (4.3.5 from @scalar/types plus 4.4.3 from the ai / @ai-sdk peer). This makes standalone.js ~68KB raw / ~18KB gzip smaller.oneOf/anyOf branch switch and regenerated itself from the schema. An open modal now keeps the selection it is already showing, while opening a different entry still re-establishes it.### Patch Changes - #9941: Republish every package through npm trusted publishing. No functional changes.
Nothing published for this version
### Minor Changes - #9868: Control OAuth2 flow tabs from your OpenAPI document. Add x-order to a flow to set the order of the tabs in the auth section
x-order to a flow to set the order of the tabs in the auth section (the first tab is selected by default, so the lowest x-order also becomes the default flow), and add x-scalar-ignore to a flow to hide its tab — useful for flows that cannot run in the browser, like Client Credentials, which usually fails on CORS. x-scalar-ignore on a whole security scheme now hides it from the auth selector too.application/x-ndjson or application/ndjson are now rendered as text, with each JSON record pretty-printed in the preview.pm.environment.get() (and pm.variables.get()) now read the active environment, and pm.environment.set() / pm.environment.unset() persist back to it so values like a bearer token survive to the next request. Previously the script variable store was created empty per request and discarded afterwards, so scripted reads returned undefined and writes were lost even though {{variable}} placeholders resolved correctly.RequestTableRow's handleUpdateRow unconditionally ran isDisabled.value = payload.isDisabled ?? false. When CodeInputLite fired @update:modelValue for
x-scalar-cookies now collapse into a single row with a dropdown to switch between the predefined values — for example a Culture cookie with PL and EN. Only the selected value is sent, and the choice persists.#9793: Expose server and customFetch in the ClientPlugin beforeRequest hook
payload (both optional, additive) so plugins can resolve relative URLs and run
network calls — e.g. a token refresh — through the host fetch without closing
over external state.
#9828: Bump shared build and runtime dependencies to their latest compatible versions
(fuse.js, vite, vitest, tailwindcss, @vitejs/plugin-vue, @vue/test-utils,
posthog-js, yaml, and the CSS injection plugin). The fuse.js 7.5.0 upgrade
tightened generic inference, so the empty new Fuse([]) search instances now
pass an explicit FuseData type argument.
#9798: fix: header parameters with x-disabled: false (e.g. x-scenario-id) now stay enabled while editing
RequestTableRow's handleUpdateRow unconditionally ran isDisabled.value = payload.isDisabled ?? false. When CodeInputLite fired @update:modelValue for the name or value field it called handleUpdateRow({ name: v }) with no isDisabled, which reset the row to enabled on every keystroke and overrode the correct initial state read from x-disabled. It now only updates isDisabled when it is explicitly present in the payload.
#9804: Long file names in the multipart form no longer stretch the request table past its container. The name now truncates with an ellipsis, and hovering shows the full name.
The bearer scheme's form gains an inline Authorize via OAuth2 shortcut (and, for authorization-code, Refresh) that runs the flow and writes the result
#9709: Add an OAuth2 token-acquisition shortcut to HTTP bearer schemes, so a bearer token can be obtained through an OAuth2 flow without switching auth methods.
Authorization: Bearer. A gear opens the
oauth2 configuration in a modal (OAuth2.hideActions).getOauth2AcquisitionTarget helper finds the oauth2 flow the shortcut
uses, preferring the authorization-code grant (which can refresh) over
implicit. Every defined security scheme, oauth2 included, stays selectable in
the auth dropdown — the shortcut is purely additive.runOAuth2Authorize + storeOAuth2Tokens route the access token to the
bearer scheme and the refresh token to the oauth2 scheme.#9726: feat: add a switchable form view for JSON and YAML request bodies
When a request body's content type is JSON or YAML and its schema (or the current example) describes an object, a "Form / Raw" toggle now appears next to the content type selector. The form view renders one row per schema property — with enum dropdowns, required badges, defaults, and per-field validation, matching the existing multipart/form-data editor — and folds edits back into a nested object using the schema's declared types (numbers, booleans, arrays, and nested objects survive the round-trip instead of becoming strings). The raw code editor remains the default and is unaffected for non-object bodies or unparseable text.
@scalar/workspace-store gains reusable exports for this: buildDottedNestedRowPredicate, coerceLeafValueToSchemaType, coerceUntypedValue, and resolveLeafSchema from @scalar/workspace-store/request-example, factored out of the existing multipart request-body builder.
userPassword, plain, scramSha256, scramSha512) get a username + password form like HTTP basic, X509 gets client certificate + private key (PEM) inputs, symmetricEncryption/asymmetricEncryption get a single key input, and gssapi gets a service name input. The entered credentials are persisted in the auth store with new type-specific secret shapes (x-scalar-secret-client-certificate, x-scalar-secret-private-key, x-scalar-secret-service-name, plus the existing username/password/token extensions) and round-trip through the merged scheme objects the same way as the OpenAPI types. The Galaxy AsyncAPI sample document now defines one scheme of each broker group so the inputs can be exercised.DataTableCheckbox now accepts an ariaLabel prop, and RequestTableRow/OAuthScopesInput pass row-specific labels (e.g. "Include x-api-key in request", "Select read:users scope") so screen reader users can tell which row a control acts on.### Patch Changes - #9719: docs: update the Scalar platform overview block in the README
The radius tokens used to be independent, so setting --scalar-radius: 0 still left rounded corners behind on anything using --scalar-radius-lg, --scal
#9687: feat(themes): derive the border radius scale from --scalar-radius
The radius tokens used to be independent, so setting --scalar-radius: 0 still left rounded corners
behind on anything using --scalar-radius-lg, --scalar-radius-xl or rounded-full. They now all
derive from --scalar-radius, which means overriding that single variable rescales every corner in the
interface, and 0 squares it off completely.
Two new tokens fill out the scale, --scalar-radius-2xl (12px) and --scalar-radius-3xl (16px), along
with --scalar-radius-full for pills and circles. The matching rounded-2xl and rounded-3xl Tailwind
utilities now emit CSS; previously they were silently dropped.
Every default value is unchanged, so nothing shifts unless you were relying on the old behaviour. If
your theme sets --scalar-radius on its own and expects the larger radii to stay put, set those tokens
explicitly. Override --scalar-radius on :root: a custom property substitutes var() at the element
where it is declared, so setting the base further down the tree moves it without moving anything derived
from it.
Nothing published for this version
### Patch Changes - #9618: Name the actual document type in the "security scheme is missing a type" warning. When a scheme has no recognizable type, t
documentType prop on the auth selector block, defaulting to openapi. Schemes that carry a valid but unsupported type (such as AsyncAPI broker types like userPassword or scramSha256) now show a dedicated "not supported yet" message naming the type, instead of the misleading "missing a type" warning.### Patch Changes - #9671: Add a canDeleteSchemes prop to the auth selector so the delete (trash) affordance can be hidden. It defaults to true (uncha
canDeleteSchemes prop to the auth selector so the delete (trash) affordance can be hidden. It defaults to true (unchanged for the API client, where schemes are editable) and the API reference now passes false, since its schemes come from the rendered document and cannot be removed there.Nothing published for this version
Nothing published for this version
Adds an optional captureOAuth2Callback option so environments that cannot use browser-popup polling (notably the Electron desktop app, where the rende
#9613: feat(api-client): support an injectable OAuth2 redirect capture for interactive flows
Adds an optional captureOAuth2Callback option so environments that cannot use browser-popup polling (notably the Electron desktop app, where the renderer runs on file://) can run the authorization-code and implicit flows through the system browser and a host-owned redirect target. The desktop app uses this to capture the redirect on a 127.0.0.1 loopback server (RFC 8252).
#9592: fix: only offer the security schemes an operation actually declares
The auth dropdown no longer lists every scheme from components.securitySchemes. In the reference docs and the request modal it now respects the operation's security: an operation with security: [] offers no auth, and an operation that lists a subset of schemes only offers those. The standalone client keeps letting you attach any defined scheme.
Breaking (`@scalar/api-client`): the @scalar/api-client/blocks/operation-code-sample and @scalar/api-client/v2/blocks/operation-code-sample export pat
#8519: refactor: extract the code example block into @scalar/blocks/code-example. api-client, api-client-react, and api-reference now import CodeExample, findClient, generateClientOptions, and the related helpers from the new package. workspace-store exports isParamDisabled with an optional defaultDisabled argument.
Breaking (@scalar/api-client): the @scalar/api-client/blocks/operation-code-sample and @scalar/api-client/v2/blocks/operation-code-sample export paths have been removed. Import from @scalar/blocks/code-example instead, and use the renamed CodeExample / CodeExampleProps (previously OperationCodeSample / OperationCodeSampleProps).
filter[ids][]) on expanded deepObject array parameter rows so the table matches the serialized request, and keep edited array leaves as arrays when writing the value backThe hook runs after the request has been built, right before it is sent. Header mutations apply to the outgoing request and the body bytes match what
#9515: feat: add requestBuilt client plugin hook and onRequestBuilt configuration callback that receive the exact fetch Request that is sent over the wire
The hook runs after the request has been built, right before it is sent. Header mutations apply to the outgoing request and the body bytes match what the server receives, which makes request signing possible: hashing the body of a rebuilt multipart/form-data request would produce a different multipart boundary than the request that is actually sent.
sources). The modal now reads auth secrets under the same document key they are written to.The auth selector now forwards the client's customFetch to the OAuth2 and OpenID Connect flows. This lets the Electron desktop app pipe these requests
#9319: feat: route OAuth2 token exchange/refresh and OpenID Connect discovery through the configured customFetch
The auth selector now forwards the client's customFetch to the OAuth2 and OpenID Connect flows. This lets the Electron desktop app pipe these requests over IPC (like regular API requests) instead of the renderer's network stack, so the desktop Content Security Policy can lock down connect-src. When no customFetch is provided the flows fall back to the global fetch, so web behavior is unchanged.
#9138: feat(api-client): add CodeInputLite, a lightweight contenteditable variable input that replaces CodeMirror in the request, auth, and environment tables for better performance
Path entries and webhooks can reference components.pathItems instead of inlining operations. Navigation, mutators, search, and markdown export now res
#9482: Fix the auth scheme dropdown not opening when multiple client apps are on the page (for example, the API reference modal). Each modal app now gets a unique id prefix, so teleport targets no longer collide and the popover renders in the visible app instead of a hidden one
#9342: fix: resolve operations when OpenAPI path items use $ref
Path entries and webhooks can reference components.pathItems instead of inlining operations. Navigation, mutators, search, and markdown export now resolve path-item references before reading HTTP methods and path-level parameters.
#9498: Sync the SDK installation tabs with the operation code examples: picking a language under "Client Libraries" now switches every operation's code sample to that language's custom example
Nothing published for this version
### Patch Changes - #9449: Replace the CommonJS-only cookie dependency with an in-repo ESM serializeCookie helper
cookie dependency with an in-repo ESM serializeCookie helperIn addition to x-codeSamples, the code sample picker now reads custom samples from x-scalar-examples, x-stainless-snippets, x-stainless-examples, and
#9398: feat: read code samples from x-readme, x-stainless and x-scalar extensions
In addition to x-codeSamples, the code sample picker now reads custom samples from x-scalar-examples, x-stainless-snippets, x-stainless-examples, and x-readme.code-samples. When more than one is present on an operation, the highest-priority source is used (x-scalar-examples > x-stainless-snippets > x-stainless-examples > x-readme > x-codeSamples).
#9438: feat(api-reference): add an AsyncAPI server selector
Adds a server selector for AsyncAPI documents in the API reference introduction. It mirrors the OpenAPI server selector but works with the AsyncAPI server shape (a named map of host/protocol/pathname), labelling each server with its constructed connection URL.
Server selection and variable changes are now persisted to the workspace store via new asyncapi-server:update:selected and asyncapi-server:update:variables events and their mutators, mirroring the OpenAPI wiring.
#9404: Send multipart/form-data and application/x-www-form-urlencoded object properties using their OpenAPI encoding style/explode (for example style: deepObject produces address[city]=... bracket notation) instead of always JSON-stringifying them. The request sent over the wire now matches the generated code snippet.
#9408: Render the client library name as a plain label instead of a dropdown when only a single client is available
Add WebSocketSession with connect, send, and close helpers, plus connectWebSocket orchestration using Result-based errors. Extend ClientPlugin with op
#9341: feat: add WebSocket session transport and plugin hooks for AsyncAPI
Add WebSocketSession with connect, send, and close helpers, plus connectWebSocket orchestration using Result-based errors. Extend ClientPlugin with optional webSocketHooks (beforeConnect, onWebSocketMessage, onWebSocketClose).
#9310: Add an ESM standalone build (dist/browser/standalone.esm.js) alongside the existing UMD bundle. The new bundle works as a side-effect script (registers window.Scalar.createApiReference and reads data-* configuration) and exports createApiReference for direct ESM consumers. It is fully minified through Rolldown's native minifier and uses code splitting so heavy features load asynchronously after first paint:
await import'd inside onMounted instead of statically imported, moving ~265 KB into a chunks/modal-*.js chunk that loads in the background.defineAsyncComponent) becomes a real chunks/AgentScalarChatInterface-*.js chunk (~200 KB), loaded only when the agent is enabled.@scalar/icons/library are coalesced into a single chunks/icons-*.js.Net effect: initial sync load drops from ~3.32 MB (UMD) to ~2.73 MB (ESM) — a ~570 KB improvement — while total bundle size shrinks by ~140 KB.
Also adds an @scalar/api-client/modal/map-hidden-clients-config deep export so consumers that only need the lightweight client-list helper don't pull the full modal barrel into their static graph.
#9323: Fixed x-codeSamples entries that share a lang: multiple code samples with the same language but different labels (e.g. separate sync and async examples) were all marked selected and showed the same snippet. Each sample is now keyed by its position, so every one stays individually selectable.
#9338: perf: warm up the request scripts sandbox on mount when scripts are present, so the first request no longer pays the sandbox cold-start cost
### Patch Changes - #9334: Add analytics events for document save and registry sync (pull/push) actions
Nothing published for this version
Per OAS 3.1.x Encoding Object, contentType SHALL be ignored when the request body media type is not a multipart. After the recent change that lifted t
#9145: fix(api-client): ignore encoding.contentType on application/x-www-form-urlencoded request bodies
Per OAS 3.1.x Encoding Object, contentType SHALL be ignored when the request body media type is not a multipart. After the recent change that lifted the multipart gate on encoding.style/explode/allowReserved, the encoding map started being passed for urlencoded bodies too. As a side effect, a urlencoded encoding entry that only set contentType would JSON-stringify object values into a single part instead of keeping the spec-default dotted-key flattening. Suppress contentType for non-multipart bodies so the flattening branch is restored.
#9145: fix(api-client): encode nested object properties in multipart/form-data as a single JSON part instead of flattening them with dotted keys
#9145: fix(api-client): serialize multipart/form-data and application/x-www-form-urlencoded parts with form / spaceDelimited / pipeDelimited / deepObject styles per RFC6570 when encoding.style / explode / allowReserved is set, matching how query parameters are already serialized. Replaces the dotted-key flattening previously emitted for style: form, explode: true.
#9145: fix(api-client): JSON-stringify nested object/array values under style: form instead of emitting [object Object] in multipart/form-data and application/x-www-form-urlencoded bodies. RFC 6570 form-style serialization only addresses one level of nesting and OpenAPI 3.1 leaves deeper structures undefined; readable JSON is more useful than String(value) garble. The documented escape hatch for cleaner output remains style: deepObject with explode: true.
#9155: feat(api-client): expand nested object properties of multipart form-data schemas into individual editable rows (e.g. props.name, props.description); the wire still sends one application/json multipart part per top-level object property — both for the initial schema-derived example and for edited form rows
#9248: feat: open the API client on the selected operation when launching from API Reference. The modal "Open API Client" link now includes operation_path and operation_method query params; scalar-app reads them after import and navigates to that request. Also fixes address bar blur replay when focus moves programmatically on first navigation into a draft operation.
#9259: fix(api-client): harden response body preview against XSS and referrer leakage
The response body preview now validates src against an allow-list of safe
protocols (blob:, http:, https:, and data: URIs limited to known media
types) before rendering, replaces the <object> fallback with a fully
sandboxed <iframe> (sandbox=""), and sets referrerpolicy="no-referrer"
on all media elements so untrusted response URLs cannot execute script in the
app origin or leak the user's location to third-party hosts.
### Patch Changes - #9236: fix: some analytics events not firing
### Patch Changes - #9216: chore: bumping release - #9218: chore: bump
Request construction now treats a bad merged URL as a first-class failure instead of throwing deep inside helpers. After mergeUrls, resolveRequestFact
WorkspaceDocument an union of OpenApiDocument and AsyncApiDocument#9211: feat: add Cmd/Ctrl+S for ui:save:local-document so hosts (e.g. scalar-app) can match the header Save control for local workspaces
#9211: fix(api-client): block invalid request URLs before send and surface buildRequest failures as results
Request construction now treats a bad merged URL as a first-class failure instead of throwing deep inside helpers. After mergeUrls, resolveRequestFactoryUrl rejects incomplete targets when strict mode applies: relative URLs, an empty server base, or path strings that still contain unresolved {{variable}} placeholders. Callers may set allowMissingRequestServerBase where a full absolute URL is intentionally optional (for example the embedded modal layout in OperationBlock, or API Reference onBeforeRequest hooks that build against the document origin).
buildRequest returns a Result (ok / err) with stable error codes such as MISSING_REQUEST_SERVER_BASE, INVALID_REQUEST_FACTORY_URL, and BUILD_REQUEST_FAILED for unexpected synchronous failures. Those failures are wrapped with safeRun from @scalar/helpers, which logs to console.error and maps throws to a string message on the result. The API Reference plugin path logs and skips onBeforeRequest when a preview request cannot be built, so user hooks never run against a half-built fetch payload.
Downstream packages (api-client, api-reference, scalar-app where applicable) unwrap the result, show toasts or logs, and avoid calling sendRequest until the URL is valid.
#9211: fix: OAuth scope CRUD UI
auth:upsert:scopes and auth:delete:scopes, plumbed from OAuth2 → RequestAuthTab → RequestAuthDataTable and registered in initializeWorkspaceEventHandlers. Updating checked scopes remains auth:update:selected-scopes without newScopePayload.– before a description is omitted when the description is empty or missing.scope prop), inline errors for missing name and duplicate names (replacing toast-only validation), trims submitted names, and tests clean up teleported modal DOM between runs.#9211: feat: some polish for the scalar-app
#9211: fix: format raw JSON responses with jsonc-parser
Raw JSON response bodies in the API client are now formatted with jsonc-parser instead of @scalar/helpers prettyPrintJson. The previous path parsed with JSON.parse and re-stringified with JSON.stringify, which coerces every JSON number to a JavaScript Number and loses precision for integers beyond Number.MAX_SAFE_INTEGER (a common pain point for 64-bit IDs and other large values). jsonc-parser formats the document as text, so numeric literals stay identical to the response on the wire while indentation and line breaks are still normalized. JSON with Comments (JSONC) tokens also remain valid alongside CodeMirror’s JSON mode.
#9211: Remove unwanted scrollbar beside auth scope checkboxes
#9211: fix: share executable URL build for copy and buildRequest
Copy URL from the operation address bar now matches the URL that is actually sent: path parameters, operation query string, environment substitution, and security schemes that use in: query are all applied the same way as Send.
#9211: fix: handle registry document and version deletion in document settings
#9211: fix: prevent address bar from stretching past max width
#9211: feat: add more analytics events
#9211: feat: add Preview/Raw tabs for JSON responses with true raw body view
JSON bodies now open on a formatted Preview tab (JSONC pretty-print without JSON.parse round-trip). The Raw tab shows the exact decoded response text. Other media types are unchanged; HTML, images, and other previews already used the same toggle pattern.
#9211: fix: padding on addressbar with no servers
#9211: fix: history bug on operation switch
#9211: fix(api-client): narrow request table parameter info popover width
#9211: fix(api-client): expand object query parameters in the request UI
#9211: feat: optimize layout for mobile
#9211: fix(api-client): hide OAuth2 client secret when PKCE is enabled and omit it from token requests
#9211: fix: posthog stream warning
#9211: refactor: remove the main import file since it was empty
#9211: fix(api-client): request body content types — OpenAPI extras, MIME labels, and "Other" without auto Content-Type
The request body dropdown lists built-in types first, then any additional media types from the OpenAPI operation. Labels use the MIME essence (no charset in the label). The Other option is available again for a raw body: it does not add an automatic Content-Type header (users can set one manually). Code snippets avoid injecting Content-Type: other.
getDefaultHeaders and filterDisabledDefaultHeaders are exported from @scalar/workspace-store/request-example; the API client uses them for code snippets instead of a duplicate helper.
#9211: fix invalid Tailwind gap utility in the address bar
#9211: fix: prevent stuck response overlay after overlapping sends
Fixes a case where the response loading overlay could stay visible indefinitely and Cancel had no effect after opening an example and sending a request very quickly (or when multiple sends overlapped).
The reason for that is that ResponseLoadingOverlay delays showing the spinner by 1s. Each hooks:on:request:sent scheduled a new setTimeout without clearing the previous one. Overlapping sent events could leave an orphaned timer that still called loader.start() after the request had already finished and hooks:on:request:complete had run—so the overlay turned on with no further complete, and Cancel targeted an AbortController that no longer matched the finished request.
#9211: build: switch Monaco Vite plugin to ESM and align workers
#9211: chore: move app files from client to scalar-app
Move the tabs on top of the page for the app layout and make the layout better for small screens
### Minor Changes - #9050: feat: support for registry sync and local persistence ### Patch Changes - #9076: fix(api-reference): improve rendering of v
### Patch Changes - #9049: Flush pending debounced operation edits before executing API client requests. - #9023: chore: use homemade slugger
### Minor Changes - #9045: feat: support version switching for regsitry documents - #9045: feat: ensure teams can have only one workspace and create d
### Minor Changes - #9000: feat: support version switching for regsitry documents - #8986: feat: ensure teams can have only one workspace and create d
### Patch Changes - #8839: Fix modal fade-in animation stutter by replacing v-show with CSS visibility/opacity to avoid forced layout recalculation on
### Minor Changes - #8972: feat: implement the new workspace sidebar - #8977: feat: add app header ### Patch Changes - #8978: fix: layout height colla
### Patch Changes - #8952: Export shared Scalar custom header constants from @scalar/helpers/http/scalar-headers and consume them in request build/sen
### Patch Changes - #8940: feat(api-client): support header for web layout
### Minor Changes - #8891: feat: support refreshing the token ### Patch Changes - #8877: fix(api-client): prefill oauth2 redirect URI after switching
### Minor Changes - #8865: feat: add plugin support for custom response body content types ### Patch Changes - #8810: refactor: move telemetry to an o
Added a new php/laravel client generator in @scalar/snippetz, including comprehensive request coverage for headers, cookies, auth, query params, JSON,
#8827: chore: removed old client v1 code
#8828: Add support for text/json media type
#8840: feat: allow updating the proxyUrl and make options reactive in api-client
#8735: fix: replace direct cjs mime and curl dependencies with local implementations
#8848: fix: use search for virtual responses
#8825: chore: moving files around in preparation for the big deletion of client v1
#8794: Fix Monaco 0.55 compatibility in JSON/YAML editor language helpers.
#8817: feat(snippetz): add a Laravel HTTP client plugin for PHP snippets
Added a new php/laravel client generator in @scalar/snippetz, including comprehensive request coverage for headers, cookies, auth, query params, JSON, multipart, form-encoded, binary, and fallback bodies.
Updated generated client registries and schema wiring so the new client is available across Scalar:
@scalar/types GROUPED_CLIENTS / AVAILABLE_CLIENTS@scalar/workspace-store reference-config schemaUpdated api-client expectations for the increased total built-in client count.
#8849: fix(api-client): improve drag regions
#8850: chore: remove entities, zod and the parser from oas-utils
#8823: fix: prevent address bar text from hiding under fade overlay while typing
### Minor Changes - #8761: feat: improve UX for creating a new operation - #8773: feat: suport for set-cookie header ### Patch Changes - #8778: fix: h
### Minor Changes - #8748: feat: support allowReserved for code samples - #8695: feat: suport pre/post request scripts ### Patch Changes - #8760: feat
### Minor Changes - #8712: feat: use separate stores for client and shared state on the reference ### Patch Changes - #8728: fix: correctly merge secu
Adds a regression test that exercises the full oauth2 merge + authorize path for clientCredentials and verifies x-scalar-security-body fields (for exa
#8692: feat: replace pretty-bytes dependency with internal helper
#8518: test(api-client): add regression coverage for oauth2 clientCredentials security body
Adds a regression test that exercises the full oauth2 merge + authorize path for
clientCredentials and verifies x-scalar-security-body fields (for example
audience) are preserved and sent in the token request body.
#8661: fix(api-client): support OAuth redirect callback override for Electron-friendly flows
#8634: feat: implement improved saving UI
#8647: feat: move addressBar path change from debounce to blur
#8713: feat: handle pasting and typing urls in the path box
#8698: fix: missing reference parameters by making skipping behavior opt-in
#8652: feat: keep form-data file delete action accessible on touch
### Patch Changes - #8625: fix: Add Variable button now navigates to environment tab using existing @navigate event pattern
### Patch Changes - #8610: fix(api-client): improve editor background color handling
Your coding agent can read these notes before it upgrades. Set up the MCP server →