On this page
Domains
List your site’s hostnames, attach a custom domain, and choose its primary address. Custom domains require Pro.
For DNS setup and address-allocation details, see Domains.
All endpoints require an organization API key. :site accepts a slug or an id.
Kinds of domain
kind |
What it is | Who gets one |
|---|---|---|
saas |
The <name>.docsary.com address allocated when the site was created. Verified and serving from the moment it exists. |
Every plan, automatically |
custom |
A hostname you own. Needs a TXT ownership challenge and a CNAME. |
Pro, up to the custom-domain ceiling |
route |
A hostname set up on your behalf. Attaches already verified. | Provisioned accounts only |
List domains
GET /v1/sites/:site/domains
curl -s -H "authorization: Bearer $DOCSARY_KEY" \
"$DOCSARY_API/v1/sites/acme/domains"
{
"domains": [
{
"hostname": "acme.docsary.com",
"is_primary": 0,
"kind": "saas",
"verified": true,
"verified_at": 1756300000000
},
{
"hostname": "docs.acme.com",
"is_primary": 1,
"kind": "custom",
"verified": true,
"verified_at": 1756300000000,
"registered": true,
"traffic": {
"type": "CNAME",
"name": "docs.acme.com",
"value": "ssl.docsary.com",
"how": "Point docs.acme.com at ssl.docsary.com with a CNAME once ownership is verified. The certificate is issued and renewed for you; there is nothing to install."
}
},
{
"hostname": "staging.acme.com",
"is_primary": 0,
"kind": "custom",
"verified": false,
"verified_at": null,
"registered": false,
"verification": {
"type": "TXT",
"name": "_docsary.staging.acme.com",
"value": "docsary-verify=8f1c...",
"how": "Publish this TXT record, then POST to /v1/sites/<site>/domains/staging.acme.com/verify. The hostname is not served until it verifies."
},
"traffic": {
"type": "CNAME",
"name": "staging.acme.com",
"value": "ssl.docsary.com",
"how": "..."
}
}
]
}
| Field | Meaning |
|---|---|
kind |
saas, custom, or route — see the table above |
is_primary |
1 on the site's canonical host, 0 otherwise |
verified |
Whether ownership is verified. HTTPS also requires working DNS and a certificate. Always true for saas |
verified_at |
Millisecond timestamp of verification, or null |
verification |
Present only while a custom hostname is unverified: the record to publish |
traffic |
Present on every custom hostname, verified or not: the CNAME to publish |
registered |
custom only. true once a certificate has been requested for the hostname |
This call is how you recover both records if you lost the attach response.
Attach a domain
POST /v1/sites/:site/domains
curl -s -X POST "$DOCSARY_API/v1/sites/acme/domains" \
-H "authorization: Bearer $DOCSARY_KEY" \
-H "content-type: application/json" \
-d '{"hostname":"docs.acme.com"}'
| Field | Type | Required | Notes |
|---|---|---|---|
hostname |
string | yes | Lowercased and trimmed. Must be a dotted hostname with a suffix of two or more letters. May not end in docsary.com. |
primary |
boolean | no | Marks this the site's canonical host and clears the flag from its other domains. |
{
"hostname": "docs.acme.com",
"kind": "custom",
"verified": false,
"verification": {
"type": "TXT",
"name": "_docsary.docs.acme.com",
"value": "docsary-verify=8f1c2d0a4b6e8f1c2d0a4b6e8f1c2d0a",
"how": "Publish this TXT record, then POST to /v1/sites/<site>/domains/docs.acme.com/verify. The hostname is not served until it verifies."
},
"traffic": {
"type": "CNAME",
"name": "docs.acme.com",
"value": "ssl.docsary.com",
"how": "Point docs.acme.com at ssl.docsary.com with a CNAME once ownership is verified. The certificate is issued and renewed for you; there is nothing to install."
}
}
201 on success. The attachment exists and is unverified; nothing is served on it, and no certificate is requested, until it verifies.
Reattaching a hostname creates a new verification token. Use the TXT record from the latest response.
Errors
| Response | Cause |
|---|---|
400 {"error":"invalid hostname"} |
Missing, malformed, or dotless hostname |
400 containing is not attachable |
The hostname ends in docsary.com. Those are allocated at site creation, not attached |
403 with "quota":"custom_domains" |
Your plan does not include custom domains (limit: 0), or your ceiling is already reached |
409 {"error":"hostname already attached","to_this_site":false} |
The hostname is attached to another site |
409 {"error":"hostname already attached","to_this_site":true} |
The hostname is already attached to this site |
404 {"error":"site not found"} |
The site slug or id does not resolve |
A plan without custom domains returns limit: 0 and required_plan: "pro":
{
"error": "Custom domains are part of Docsary Pro; the 'free' plan does not include them. Your site keeps serving on its docsary.com address. To put it on a hostname you own, upgrade to Pro — email hello@robota.us.",
"quota": "custom_domains",
"limit": 0,
"plan": "free",
"required_plan": "pro"
}
Pro quota responses identify the allowed count:
{
"error": "quota exceeded: custom_domains limit is 25 on plan 'pro'",
"quota": "custom_domains",
"limit": 25,
"plan": "pro"
}
The limit applies across your organization. Allocated docsary.com addresses do not count. Contact us for a higher allowance.
Hostnames are unique across every site. to_this_site distinguishes a re-run from a genuine conflict.
A hostname provisioned on your behalf may return kind: "route" and verified: true. Contact support if its setup report includes a failed step.
Verify a domain
POST /v1/sites/:site/domains/:hostname/verify
Publish the TXT record from the attach response, then call this. It resolves the record live on every call.
curl -s -X POST "$DOCSARY_API/v1/sites/acme/domains/docs.acme.com/verify" \
-H "authorization: Bearer $DOCSARY_KEY"
{
"hostname": "docs.acme.com",
"verified": true,
"traffic": {
"type": "CNAME",
"name": "docs.acme.com",
"value": "ssl.docsary.com",
"how": "..."
},
"certificate": { "status": "created" }
}
After ownership verification, publish the traffic record and wait for certificate issuance before checking the hostname over HTTPS.
| Response | Meaning |
|---|---|
200 {"verified":true} |
Ownership verified. HTTPS requires the CNAME and certificate to be ready. |
200 {"verified":true,"already_verified":true} |
It was already verified. If no certificate had been requested yet, this call retries that. |
409 with expected and found |
The record was not found. found lists what did resolve at that name. |
409 {"error":"domain has no verification token; re-attach it"} |
The attachment predates its challenge — detach and attach again. |
502 {"error":"DNS lookup failed: ..."} |
The lookup itself failed. Retry. |
404 {"error":"domain not found"} |
That hostname is not attached to this site. |
For 409, compare expected with found, correct the TXT record if needed, allow time for DNS propagation, and retry.
The certificate block
status |
Meaning |
|---|---|
created |
A certificate was requested for the hostname. It issues once the CNAME resolves to us. |
exists |
One had already been requested. Nothing to do. |
skipped |
That step could not run right now, with a reason. Call verify again later. |
failed |
The request was refused, with an error. Call verify again; if it persists, send us the text. |
A skipped or failed certificate request leaves ownership verified. Retry verification to request the certificate again; contact support if it continues to fail.
Set the primary domain
POST /v1/sites/:site/domains/:hostname/primary
Makes an already-attached hostname the site's canonical host and clears the flag from every other domain on the site, in one call.
curl -s -X POST "$DOCSARY_API/v1/sites/acme/domains/docs.acme.com/primary" \
-H "authorization: Bearer $DOCSARY_KEY"
{
"hostname": "docs.acme.com",
"is_primary": true,
"previous_primary": "acme.docsary.com",
"already_primary": false,
"note": "Canonical URLs, indexing, and the sitemap follow the primary host. ..."
}
Use this endpoint to change the primary host without detaching it or restarting certificate setup.
| Field | Meaning |
|---|---|
previous_primary |
The hostname that held the flag before this call, or null if this one already held it |
already_primary |
true when the hostname was already the site's only primary and nothing changed |
The primary flag moves in one operation. A refused request leaves the current primary unchanged.
Repeated calls are safe; an unchanged primary returns previous_primary: null.
What changes when the primary moves
| Behaviour | New primary host | Every other host |
|---|---|---|
robots.txt |
invites indexing | asks not to be indexed |
Page noindex |
absent | present |
| Canonical URLs | point at this host | rewritten to point at this host |
sitemap.xml |
lists this host's URLs | available with that host's URLs, but not advertised in robots.txt |
Verify the new domain and confirm that it serves your content before making it primary. The change affects search indexing signals; search engines decide when to update their results.
Other hostnames remain public. Their noindex and crawler directives request exclusion from cooperating search engines, without guaranteeing it.
Errors
| Response | Cause |
|---|---|
404 {"error":"domain not found"} |
The hostname is not attached to this site |
404 {"error":"site not found"} |
The site slug or id does not resolve |
409 containing not verified |
The hostname is an unverified custom domain |
403 containing read-only |
The key cannot write |
Verify an unverified custom hostname before promoting it. Otherwise the call returns 409.
Detach a domain
DELETE /v1/sites/:site/domains/:hostname
curl -s -X DELETE "$DOCSARY_API/v1/sites/acme/domains/docs.acme.com" \
-H "authorization: Bearer $DOCSARY_KEY"
{ "deleted": "docs.acme.com", "certificate": { "status": "deleted" } }
The hostname stops serving and its certificate is released. certificate reads deleted, absent (there was none to release), skipped, or failed with a reason.
Your DNS records are never touched — they are yours, and removing them is your call.
404 {"error":"domain not found"} if the hostname is not attached to this site.
Detaching your docsary.com address works the same way and frees that name for somebody else, so do it deliberately. Deleting the site detaches everything it had.
When changes take effect
No deployment or separate publish call is required. Allow for DNS propagation, certificate issuance, and cached responses, then check the hostname over HTTPS.
Unattached or unverified hostnames return 404: docsary: no site bound to this host.