Topolo Docs Topolo Platform
Open workspace

Verify and attach a Forms custom domain

Check the applicable DNS proof, reconcile the provider hostname and store its observed activation state under the original owner workspace.

Outcome

Check the applicable DNS proof, reconcile the provider hostname and store its observed activation state under the original owner workspace.

POST /api/domains/{domainId}/verify

Before you start

Use the original authorized organization and a discovered canonical Forms workspace, bound separately. List needs workspace:read; writes need workspace:write. Bearer requests resolve minimum read for list and admin for domain writes. API-key authority comes through original Auth introspection of its binding and the app permission check; do not invent an additional local role check.

Only connect a hostname and DNS zone you are authorized to administer. Organization visibility does not transfer ownership or mutation authority. The projection does not identify its owning workspace. An ownership TXT token is not an Auth credential or platform grant.

These actions return planned DNS instructions; they do not publish DNS records. Preserve unrelated mail/TXT records during any separately approved DNS administration. Syntax validity is not global hostname registry custody, reserved-hostname enforcement, exclusive ownership or correct provider origin. Those surrounding contracts remain with their existing owners.

All examples are complete source-derived synthetic responses, unrun. Names, ids, ownership token and example.test URLs are fictional. The exact published domain-connections0.4.4 artifact matches the checked lock integrity and was inspected without import/execution. No real DNS lookup/write, Cloudflare, form/subject/Auth/provider/model/notification operation or browser navigation occurred.

Request and effects

Action: app_topolo_forms.domains.verify. Validate current input and, for a real mutation, obtain applicable approval and a confirmed executable plan for the exact owner-scoped target and provider/public effects.

Requires discovered domainId and owner-workspace mutation authority. An organization-visible row owned elsewhere returns404 domain_not_found before provider work; visibility is not transfer authority.

Only stored pending_dns causes the selected app to call DNS verification. The exact published verifier queries public DNS-over-HTTPS for routing and ownership TXT, accepting bare token or topolo-verification=<token> with normalized quotes/case/root dot. pending_ssl/active repeats skip DNS proof here; they are not fresh ownership verification.

Then provider ensure/read runs. Ensure attempts Cloudflare custom-hostname POST with SSL settings and can reconcile a matching existing hostname after attach failure. An external effect may precede a lost/error result. It does not publish DNS records. The helper receives originServer, but this published POST body does not send a custom origin override; default-origin correctness remains unqualified.

Both provider hostname and SSL must be active to store active. Any other/null result, including helper failed classification, becomes pending_ssl. Provider work precedes DB status/timestamp update and separate read-back without one transaction. pending_ssl is not a unique diagnosis or permission to retry indefinitely.

Even active is an observation rather than end-to-end public form rendering/submission, ongoing ownership, event delivery or origin correctness. Preserve actual provider/request evidence and reconcile uncertainty before another mutation.

Complete worked responses

Observed active state stored

Complete source-derived synthetic, unrun HTTP200. Assumes original ownership, passing DNS when pending_dns, provider hostname+SSL active and successful DB update/read-back at the shown clock. No resolver/provider request was run.

Input:

{
  "domainId": "domain_00000000-0000-4000-8000-000000000004"
}

Response:

{
  "domain": {
    "id": "domain_00000000-0000-4000-8000-000000000004",
    "hostname": "forms.example.test",
    "status": "active",
    "verificationToken": "00000000-0000-4000-8000-000000000003",
    "dnsTarget": "edge.example.test",
    "formId": "forms_docs_fixture",
    "availableAcrossWorkspaces": false,
    "records": [
      {
        "purpose": "routing",
        "type": "CNAME",
        "host": "forms",
        "name": "forms.example.test",
        "value": "edge.example.test",
        "required": true,
        "instruction": "Publish a CNAME from forms to edge.example.test. Leave MX, SPF, and DKIM records unchanged."
      },
      {
        "purpose": "ownership",
        "type": "TXT",
        "host": "_topolo-verification.forms",
        "name": "_topolo-verification.forms.example.test",
        "value": "topolo-verification=00000000-0000-4000-8000-000000000003",
        "required": true,
        "instruction": "Publish a TXT record at _topolo-verification.forms.example.test with this exact value. Leave every other TXT record unchanged."
      }
    ],
    "createdAt": "2026-10-21T01:00:00.000Z",
    "updatedAt": "2026-10-21T01:05:00.000Z"
  }
}

