Make Bold API testing,
one line of code

Embed a Make Bold Spark API testing workbench into any .NET 10 Minimal API project. Autodiscovers your OpenAPI v3 endpoints. No separate deployment required.

⚡ Open Live Demo Get Started →

Install from NuGet

dotnet add package ApiTestSpark
📦
v1.5.0

ApiTestSpark

MIT license  ·  net10.0  ·  500 KB  ·  No dependencies  ·  Last updated June 12, 2026

Version
1.5.0
Framework
.NET 10.0
License
MIT
Package Size
500 KB
Dependencies
None
api openapi-v3 minimal-api aspnetcore net10 react spa developer-tools api-testing remote-api embedded-ui curl swagger-ui-alternative api-documentation local-development make-bold-spark make-bold-solutions

Everything you need to test your API

API Test Spark embeds a React-powered test harness directly into your .NET application. No extra services, no configuration files, no separate deployments.

🔍

OpenAPI Autodiscovery

Points at your OpenAPI v3 document and renders every endpoint in a collapsible accordion grouped by tag. Works with .NET's built-in MapOpenApi().

📦

Single NuGet Package

The entire React SPA is embedded as resources inside the package. No wwwroot copying, no CDN, no build step required in your app.

🔐

Auth & Header Injection

Pre-populate Bearer tokens, API keys, or custom headers for every request. Supports Bearer, ApiKey, and Basic schemes.

🐛

Live Debug Panel

Inspect every request, response, and error in real time. cURL snippet generation per request. FIFO history buffer keeps memory bounded.

📄

API Doc Builder

Select endpoints, capture live curl + responses, annotate sections, and export a complete markdown document for front-end developer agents — at /api-docs.

🔒

Environment Gating

Restrict the harness to specific environments such as Development or Staging. One option keeps the harness out of production entirely.

🎛️

Demo Integration Toggle

Set EnableDemoIntegrations = false to hide the built-in JokeAPI and JSONPlaceholder screens. Present a clean harness showing only your host API and API Doc Builder — no sample data, no external noise.

✏️

Editable Nested Responses

Depth-1 nested object fields in API responses render as collapsible editable sub-forms. Edit a nested value and click "Copy as JSON" to get updated output — without leaving the tool.

📋

Copy as cURL (Response Panel)

One-click cURL command generation is now available in the response panel as well as the request panel. The command always captures the request that produced the response shown.

🔎

Pretty / Minified JSON Toggle

Switch between 2-space-indented and single-line JSON views for any raw JSON response. The preference persists across API calls for the browser session and resets on page reload.

🏷️

JSONPath Field Labels

Every field in the response form shows its dot-notation JSONPath address ($.field, $.parent.field) as a tooltip. Click any field label to copy the path to the clipboard.

🌐

Remote API Profiles

Browse and test multiple named remote REST APIs from their OpenAPI documents. Configure RemoteApiProfiles in Program.cs or add browser-local profiles from the Config page.

🎨

Make Bold Spark Branding

The embedded UI ships with Make Bold Solutions colors, logo assets, favicon set, package icon, and Inter Tight typography as part of the Make Bold Spark product family.

🔑

Credential-Safe Proxy

A server-side proxy endpoint (GET /api-test-spark/remote-spec?profileId=...) resolves server profiles by id and injects API keys or Bearer tokens without serializing secrets to the browser.

🪪

Header Token Expansion

Header values support {session-guid} (one UUID per page load) and {request-guid} (fresh UUID per call), expanded at request-send time. Ideal for correlation IDs in distributed tracing.

📑

Remote API Doc Builder

The same endpoint-capture and markdown-export experience as the host API Doc Builder, but scoped to the selected remote profile so generated docs use that profile's name and description.

Quickstart

From zero to a running test harness in under five minutes.

1

Install the NuGet package

Run this in your project directory or use the NuGet Package Manager.

dotnet add package ApiTestSpark
2

Add OpenAPI support (if not already present)

.NET 9+ includes OpenAPI support built-in. Add it to the service container and map the document endpoint.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();          // built-in .NET 9+

var app = builder.Build();
app.MapOpenApi();                        // serves at /openapi/v1.json
3

Register the harness with one line

Call MapApiTestSpark() after building the app. That's all that's required.

app.MapApiTestSpark();

The harness is now live at https://localhost:{port}/api-test-spark/

4

Full minimal Program.cs

A complete working example — copy, paste, run.

using ApiTestSpark;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();

