Debugging / CORS & keys
Calling From a Browser
Browser calls fail for two different reasons: the origin is not allowed, and API keys must never be in client code. Both are fixed the same way.
Two problems
Why the request fails
- The origin is not allowed
- Cross-origin browser requests only succeed from origins the API is configured to allow. A blocked request shows up as a CORS error in the browser console, even though the API itself never rejected your credentials.
- The key cannot be there
- Anything in client-side JavaScript is readable by your users. An API key in a browser bundle is a leaked key, so this is a design problem rather than a configuration one.
Both problems disappear with the same change: call MemorySync from your own server and let the browser talk to your endpoint.
Pattern
The pattern that works
Avoid
// browser — do not do this
await fetch("https://api.memorysync.io/memory/query", {
method: "POST",
headers: { "X-API-Key": "ms_live_…" }, // visible to every user
body: JSON.stringify({ query }),
});Even if the origin were allowed, the key is now public. Treat any key that has shipped to a browser as compromised and rotate it.
DevTools
Identify the failure before changing CORS
- No HTTP status is visible
- The browser stopped the response at the cross-origin boundary. Check the console for the rejected origin and move the request behind your server route; do not solve this by exposing an API key in JavaScript.
- A 401 or 403 response is visible
- The request reached MemorySync. Debug the credential, project scope, and end-user scope instead of changing CORS.
- The same call works in cURL
- That isolates the failure to browser origin policy or client-side credential handling. It does not mean the key is safe to ship to the browser.
# Run this from a terminal, with the key in an environment variable.
curl --include --request POST https://api.memorysync.io/memory/query \
--header "X-API-Key: $MEMORYSYNC_API_KEY" \
--header "X-End-User-ID: user_42" \
--header "Content-Type: application/json" \
--data '{"query":"shipping preference"}'Checklist
Production-safe browser integration
- Store the MemorySync credential only in server-side environment variables or a secrets manager.
- Authenticate the browser request to your own backend before it can call the MemorySync client.
- Derive the MemorySync end-user identifier from that verified session, never from an untrusted request field.
- Return only the fields the browser needs, and keep upstream errors free of credentials and internal details.
- Rotate any API key that has appeared in a bundle, source map, browser log, or copied network request.
Was this page helpful?