Skip to main content

Documentation Index

Fetch the complete documentation index at: https://usenaive.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

Overview

CommandDescriptionCost
naive domainsList all domains for your company (includes app_connect_status)Free
naive domains connect --domain <name>Connect a custom domain (BYOD)Free
naive domains setup-records <id> (alias: dns-records)Show the Resend email-provider setup records to add at your registrarFree
naive domains verify <id>Trigger DNS verification for a domainFree
naive domains search <domain>Check domain availability and priceFree
naive domains purchase <domain>Purchase a domain via Stripe CheckoutDomain price (via Stripe)
naive domains zone-records <id>List every record on the live Vercel zoneFree
naive domains set-record <id> [opts]Create or replace a DNS record on the zoneFree
naive domains delete-record <id> <record-id>Delete a DNS record by its provider record IDFree

Two DNS Surfaces

There are two related-but-distinct DNS commands. Pick the right one:
CommandWhat it returnsMutable?
naive domains setup-recordsResend email-provider records (MX/TXT/CNAME) the customer must add at their registrar to pass verificationNo
naive domains zone-recordsEvery record currently on the live Vercel zone, with provider record IDs needed for delete-recordYes (via set-record / delete-record)
The MCP tools follow the same split: naive_resend_setup_records (verification view) vs naive_list_dns_records / naive_set_dns_record / naive_delete_dns_record (live zone).

List Domains

naive domains
{
  "success": true,
  "action": "domains.list",
  "result": {
    "domains": [
      {
        "id": "dom-uuid-1",
        "domain": "acme-corp.usenaive.ai",
        "status": "active",
        "dns_status": "provisioned",
        "byod": false,
        "app_connect_status": null,
        "connected_app_id": null
      },
      {
        "id": "dom-uuid-2",
        "domain": "acme.com",
        "status": "pending_dns",
        "dns_status": "pending_verification",
        "byod": true,
        "app_connect_status": "agent_managed",
        "connected_app_id": null
      }
    ]
  }
}
app_connect_status is null/disconnected for fresh domains, connected once the apex points at a Naive app, agent_managed_pending while an apex A/AAAA write is in flight, and agent_managed once an agent has taken over apex DNS.

Connect Domain (BYOD)

naive domains connect --domain mycompany.com
Returns the Resend DNS records to add at your registrar. After adding them, run naive domains verify <id>.

Verify Domain

naive domains verify <domain-id>
Triggers an immediate verification check. Once all records propagate, the domain transitions to active and can be used for email sending.

Search and Purchase Domains

naive domains search example.com
naive domains purchase example.com
search returns availability and price. purchase creates a Stripe Checkout session — open the returned checkout_url to complete payment. The domain is registered automatically after payment.

Zone Records (live Vercel zone)

naive domains zone-records <domain-id>
{
  "success": true,
  "action": "domains.zone-records",
  "result": {
    "domain": "acme.com",
    "domain_id": "dom-uuid-2",
    "mock": false,
    "records": [
      { "id": "rec_abc", "type": "A", "name": "", "value": "76.76.21.21", "ttl": 60, "comment": "naive:owned;company=co_...;agent=ag_...;ts=1717..." },
      { "id": "rec_def", "type": "CNAME", "name": "www", "value": "shops.myshopify.com", "ttl": 60 }
    ]
  }
}
If the response includes mock: true, the API is in DOMAIN_MOCK mode and the records came from an in-memory store instead of the live Vercel zone.

Set Record (create or replace)

# Apex A record
naive domains set-record <domain-id> --type A --name @ --value 76.76.21.21

# CNAME for www
naive domains set-record <domain-id> --type CNAME --name www --value shops.myshopify.com

# MX with priority
naive domains set-record <domain-id> --type MX --name @ --value mx1.example.com --priority 10

# CAA (must use an allowed CA)
naive domains set-record <domain-id> --type CAA --name @ --value '0 issue "letsencrypt.org"'

Options

FlagRequiredDescription
--type <type>YesOne of A, AAAA, CNAME, MX, TXT, CAA
--value <value>YesRecord value (IPv4/IPv6, hostname, TXT string, or CAA value)
--name <name>NoRecord name; @ or omit for apex. Defaults to @
--ttl <seconds>NoTTL in seconds, 60-86400
--priority <0-65535>NoMX priority (required for MX)
--mode <mode>Noreplace (default) or append. replace PATCHes a single matching record or add-then-deletes multiple; append always creates a new row
--acknowledge-unownedNoOverwrite a record that wasn’t created by Naive