var app = builder.Build();
app.MapOpenApi();

app.MapGet("/products", () => new[] {
    new { Id = 1, Name = "Widget", Price = 9.99 }
}).WithSummary("List all products");

app.MapApiTestSpark(options =>
{
    options.OpenApiUrl = "/openapi/v1.json";
    options.Environments = ["Development"];
    options.EnableDemoIntegrations = false; // hide demos, show only your API
});

app.Run();

Configuration options

All options are set via the Action<ApiTestSparkOptions> delegate passed to MapApiTestSpark(). Every property has a sensible default — only set what you need.

Property Default Description
OpenApiUrl "/openapi.json" Relative or absolute URL to your OpenAPI v3 JSON document. The SPA fetches this on startup to discover endpoints. Set to null to disable autodiscovery.
AuthScheme null Advertises the auth scheme to the SPA UI ("Bearer", "ApiKey", or "Basic"). Pre-populates the auth field. Never a token value.
DefaultHeaders {} Key-value headers injected into every request the SPA makes to your API. Use for tenant IDs, correlation headers, etc. Must not contain secrets — values are served via the public config endpoint.
Environments [] (all) Environment names where the harness is active. Empty array enables it everywhere. Example: ["Development", "Staging"] keeps it off production.
CorsOrigins [] (same-origin) Extra origins allowed to call the config endpoint. Use when the Vite dev server and your .NET API run on different ports, e.g. ["http://localhost:5151"].
EnableVerboseLogging false Emits ILogger.LogDebug for every static asset served and every SPA fallback. Alternatively set Logging:LogLevel:ApiTestSpark=Debug in appsettings without redeploying.
EnableDemoIntegrations true When false, hides the built-in JokeAPI and JSONPlaceholder demo screens from the home page and disables their routes (/joke-api, /json-placeholder). The home page shows only Host API Explorer and API Doc Builder. Default true — existing installs are unaffected.
RemoteApiProfiles [] List of named remote API defaults. Each profile includes an id, name, description, base URL, OpenAPI URL, credentials, and default headers.
RemoteBaseUrl null Legacy single-remote base URL. Used as one compatibility profile when RemoteApiProfiles is empty.
RemoteOpenApiUrl null Legacy single-remote OpenAPI URL. Used as one compatibility profile when RemoteApiProfiles is empty.
RemoteOpenApiApiKeyHeader null Legacy API key header name for the compatibility profile.
RemoteOpenApiApiKeyValue null Legacy API key value. Used server-side only and redacted from /api-test-spark/config.
RemoteOpenApiBearerToken null Legacy bearer token. Used server-side only and redacted from /api-test-spark/config.
RemoteDefaultHeaders {} Legacy headers injected into every browser-side request to the compatibility remote API. Supports {session-guid} and {request-guid} tokens.

Example — auth, custom headers, and environment gating

app.MapApiTestSpark(options =>
{
    options.OpenApiUrl   = "/openapi/v1.json";
    options.AuthScheme   = "Bearer";
    options.DefaultHeaders["X-Tenant-Id"] = "acme";
    options.Environments = ["Development", "Staging"];
});

Example — Remote API Profiles with credential-safe proxy

Configure named remote API profiles. Server profile specs are fetched by profile id so API key values stay server-side and redacted from the config payload.

app.MapApiTestSpark(options =>
{
    options.OpenApiUrl                   = "/openapi/v1.json";
    options.RemoteApiProfiles.Add(new RemoteApiProfile
    {
        Id = "partner-api",
        Name = "Partner API",
        Description = "External partner integration endpoints.",
        RemoteBaseUrl = "https://api.partner.com",
        RemoteOpenApiUrl = "https://api.partner.com/openapi.json",
        RemoteOpenApiApiKeyHeader = "x-api-key",
        RemoteOpenApiApiKeyValue = "your-api-key", // stays server-side
        RemoteDefaultHeaders =
        {
            ["correlationId"] = "{request-guid}",
            ["sessionId"] = "{session-guid}",
        },
    });
});

Example — behind a reverse proxy

Call UseForwardedHeaders() before MapApiTestSpark() so the config endpoint reports the correct public base URL.

app.UseForwardedHeaders();
app.MapApiTestSpark();

Live demo

This server is the live demonstration. Three related API groups are running and fully annotated — Products, Customers, and Orders. API Test Spark has autodiscovered all of them via the OpenAPI document.