Preserve actual original target/request evidence and follow verification/recovery; the fixture authorizes no operation.

Non-active provider state stored

Complete source-derived synthetic, unrun HTTP200. Assumes provider work returns non-active/missing state and the app stores pending_ssl. This does not diagnose pending versus failed/moved/absent provider state.

Input:

{
  "domainId": "domain_00000000-0000-4000-8000-000000000004"
}

Response:

{
  "domain": {
    "id": "domain_00000000-0000-4000-8000-000000000004",
    "hostname": "forms.example.test",
    "status": "pending_ssl",
    "verificationToken": "00000000-0000-4000-8000-000000000003",
    "dnsTarget": "edge.example.test",
    "formId": "forms_docs_fixture",
    "availableAcrossWorkspaces": false,
    "records": [
      {
        "purpose": "routing",
        "type": "CNAME",
        "host": "forms",
        "name": "forms.example.test",
        "value": "edge.example.test",
        "required": true,
        "instruction": "Publish a CNAME from forms to edge.example.test. Leave MX, SPF, and DKIM records unchanged."
      },
      {
        "purpose": "ownership",
        "type": "TXT",
        "host": "_topolo-verification.forms",
        "name": "_topolo-verification.forms.example.test",
        "value": "topolo-verification=00000000-0000-4000-8000-000000000003",
        "required": true,
        "instruction": "Publish a TXT record at _topolo-verification.forms.example.test with this exact value. Leave every other TXT record unchanged."
      }
    ],
    "createdAt": "2026-10-21T01:00:00.000Z",
    "updatedAt": "2026-10-21T01:05:00.000Z"
  }
}

Preserve actual original target/request evidence and follow verification/recovery; the fixture authorizes no operation.

Visible but not owned here

Complete source-derived synthetic, unrun HTTP404. Assumes organization visibility but a failed selected-owner lookup. No DNS/provider mutation is reached.

Input:

{
  "domainId": "domain_00000000-0000-4000-8000-000000000004"
}

Response:

{
  "error": "domain_not_found"
}

Preserve actual original target/request evidence and follow verification/recovery; the fixture authorizes no operation.

Verify and recover

  1. Read domains.list and compare actual id,status,target,form in the original context; DB read-back alone does not settle an uncertain provider attachment.

  2. Use separately approved supported DNS/provider/public read evidence when reachability/origin must be proven. Do not submit a real form response, bypass proof or retry unchanged errors indefinitely.

Reconcile actual provider and DB state before a separately approved exact owner-scoped disconnect. This cannot restore DNS history or retract prior submissions; do not use it as blind rollback after an uncertain attach.

Refusals and uncertainty

400 / workspace_required: Discover/bind the original authorized canonical workspace through Auth; input is not a grant.

403 / forbidden: Preserve actual permission denial and use its owner for legitimate access.

404 / domain_not_found: Reconcile discovered domain and owner workspace; organization visibility is not mutation authority.

422 / invalid_hostname: Use the actual legitimate plain hostname/plan, without bypassing policy or publishing fictional records.

422 / edge_not_configured: Refer actual public-base/provider configuration evidence to the existing owner; do not provision or change credentials as a workaround.

422 / dns_records_missing: Reconcile approved real routing/ownership records while preserving unrelated DNS; do not drop proof or edit stored status to bypass it.

422 / dns_lookup_failed: Preserve actual lookup evidence; failure proves neither provider absence nor verification success.

422 / edge_attach_failed: This helper class also covers provider read/delete errors. Reconcile possible provider effects and original evidence before a repeat.

Concrete branches differ from shared runtime failures. DNS,provider,local state and read-back can disagree after interrupted work; a response is not a complete external effect or rollback receipt.

Change log

  • 2026-10-21: Added owner-workspace/organization visibility, exact published DNS plans, provider/local sequencing, complete illustrative responses and scoped recovery. All examples remain synthetic and unrun.