Output

{
  "success": true,
  "action": "domains.set-record",
  "result": {
    "ok": true,
    "record": { "id": "rec_xyz", "type": "CNAME", "name": "www", "value": "shops.myshopify.com" },
    "mock": false,
    "ownership": "naive",
    "replaced_count": 1,
    "path": "patch"
  },
  "hints": [
    "Wrote CNAME record at 'www' (id: rec_xyz)",
    "Replaced 1 existing record(s) via patch"
  ]
}
path is one of:
  • patch — A single matching record was updated in place (atomic, no race window)
  • add-then-delete — Multiple matching records existed; the new record was added first, then the old ones were best-effort deleted
  • add — No matching record existed; a fresh row was created
ownership is naive for clean writes and unowned-acknowledged when --acknowledge-unowned was used to override an existing non-Naive record.

Delete Record

naive domains delete-record <domain-id> <record-id>
naive domains delete-record <domain-id> <record-id> --acknowledge-unowned
The record ID comes from naive domains zone-records. Protected records (DMARC, DKIM, inbound MX/TXT) and system domains cannot be deleted — the API returns 403 forbidden with reason: "PROTECTED_RECORD" or "SYSTEM_DOMAIN".

Safety Rules (enforced by the API)

RuleReason code
Allowed types only: A, AAAA, CNAME, MX, TXT, CAADISALLOWED_RECORD_TYPE
Wildcards (* or *.foo) are rejectedDISALLOWED_RECORD_TYPE
TTL must be 60-86400 secondsINVALID_TTL
MX records require a 0-65535 priorityINVALID_MX_PRIORITY
CNAME at apex is not permittedCNAME_AT_APEX
CNAME cannot coexist with A/AAAA/MX/TXT at the same nameCNAME_COEXISTENCE
CAA values must use one of: ssl.com, letsencrypt.org, digicert.com, sectigo.com, globalsign.com, amazon.com, pki.goog, google.comCA_NOT_ALLOWED
System domains (registrar=system) are read-onlySYSTEM_DOMAIN
DMARC and DKIM TXT records are protectedPROTECTED_RECORD
Inbound subdomain MX/TXT (e.g. agents.acme.com) is protectedPROTECTED_RECORD
Per-company rate limit: 5 mutations/min, 20/hrRATE_LIMITED (sets Retry-After)
Overwriting/deleting a record not created by Naive requires --acknowledge-unownedUNOWNED_RECORD_REQUIRES_ACK

Mock Mode

If the API is configured with DOMAIN_MOCK=true (or VERCEL_REGISTRAR_TOKEN is unset), DNS edits are simulated against an in-memory store and the response includes mock: true. Useful for local development and CI; real DNS is not touched. The feature flag AGENT_DNS_EDIT_ENABLED defaults to on. Flip it to false only as an emergency kill switch. When disabled the endpoints return 501 feature_not_configured with reason: "FEATURE_DISABLED".

Apex A/AAAA flips app_connect_status

naive domains set-record <id> --type A --name @ --value ... (and the AAAA equivalent) atomically transitions the domain to app_connect_status = "agent_managed":
  1. Pre-flip the row to agent_managed_pending and clear connected_app_id.
  2. Write to Vercel.
  3. On success, commit the flip to agent_managed and emit a domain.updated live event with payload.action = "agent_managed".
  4. On failure, roll back to the previous status (best-effort).
Reapers and connect sweeps in either Naive product (this SDK or naive-paperclip on a shared DB) skip agent_managed/agent_managed_pending rows, so the agent’s record won’t be reverted. To re-enable Naive app routing the user must explicitly disconnect and reconnect the domain from the dashboard — the agent cannot reverse this automatically.

Audit log + live events

Every successful or rejected DNS edit appends a row to activity_log:
ActionWhen
dns.record.setSuccessful set-record
dns.record.deleteSuccessful delete-record
dns.record.rejectedAny guard-rail rejection
The same event also fans out on the Server-Sent Events stream (GET /v1/events) as domain.updated (and activity.logged) so dashboards and supervising agents can react in real time.

Workflow: Editing Apex DNS for a New Web App

# 1. List domains and copy the UUID of the BYOD domain you want to edit.
naive domains

# 2. Inspect the current zone — find any existing apex A record.
naive domains zone-records <domain-id>

# 3. Replace the apex A record so traffic points at your new app.
naive domains set-record <domain-id> --type A --name @ --value 76.76.21.21

# 4. Re-list to confirm.
naive domains zone-records <domain-id>