Click to open the harness. Use the collapsible group list on the left to navigate between resource groups. Request body fields are pre-filled from the schema. Responses render as sortable tables or editable forms in the debug panel.

⚡ Open API Test Spark
Products
  • GET/products
  • GET/products/{id}
  • POST/products
  • PUT/products/{id}
  • DELETE/products/{id}
Customers
  • GET/customers
  • GET/customers/{id}
  • POST/customers
  • PUT/customers/{id}
  • DELETE/customers/{id}
Orders
  • GET/orders
  • GET/orders/{id}
  • GET/orders/customer/{id}
  • POST/orders
  • PATCH/orders/{id}/status
  • DELETE/orders/{id}
Running .NET 10 Minimal API
📖 OpenAPI v3 — full schema + descriptions
📦 ApiTestSpark v1.5.0 — MIT
🔗 16 endpoints across 3 resource groups
⚖️ No dependencies — 500 KB

How it works

API Test Spark compiles the React SPA into embedded resources inside the NuGet package. When you call MapApiTestSpark(), the library registers four things into your ASP.NET Core pipeline:

Static file middleware

Serves the embedded SPA assets (HTML, JS, CSS, icons) at /api-test-spark/ using EmbeddedFileProvider. No files are copied to your project. No wwwroot changes.

Config endpoint

Registers GET /api-test-spark/config. The SPA fetches this on startup to receive all configuration — host API URL, auth scheme, default headers, redacted remote API profile metadata, and the harness version/build date. Nothing is hardcoded in the bundle.

{
  "baseUrl": "https://your-api.example.com",
  "openApiUrl": "/openapi/v1.json",
  "authScheme": "Bearer",
  "defaultHeaders": { "X-Tenant-Id": "acme" },
  "enableDemoIntegrations": true,
  "remoteApiProfiles": [
    {
      "id": "partner-api",
      "name": "Partner API",
      "description": "External partner integration endpoints.",
      "remoteBaseUrl": "https://api.partner.com",
      "remoteOpenApiUrl": "https://api.partner.com/openapi.json",
      "remoteOpenApiApiKeyValue": null,
      "remoteOpenApiApiKeyConfigured": true,
      "source": "server",
      "proxyMode": "server"
    }
  ],
  "harnessVersion": "1.5.0",
  "harnessBuiltAt": "2026-06-09T01:24:11Z"
}

Remote spec proxy

Registers GET /api-test-spark/remote-spec?profileId=.... When a server-configured Remote API Explorer loads, the SPA requests this endpoint by profile id. The proxy resolves only server-provided profiles, injects API keys or Bearer tokens server-side, fetches the remote OpenAPI document, validates it, and returns the JSON. Browser-created profiles fetch their OpenAPI documents directly from the browser.

SPA fallback middleware

Extensionless paths under /api-test-spark/ fall back to index.html so client-side routing works. Requests for unknown file extensions return HTTP 404 — the SPA never silently swallows asset 404s.

Maximising your API Test Spark experience

API Test Spark's entire input is your OpenAPI v3 document. Everything it renders — endpoint groups, descriptions, request scaffolds, response schemas, status codes — comes directly from that document. The richer your OpenAPI metadata, the better your test harness. This page is itself a live example: every section below is demonstrated by the running Products, Customers, and Orders API. Open the harness alongside this guide to see each technique in action.

OpenAPI featureWhat API Test Spark does with itImpact
operation tags with "Namespace: Label" formatTwo-level collapsible accordion groups on the left navHigh
operation summaryBold title shown on every endpoint cardHigh
operation description (markdown)Rendered markdown below the summary — bold, lists, code, tablesHigh
operationId / WithName()Copyable chip beside each endpoint; used in API Doc Builder referencesHigh
request body schema with example / defaultJSON scaffold pre-filled in the request body editorHigh
schema property descriptionShown in the schema property table beside each fieldHigh
Produces<T> per status codeColoured response-code badges with expandable inline schemasHigh
info.title, info.version, info.contactAPI info header at the top of the Host API screenMedium
info.description (markdown)Rendered in the API info header — ideal for workflow walkthroughsMedium
parameter description + exampleShown in the parameter table; example pre-fills path/query fieldsMedium
schema constraints (minLength, maximum, enum)Displayed in schema property tables; enum drives a select inputMedium
deprecated: trueEndpoint visually flagged as deprecated in the accordionLow
info.licenseShown in the API info headerLow

1 — Tag your endpoints with a two-level group name

