Security

Allowed origins

Restrict which websites can submit to your form using CORS origin checking.

By default, your form accepts submissions from any website. This is intentional for getting started quickly — it matches how Web3Forms and similar services work.

If you want to lock down your form so only your own website can submit to it, use the allowed origins setting.

How it works

When a browser submits a form, it includes an Origin header indicating which website the request came from (e.g., https://example.com). If you configure allowed origins on your form, the service checks this header and rejects requests from unlisted domains with a 403 error.

Configuring allowed origins

In the dashboard → Forms → your form → SettingsAllowed origins:

Add one domain per line. Include just the domain — no protocol prefix, no trailing slash:

example.com
www.example.com
app.example.com

TIP

Add both example.com and www.example.com if your site uses both — they are treated as different origins.

What counts as an origin

An origin is the scheme + hostname + port combination from the browser's Origin header. The matching is domain-only — the service compares the hostname portion after normalising both values (strip https://, strip www., strip trailing slashes).

So allowed_origins: ["example.com"] would match:

  • https://example.com
  • https://www.example.com

It would not match:

  • https://subdomain.example.com
  • https://other.com

Empty allowed origins = allow any origin

If you leave the allowed origins list empty (the default), submissions from any origin are accepted. This is correct for:

  • Public forms shared via URL (the hosted page is api.vlozi.app, a different origin)
  • The @vlozi/forms SDK used server-side (no browser Origin header)
  • Serverless/edge environments that call the API directly

CORS and the browser

The gateway serves the submit endpoint with any-origin CORS headers (Access-Control-Allow-Origin: *). This means the browser will not block the request before it reaches the server. The server-side allowed origins check is a separate, additional gate — the two are independent:

  1. Browser CORS: always permitted (gateway sends permissive headers)
  2. Server allowed origins check: enforced at the worker level

In practice: a cross-origin request from an unlisted domain will get a 200 OK preflight (CORS passes), but the actual POST will get a 403 from the worker if allowed origins is configured.

Testing

Use curl to simulate a specific origin:

curl -X POST \
  -H "Origin: https://evil.com" \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com"}' \
  "https://api.vlozi.app/forms/f/YOUR_FORM_ID"
# → 403 { "success": false, "message": "Origin not allowed" }
curl -X POST \
  -H "Origin: https://example.com" \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com"}' \
  "https://api.vlozi.app/forms/f/YOUR_FORM_ID"
# → 200 { "success": true, ... }
Forms · SecurityEdit on GitHub