CORS preflight decision from Fetch spec

$0.005 USDC per call · Developer and security · POST /api/v1/cors-preflight · Id cors-preflight

Takes a browser request shape (origin, method, headers, credentials flag) and a server CORS policy (allow-origin, allow-methods, allow-headers, allow-credentials, expose-headers, max-age) and returns the exact decision a browser would make per the Fetch Living Standard §3.2 and §4.10: whether a preflight OPTIONS is required, whether the main request is allowed, which response headers the script can read, and which rule killed it when it is denied. No network — the policy is an input, not fetched. Catches the three bugs every stack reinvents: Access-Control-Allow-Origin: '*' with credentials, wildcard allow-headers with credentials, and forbidden request headers like Cookie that the spec blocks before the policy is consulted.

What you get

A CORS failure costs an engineering half-day across backend and frontend; this returns the offending rule in one call without browser-side guesswork.

Call it

Send the JSON body below to https://agents.writerslogic.com/api/v1/cors-preflight. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.

curl -i -X POST https://agents.writerslogic.com/api/v1/cors-preflight \
  -H 'content-type: application/json' \
  -d '{"request":{"origin":"https://app.example.com","method":"POST","headers":{"content-type":"application/json","authorization":"Bearer x"},"withCredentials":true},"policy":{"allowOrigin":["https://app.example.com"],"allowMethods":["POST"],"allowHeaders":["authorization","content-type"],"allowCredentials":true,"maxAge":600}}'

Input

FieldTypeRequiredDescription
requestobjectyes
policyobjectyes

Example request body

{
  "request": {
    "origin": "https://app.example.com",
    "method": "POST",
    "headers": {
      "content-type": "application/json",
      "authorization": "Bearer x"
    },
    "withCredentials": true
  },
  "policy": {
    "allowOrigin": [
      "https://app.example.com"
    ],
    "allowMethods": [
      "POST"
    ],
    "allowHeaders": [
      "authorization",
      "content-type"
    ],
    "allowCredentials": true,
    "maxAge": 600
  }
}

Result

The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.

FieldTypeRequiredDescription
statusstring; one of "pass", "fail", "unknown", "unsupported"nopass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass.
allowedbooleannoWhether the main request (after any preflight) would succeed.
preflightRequiredbooleannoWhether the browser would first send OPTIONS.
preflightResponseobjectnoThe headers the server must return on the OPTIONS preflight for this request to be approved.
exposedResponseHeadersarray<string>noResponse headers that would be visible to the script (CORS-safelisted plus Access-Control-Expose-Headers).
witnessesarray<object>no
versionsobjectnoEvery semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile).
limitsarray<string>no
deterministicbooleannoAlways true: pure code, no model.

Pay and connect

Available through: x402 (USDC on Base), MCP. MCP clients reach it through the infra-preflight-kit package.

Machine-readable