API Test Spark parses tags in "Namespace: Label" format into a two-level accordion. Without this pattern all endpoints land in a single flat list.

  • Use WithTags("Products: Catalog") on your route group
  • Or apply [Tags("Orders: Lifecycle")] on a controller
  • The colon + space is the separator — anything before it is the group, anything after is the sub-label
  • Consistent casing matters: "Auth: Tokens" and "auth: tokens" become separate groups

2 — Write a summary and a description for every operation

summary is the title shown on every card. description accepts full markdown and renders inline — use it to explain behaviour, constraints, and cross-references.

  • Summary — short imperative phrase: "List all products", "Place a new order"
  • Description — explain what the response contains, valid input ranges, seeded test data, and what to try next
  • Markdown bold (**text**), inline code, bullet lists, fenced code blocks, and tables all render
  • Embed a workflow callout in your POST description linking to the next step in a typical flow

3 — Name every operation with WithName()

operationId (set via WithName() on Minimal APIs) is surfaced as a copyable chip on each endpoint card and used as the section heading in exported API Doc Builder documents.

  • Use PascalCase verb-noun: GetProductById, CreateOrder, UpdateOrderStatus
  • Must be unique across the entire document
  • On controllers, the method name becomes the operationId automatically
  • Clients and generated code also use this — it doubles as your SDK method name

4 — Declare every response code with Produces<T>

Each .Produces<T>(statusCode) call adds a coloured badge in the harness. Click the badge to expand the inline schema. Undeclared status codes produce no badge — testers have to guess.

  • Always declare 200/201 with the response type
  • Declare 400 with Produces<string>(400) or a problem-details type
  • Declare 404 for any lookup by ID
  • Use TypedResults — it declares response types automatically without extra .Produces() calls
  • On controllers, use [ProducesResponseType] attributes

5 — Annotate your schema types with descriptions and constraints

API Test Spark renders a property table for every request body and response schema. [Description], [Range], [MinLength], and [MaxLength] all appear as columns in that table.

  • Add [Description("...")] from System.ComponentModel to every public property
  • Use [Range(min, max)] for numeric bounds — displayed in the constraints column
  • Use [MinLength] / [MaxLength] for string lengths
  • Use [Required] — surfaced as a required marker in the table
  • enum types render as a select input in the scaffold editor

6 — Set examples and defaults on schema properties

API Test Spark pre-fills the JSON scaffold from example → default → enum[0] → type placeholder. Without examples, every field shows a generic placeholder. With examples, testers can run requests immediately.

  • Add [DefaultValue("acme")] to pre-fill string fields
  • For records, set default parameter values: int StockQuantity = 0
  • Use WithOpenApi(op => { op.RequestBody.Content["application/json"].Example = ... }) for a full example body
  • Realistic test data (real-looking IDs, prices, names) makes the harness immediately usable

7 — Use info.description for workflow documentation

The API-level info.description field renders as markdown in the Host API screen header. Use it to describe the overall API, link resource groups together, and provide a step-by-step workflow for testers.

  • Set it via AddDocumentTransformer in AddOpenApi()
  • Include a markdown table of resource groups and their endpoint counts
  • Add a numbered workflow walkthrough: create customer → create product → place order → advance status
  • Mention seeded test data (IDs, values) so testers don't have to explore blind

8 — What degrades the experience

Avoid these patterns — they leave testers with empty or misleading harness UI.

  • No tags — all endpoints collapse into one unsorted list with no groups
  • No summary — card titles show the raw HTTP method + path only
  • No response types — no schema badges, no inline schema preview
  • No property descriptions — schema table has blank description column
  • Returning IResult without TypedResults — response type information is lost; use Results<Ok<T>, NotFound> instead
  • Anonymous objects as response types — schema is inferred as empty object

Before and after — Minimal API endpoint

The difference between a bare endpoint and a fully-annotated one.

✗ Bare — minimal harness value
// No tags, no name, no summary,
// no description, no response type
app.MapGet("/products/{id}",
    (int id, ProductCache cache) =>
        cache.GetById(id) ??
        (IResult)Results.NotFound()
);
✓ Annotated — full harness value
app.MapGet("/products/{id}", GetById)
   .WithName("GetProductById")
   .WithSummary("Get a product by ID")
   .WithDescription("Returns a single product. "
       + "Seeded IDs are **1–10**. "
       + "Returns 404 if not found.")
   .Produces<Product>(200)
   .Produces(404);

