OpenAI-Compatible API CORS Errors: Diagnose and Fix Them

If curl works but browser fetch fails, inspect the browser preflight. The endpoint must allow the page origin, method, and request headers.

Published
Updated
Reading time
7 minutes
BrowserOPTIONS preflight
EndpointAllow origin and headers
BrowserPOST request

The Short Answer

CORS is a browser permission check. It does not show that the endpoint is offline. Compare a command-line request with the browser preflight.

  1. 1

    Confirm that the same operation works outside the browser.

  2. 2

    Inspect the browser OPTIONS request and response.

  3. 3

    Allow the exact origin, method, and required request headers.

  4. 4

    Do not put long-lived provider credentials in public browser code.

Compare direct and proxy routes

Inspect the Preflight Response

An authenticated JSON request normally triggers a preflight. Test the same origin and request headers that the browser will use.

Preflight reproduction
curl -i -X OPTIONS https://api.example.com/v1/chat/completions \
  -H "Origin: https://app.example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: authorization,content-type"
Example response headers
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Vary: Origin

Read the browser rules in the MDN CORS guide.

Map the Browser Error to the Missing Permission

SymptomLikely problemCheck next
No allow-origin headerOrigin is not allowedExact scheme, host, and port
Method is not allowedPOST or OPTIONS missingAllowed methods
Header is not allowedAuthorization or content type missingAllowed headers
Preflight returns 404OPTIONS route missingGateway and server routing
curl works; browser failsBrowser policyPreflight response
Both requests failEndpoint or configurationDNS, TLS, route, and auth

Choose a Safe Execution Route

Use browser-direct requests for localhost or private endpoints. Configure their CORS policy for the testing page origin.

Use a controlled server proxy for public endpoints when browser access is not required. The proxy must protect credentials and block internal network targets.

no-cors does not grant response access

The browser can send an opaque request, but JavaScript cannot read the status, headers, or response body.

Verify CORS and Endpoint Health Separately

LLMCompat can compare a browser-direct attempt with a protected server route. Local and private endpoints always stay browser-direct.