This page covers two things.
| You want to | Read |
|---|---|
Show a site hosted on Siteon on your own domain (www.example.com) | Custom domains |
Fix forms that fail with 403 / origin_not_allowed, or register the domain of the site your form lives on | Allowed origins for forms |
When a custom domain becomes active on Siteon hosting, it is added to the allowed origins automatically. If you only put a form on a site hosted elsewhere (Cloudflare Pages, Vercel and so on), you only need the allowed origins.
Custom domains Soon
Custom domain requests are not open yet Soon. This section describes the steps for when they open. Until then you can publish at
https://<name>.siteun.com/.
On your own domain, www.example.com is the main host (primary) and example.com (without www) redirects to www.
Before you start
- The site must be on a paid plan. Lite allows 1, Standard 3 and Business 10.
www.example.comandexample.comtogether count as one. Not available on Free (plan_required) - Hosting must be enabled for the site (
siteon hosting enable; see Hosting and delivery) - In the admin, the site's owner can do this. With an API key (CLI, MCP) you need the
domains:writescope. It is not granted by default, so choose it explicitly when you create the key (siteon login --scopes +domains:write) - You must be able to edit the domain's DNS. The company you bought the domain from (the registrar) is not always where the DNS is edited: edit it where the nameservers point
- An account can request up to 5 domains a day (days counted in Japan time)
Steps
- In the admin, open "Publishing" in the sidebar, type
www.example.comin the "Custom domains" box and press "Add" (CLI:siteon domains add www.example.com --site <site-id>) - Add the two records shown on screen (
TXTandCNAME) to your domain's DNS (Records to add) - Wait. Siteon checks the DNS and the certificate automatically every 5 minutes; once both are in place the status becomes "Active" and the site is served on your domain. Reopening "Publishing" in the admin checks again on the spot (CLI:
siteon domains status) - Redirect
example.com(without www) towww.example.com(The bare domain)
If the records cannot be verified within 72 hours of the request, the request is cancelled (the status becomes "Failed"). Add the domain again in that case.
Records to add
For a request for www.example.com you add these two records. The value changes with every request, so always copy exactly what the screen (or the CLI / API response) shows.
| Type | Name (host) | Value |
|---|---|---|
TXT | _sitekit-verify.www.example.com | The value shown on screen, starting with sitekit-verify= |
CNAME | www.example.com | cname.siteun.com |
- The TXT record proves ownership. It is required for every request and its value changes with each one. Do not delete it after the domain is active: Siteon keeps checking every 5 minutes, and if the TXT record disappears the domain stops being served at once (and drops out of the allowed origins)
- The CNAME record points traffic at Siteon. Any record that
www.example.comhas now (A,AAAA, anotherCNAME) cannot coexist with the CNAME. Remove it, then add the CNAME. The old site disappears as soon as you switch the CNAME, andhttps://may not open for a few minutes until the certificate is issued. Add the TXT record first and switch the CNAME at a quiet time to keep the gap short - Most DNS screens append the domain (
.example.com) to the name field automatically. Then enter onlywwwand_sitekit-verify.www. Enteringwww.example.comthere would createwww.example.com.example.com - Leave mail (
MX) and any other records that are notwwwalone - For internationalized domain names, request and enter the
xn--form (Punycode)
After adding them, you can check that the DNS serves them:
dig +short CNAME www.example.com # OK if it prints cname.siteun.com.
dig +short TXT _sitekit-verify.www.example.com # OK if it prints the value on screenExamples by DNS provider
Screen and menu names change from time to time. Whatever the provider, you add two rows in its DNS records screen: "type CNAME, host www, value cname.siteun.com" and "type TXT, host _sitekit-verify.www, value as shown on screen".
- Cloudflare — In the domain's "DNS" → "Records", use "Add record". CNAME: Name
www, Targetcname.siteun.com, and set Proxy status to "DNS only" (grey cloud). TXT: Name_sitekit-verify.www, Content the value on screen - Onamae.com — In Onamae.com Navi's DNS features ("DNS settings", "DNS record settings"), add host
www, TYPECNAME, VALUEcname.siteun.com, and host_sitekit-verify.www, TYPETXT, VALUE the value on screen. This screen works when the domain uses Onamae.com's nameservers - Muumuu Domain — In "Muumuu DNS" custom settings, add subdomain
www, typeCNAME, contentcname.siteun.com, and subdomain_sitekit-verify.www, typeTXT, content the value on screen - Xserver Domain — In the domain's "DNS record settings", add host
www, typeCNAME, contentcname.siteun.com, and host_sitekit-verify.www, typeTXT, content the value on screen. If the nameservers point at a rental server (such as Xserver), use that server's DNS record settings instead - Sakura Domain — In the member menu's "zone edit" for the domain, add entry
www, typeCNAME, valuecname.siteun.com.(some screens need the trailing dot), and entry_sitekit-verify.www, typeTXT, value the value on screen - Squarespace (formerly Google Domains) — In the domain's "DNS" settings, under custom records, add Host
www, TypeCNAME, Datacname.siteun.com, and Host_sitekit-verify.www, TypeTXT, Data the value on screen
With Cloudflare's proxy turned on (orange cloud), requests to www.example.com pass through your own Cloudflare settings before reaching Siteon, which can stall certificate issuance and the checks. Siteon already serves your domain and its certificate through Cloudflare, so there is no need to turn the proxy on.
The bare domain (example.com)
Ordinary DNS does not allow a CNAME on example.com itself (the apex). Redirect it to www.example.com in one of these two ways.
A. Your DNS can do CNAME flattening (ALIAS, ANAME)
- Add
www.example.comfirst (if you add onlyexample.comwith no primary host, there is nothing to redirect to and it answers404) - Add
example.comas well. Together withwww.example.comit counts as one, so it uses no extra slot. It becomes "Redirects to primary" automatically - Add the
TXTrecord shown (_sitekit-verify.example.com) and aCNAMEon the apex (name@or blank) →cname.siteun.com. Remove anyA/AAAArecords on the apex (MXandTXTcan stay) - Once active,
https://example.com/…redirects tohttps://www.example.com/…(path and query preserved)
Cloudflare flattens apex CNAMEs as standard, so this method works there. For other providers, check their documentation for whether they offer ALIAS / ANAME.
B. Your registrar's URL forwarding
Use your DNS provider's "URL forwarding" (web forwarding, redirect settings and so on) to forward example.com to https://www.example.com. Do not add example.com to Siteon (it uses no slot). Forwarding is the provider's own service, so whether https://example.com opens without a certificate error and whether the path is carried over depends on that provider.
You can also make example.com the main host instead of www (mark it primary when you add it; --primary in the CLI). We recommend www as the main host because it has fewer DNS restrictions.
What the statuses mean
| Status (API value) | Meaning | What to do / how long |
|---|---|---|
Received (requested) | The request was received and serving is being prepared | Just wait. Usually seconds to a few minutes until "Waiting for DNS" |
Waiting for DNS (pending_dns) | The CNAME or TXT record cannot be verified yet | Add both records. DNS changes take from minutes to a few hours to show up (depends on the provider and the TTL); the next 5-minute check then moves it on |
Waiting for the certificate (pending_ssl) | DNS is verified and the https:// certificate is being issued | Just wait. Usually minutes to tens of minutes |
Active (active) | The site is served on this domain, and the domain is in the allowed origins automatically | Keep the TXT and CNAME records. Each passing 5-minute check extends it by 72 hours |
Failed (failed) | Not verified within 72 hours of the request, so the request was cancelled | Add it again (the TXT value is new, so replace the old TXT record with the new value) |
- If the TXT or CNAME record disappears after "Active", the status goes back to "Waiting for DNS" at once and the domain stops being served (it also leaves the allowed origins). Put the record back and the next check makes it "Active" again, with no new request
- If the check cannot run because of a temporary problem on Siteon's or Cloudflare's side, serving does not stop (for up to 72 hours since the last successful check)
- Times are rough guides. With slow DNS providers it can take around half a day
Removing a domain and changing the main host
- Remove — "Remove" under "Publishing" → "Custom domains" in the admin (CLI:
siteon domains remove www.example.com --yes). The domain stops being served at once and this cannot be undone. To use it again, add it and verify the DNS again (with a new TXT value). The slot frees up once Siteon has finished cleaning up (usually a few minutes). Delete DNS records you no longer need yourself. If you remove the main host, a domain set to redirect (example.com) has nowhere to go and answers404 - Change the main host —
siteon domains primary <domain> --yes(MCP:domains_primary). Choose an active domain. The other domains redirect to the new main host at once, and the pages' canonical URL changes - While a custom domain is the active main host, the shared subdomain (
<name>.siteun.com) keeps serving, but it is set to stay out of search (noindex) and names the custom domain as the canonical URL
Errors
The admin shows a plain-language message; the CLI, API and MCP put a code in error.
| Code | Meaning | Fix |
|---|---|---|
plan_required (402) | The site's plan has no custom domains (Free) | Move the site to a paid plan (Lite or higher) |
quota_hostnames (402) | The plan's slots are used up (limit and used are returned) | Remove a domain you do not use, or upgrade. A just-removed domain still counts for a few minutes until clean-up finishes |
invalid_hostname (400) | The domain is malformed (reason is bad_format), or it is a siteun.com name (base_domain) | Enter it as www.example.com, without https://, a trailing / or a path. Allowed characters are lowercase letters, digits and hyphens (internationalized names in their xn-- form) |
hostname_blocked (400) | Names that combine a brand name with words like login or verify (shapes common in impersonation) cannot be registered | Use a different domain |
hostname_reserved (409) | Another account has requested or is using the domain (reserved_until shows the deadline of a pending request) | If the domain is yours, request it after the deadline (72 hours from that request). If no deadline is shown (it is active elsewhere), contact Siteon |
hostname_in_use (409) | It is registered on another site in the same account (site_id) | Remove it from that site first |
too_many_domain_requests (429) | An account can request up to 5 domains a day | Try again the next day (after the date changes in Japan time) |
hosting_disabled (409) | Hosting is not enabled for the site | Run siteon hosting enable first |
billing_inactive (402) | Payment could not be confirmed | Check billing in the admin |
account_held / transferring (409) | Publishing is held for the account / the site is being transferred | Check the hold notice email / try again after the transfer |
hostname_not_live (409) | The domain you tried to make primary has failed or was removed | Start again by adding it |
site_changed (409) | Another operation got there first | Read the state again and retry |
insufficient_scope (403) | The API key lacks domains:write | Create a key with domains:write (siteon login --scopes +domains:write) |
confirmation_required (400) | Removing a domain or changing the main host with an API key needs confirmation | Ask the person first, then pass confirm: true (--yes in the CLI) |
Allowed origins for forms
The allowed origins (allowed_origins in the API) are the domains of the pages that may carry this site's forms. Submissions sent from pages on any other domain are refused. This stops other people from putting your form on their own site and using up your submission quota. Page-view counting uses the same list.
- In the admin: the site's "Settings" → "Domains and site name", under "Domains that may submit forms". One per line, then "Save". The site's owner can change it. It takes effect as soon as you save
- In the admin you can leave out
https://(localhostis taken ashttp://). If you type a path, only the domain part is registered - Up to 20 entries
- Only exact matches are accepted.
https://www.example.comandhttps://example.comare different, so add both if you use both.http://versushttps://and different port numbers are different too. Wildcards like*cannot be used (preview URLs that change every time, such as Cloudflare Pages'<hash>.<project>.pages.dev, must be added one by one, or use a fixed preview URL) - Submissions without an
Originheader (curl, servers) are accepted regardless of the allowed origins
Origins added automatically
These two are accepted without being in the list (they do not appear in the admin's box):
- The site's shared subdomain on Siteon hosting (
https://<name>.siteun.com) - Custom domains that are "Active" (
https://www.example.com, and a redirectinghttps://example.comtoo). They drop out automatically when they stop being active.auto_originsinsiteon domains statusshows what is in right now
What Free sites can register
A Free site can only register development and preview domains. Anything else (your own domain) is refused with 402 upgrade_required; move the site to a paid plan first.
localhost
127.0.0.1
*.pages.dev
*.vercel.app
*.netlify.app
*.github.io
*.workers.dev*.pages.dev here means "names of this shape can be registered". What is accepted is still only the individual domains you put in the list.
Changing them with the API
With an API key (scope sites:write) you replace the site's allowed origins. The list you send becomes the new list, so send the current list (readable with GET, scope sites:read) plus your additions.
curl -X PATCH "https://cdn.siteon.dev/v1/accounts/<account-id>/sites/<site-id>" \
-H "Authorization: Bearer stk_..." \
-H "Content-Type: application/json" \
-d '{"allowed_origins":["https://www.example.com","https://example.com","https://my-shop.pages.dev"]}'- Write each one as
https://www.example.com. A trailing/, a path or uppercase letters are refused (400), as are more than 20 entries - With a personal key (one made by
siteon login), you must be an owner or admin of the account - Sending a non-development domain for a Free site gives
402 upgrade_required
Fixing 403 origin_not_allowed
If you see either of the following, the domain of the page with the form is not in the allowed origins. The submission is not saved and does not count toward your quota.
- The form says it could not be sent, and the browser's developer tools console shows a CORS error (no
Access-Control-Allow-Originheader, for example). For submissions from the Siteon script, the browser stops at its pre-flight check, so the submission is never sent - With your own sending code (
fetch, a plain<form>post and so on), the response is403with{"ok":false,"error":"origin_not_allowed"}
- Open the page with the form and run
location.originin the developer tools console to get the page's exact domain (for examplehttps://www.example.com) - Compare it with "Settings" → "Domains and site name" → "Domains that may submit forms" in the admin. Check
wwwor not,httpversushttps, and the port - If it is missing, add it and save. It takes effect at once, so reload the page and submit again
- If you cannot add it
- "Production domains are available on a paid plan" (
402 upgrade_required) — the site is on Free. Move it to a paid plan, then add the domain - "Up to 20 domains" — remove the ones you do not use
- "Production domains are available on a paid plan" (
- For a custom domain on Siteon hosting, you do not need to add it: it is added automatically once "Active". If it is still "Waiting for DNS" or similar, see What the statuses mean and fix the domain instead
When an AI agent uses this page
Steps for when a person asks "set up my custom domain" or "my form returns 403". The MCP tools are in preparation Soon (until then, walk the person through the admin).
When asked to set up a custom domain
- Confirm with the person: the domain (as
www.example.com), that they own it, which company hosts its DNS (Cloudflare, Squarespace and so on), and that the site is on a paid plan with hosting enabled. Never request a domain the person does not own - Call
domains_add(site,hostname: "www.example.com"). If the key lacksdomains:writeyou getinsufficient_scope; ask the person to create a new key withsiteon login --scopes +domains:write - Show the person
dns.txt(name,value) anddns.cname(name,target) from the response exactly as returned. Add the form the name field takes at their provider (_sitekit-verify.wwwandwww; see Records to add and Examples by DNS provider). On Cloudflare, tell them to use "DNS only". Tell them to add the records beforeexpires_at(72 hours later) - If the response contains
next_steps, follownext_stepsover this page - When the person says the records are in, call
domains_status(it checks on the spot). Leave 1 to 5 minutes between repeated calls - Next step by status (What the statuses mean)
requested— wait a little and calldomains_statusagainpending_dns— look atlast_check_detail.txtofmismatch/nxdomainmeans the TXT name or value was copied wrong;cfofokwith acf_statusother thanactivemeans the CNAME does not point at us. Ask the person for thedigoutput. If the records are fresh, wait for DNS to updatepending_ssl— wait (minutes to tens of minutes)active— done. Ask the person to openhttps://www.example.com/to check, and to keep the TXT and CNAME recordsfailed— 72 hours passed. After confirming with the person, calldomains_addagain and have them replace the TXT record with the new value
- Ask about the bare domain (The bare domain). If their DNS can do CNAME flattening (Cloudflare and others), confirm
wwwis already added, then calldomains_addwithhostname: "example.com". Otherwise, guide them to forward it tohttps://www.example.comwith the registrar's URL forwarding - Look up error codes in Errors. Call
domains_removeanddomains_primaryonly after telling the person what will happen and getting an explicit yes, withconfirm: true
When told a form returns 403
- Check that the symptom is
403/origin_not_allowedor a CORS error in the console (Fixing it).429or400has a different cause (Common errors) - Ask the person for the exact domain (
location.origin) of the page with the form - Read the site's
allowed_originswithlist_sitesand look for an exact match (wwwor not,http/https, port) - If it is missing, ask the person to add it under "Settings" → "Domains and site name" in the admin. To add it through the API, confirm with the person first and
PATCHthe current list plus the new entry (Changing them with the API). A Free site cannot take your own domain (upgrade_required), so explain that a paid plan is needed - For a custom domain on Siteon hosting, do not add it to the allowed origins; check its state with
domains_statusinstead (it is added automatically once active)