// Handler uses TypedResults so the
// return type is inferred automatically
static Results<Ok<Product>, NotFound>
GetById(int id, ProductCache cache) =>
    cache.GetById(id) is { } p
        ? TypedResults.Ok(p)
        : TypedResults.NotFound();

Controller-based APIs

The same principles apply — just use attributes instead of fluent calls.

/// <summary>Get a product by ID.</summary>
/// <remarks>Seeded IDs are **1–10**. Returns 404 if not found.</remarks>
[HttpGet("{id}")]
[Tags("Products: Catalog")]
[ProducesResponseType(typeof(Product), 200)]
[ProducesResponseType(404)]
public ActionResult<Product> GetById(int id) { ... }

This site is the live reference

Every best practice above is implemented in this demo. The Products, Customers, and Orders source code is available in the SampleApi folder on GitHub. Open the harness and compare what you see against the source to understand exactly what each annotation produces.

⚡ Open the harness

Remote API Profiles

Browse and test named remote REST APIs from their OpenAPI documents without leaving the harness. Server-configured profile specs use a credential-safe proxy; browser-created profiles are stored locally and fetch specs directly.

Path 1 — Spec Fetch (server-side)

For server profiles, the browser calls GET /api-test-spark/remote-spec?profileId=... → .NET resolves the server profile → adds credentials → fetches remote OpenAPI JSON. Credential values are redacted from config.

Path 2 — Endpoint Calls (browser-direct)

When you click Send, the request goes from your browser to the selected profile's remote server. Default headers, browser-local credentials, and token placeholders such as {request-guid} are injected by the SPA.

Configuration Management

Server profiles appear first and can be hidden locally. Browser profiles are added, edited, and deleted from the Config page, with all browser-managed values persisted in localStorage.

This demo's remote profiles

This site seeds two remote profiles from Program.cs: JSONPlaceholder and the hosted API Test Spark demo. Open either profile's explorer or docs from the harness home screen.

app.MapApiTestSpark(options =>
{
    options.OpenApiUrl    = "/openapi/v1.json";
    options.RemoteApiProfiles.Add(new RemoteApiProfile
    {
        Id = "jsonplaceholder-demo",
        Name = "JSONPlaceholder",
        Description = "Public demo API for posts, users, and comments.",
        RemoteBaseUrl = "https://jsonplaceholder.typicode.com",
        RemoteOpenApiUrl = "https://apitest.makeboldspark.com/openapi/v1.json",
        RemoteDefaultHeaders =
        {
            ["correlationId"] = "{request-guid}",
            ["sessionId"] = "{session-guid}",
        },
    });
});
🌐 Open JSONPlaceholder Explorer 📄 Open JSONPlaceholder Docs

Release History

API Test Spark ships frequently. Every release is a backwards-compatible drop-in upgrade.

v1.5.0 June 12, 2026 Latest

Make Bold Solutions brand alignment. API Test Spark now presents as a Make Bold Spark product across the embedded UI, favicon set, package icon, NuGet metadata, package README, and public documentation. No public API changes.

v1.4.0 June 9, 2026

Remote API Profiles. Configure multiple named remote APIs in Program.cs or from the browser Config page. Each profile has its own explorer and doc builder route, safe name/description display, scoped headers and credentials, redacted server secrets, server-profile-only proxying, local browser-created profiles, and duplicate-name validation before save.

v1.3.0 June 6, 2026

Remote API Explorer. Browse and test remote REST APIs from named RemoteApiProfiles. Server-side spec proxy resolves server profile ids and redacts credential values from config; browser-created profiles stay local and fetch specs directly. Header token expansion ({session-guid}, {request-guid}). Harness version and build date on About page.

v1.2.0 June 2, 2026

Response panel DX improvements. Editable depth-1 nested object sub-forms (collapsed by default, values merge into "Copy as JSON"). "Copy as cURL" in the response panel. Pretty/minified JSON toggle with session-persistent preference. JSONPath tooltips on every field label (click to copy). 2-row table truncation with show-all/show-less. buildCurl extracted to shared src/utils/curlBuilder.ts.

v1.1.0 May 31, 2026

Demo integration toggle. New EnableDemoIntegrations option — set to false to hide the built-in JokeAPI and JSONPlaceholder demo screens. TypeScript type system hardened: ErrorCategory union expanded with 'React'; ErrorBoundary observability corrected. Constitution amended to v1.1.1.

v1.0.2 May 30, 2026

CSP fix. Fixed Content-Security-Policy blocking localhost WebSocket and HTTP connections in Development, restoring Browser Link and hot-reload. No public API changes.

v1.0.1 May 30, 2026

API Doc Builder + rich metadata. New /api-docs screen captures live endpoint responses and exports complete markdown documentation. Full OpenAPI metadata surface: response codes with inline schemas, operationId chip, schema constraints, markdown rendering, API info header. Relational seed data in SampleApi.

v1.0.0 May 30, 2026

Initial release. MapApiTestSpark() extension, OpenAPI v3 autodiscovery, collapsible accordion endpoint groups, smart response rendering (tables/forms/pre), cURL generation, debug panel, environment gating, Azure Application Insights integration, 30 MSTest integration tests.

View full CHANGELOG →

Frequently asked questions

Does it work on .NET 8 or 9?

The package targets net10.0. For earlier targets, reference the package source directly and adjust the target framework in the .csproj. OpenAPI support is built-in from .NET 9 onwards; for .NET 8 use Swashbuckle and point OpenApiUrl at your Swagger JSON URL.

Is it safe to leave enabled in production?

The config endpoint is publicly accessible and returns metadata (auth scheme, header names) — never token values. For production we recommend using Environments = ["Development", "Staging"] or adding network-level access controls (e.g. IP allowlist on your reverse proxy) to restrict access.

Will it conflict with other middleware?

The harness is scoped to /api-test-spark/. It does not affect any other routes or middleware. If you have a WAF or CDN, note that all extensionless paths under /api-test-spark/ return HTTP 200 — the React router handles 404s client-side.

How do I add the harness only in Development without an environment check in code?

Set options.Environments = ["Development"]. The library checks IHostEnvironment.EnvironmentName at startup and skips registration if the current environment is not in the list.

Does it support OpenAPI v2 / Swagger 2.0?

Only OpenAPI v3.x documents are parsed. For Swagger 2.0 APIs, use a converter to produce a v3 document (e.g. converter.swagger.io) and point OpenApiUrl at the converted output.

Can I generate API documentation from test runs?

Yes — the API Doc Builder at /api-docs lets you select endpoints, capture live requests and responses, annotate sections, and export a complete markdown document targeted at front-end developer agents. It includes exact curl commands, full JSON responses, parameter tables, and schema tables.

Can I hide the JokeAPI and JSONPlaceholder demo screens?

Yes — set options.EnableDemoIntegrations = false when calling MapApiTestSpark(). The home page will show only the Host API Explorer and API Doc Builder, and the demo routes (/joke-api, /json-placeholder) are disabled entirely. This is the recommended setting for teams using API Test Spark to test their own APIs rather than as a general-purpose demo tool.

What does this site use for EnableDemoIntegrations?

This demo site sets EnableDemoIntegrations = true so you can explore all features including the built-in JokeAPI and JSONPlaceholder integrations. In a real installation you would typically set this to false to present a focused harness for your own API.

How does the Remote API Explorer keep credentials safe?

For server-configured profiles, the SPA calls GET /api-test-spark/remote-spec?profileId=... — a .NET endpoint in the same process as your app. That endpoint resolves only server-provided profile ids, reads that profile's API key or Bearer token from ApiTestSparkOptions (server-side memory, never the browser), and injects them into the outbound spec request. Browser-created profiles do not use the proxy; they fetch OpenAPI documents directly from the browser.

What are {session-guid} and {request-guid}?

These are token placeholders you can embed in any header value in RemoteDefaultHeaders. {session-guid} is replaced with one UUID that stays constant for the entire page session — useful for tracking a user's full session in a distributed trace. {request-guid} is replaced with a fresh UUID on every individual API call — useful as a per-request correlation ID. Expansion happens at request-send time, not at configuration time.

Can I use the Remote API Explorer to test an API that requires CORS?

Yes, if the remote server allows browser calls. Server-configured profiles add their RemoteBaseUrl to the page's Content-Security-Policy connect-src directive, and browser-created profiles are allowed by the harness CSP as well. The remote server still needs permissive CORS headers for browser-direct endpoint calls and browser-created OpenAPI spec fetches.

Why don't browser-created profiles use the server proxy?

The proxy accepts server-provided profile ids only. Browser-created profile credentials are persisted in localStorage and applied to browser-direct spec fetches and endpoint calls, but they are never submitted to /api-test-spark/remote-spec. This keeps the proxy from becoming an arbitrary server-side URL fetcher and keeps browser-local secrets out of the proxy request.