Domains & DNS
Domains & DNS let a deployed agent check domain availability, register and renew names, inspect owned domains, manage DNS records, and start a transfer out. Agent steps call the typed ctx.sapiom.domains capability; Sapiom supplies the authenticated cloud connection when the deployed agent runs.
Choose the domain operation
Section titled “Choose the domain operation”| What the agent needs | Recommended operation |
|---|---|
| Availability plus current purchase and renewal quotes | domains.check({ domainNames }) |
| Register one approved domain for one year | domains.register({ domainName }) |
| Inspect or enumerate owned domains | domains.get(...) or domains.list() |
| Extend an owned domain by one year | domains.renew({ domainName }) |
| Create, inspect, change, or remove DNS | domains.dns.* |
| Move a domain to another registrar | domains.transferOut({ domainName }) |
Availability can change between check and registration. Treat the returned quote as decision input, not a reservation.
Check before registering
Section titled “Check before registering”Registration is a real purchase. Require the exact name and a price ceiling from an approval boundary before the step calls register:
const [candidate] = await ctx.sapiom.domains.check({ domainNames: [input.approvedDomain],});
if (!candidate || candidate.domainName !== input.approvedDomain) { throw new Error("Availability response did not match the approved domain");}
if (!candidate.available) { return { registered: false, reason: "unavailable" };}
const quotedPrice = Number(candidate.purchasePrice);if ( !Number.isFinite(input.approvedMaxPurchasePrice) || !Number.isFinite(quotedPrice) || quotedPrice > input.approvedMaxPurchasePrice) { return { registered: false, reason: "price-not-approved", quotedPrice: candidate.purchasePrice ?? null, };}
const domain = await ctx.sapiom.domains.register({ domainName: candidate.domainName,});
return { registered: true, domainName: domain.domainName, expiresAt: domain.expiresAt ?? null,};Check accepts 1–50 names and returns decimal purchase and renewal prices as strings when available. Registration and renewal charge on success. Recheck any policy-relevant value at the point of action and handle a registration failure even after a positive availability result.
Manage DNS records
Section titled “Manage DNS records”Use host: "" for the root domain and a label such as "www" or "api" for a subdomain:
const record = await ctx.sapiom.domains.dns.create({ domainName: input.domainName, type: "A", host: "", value: input.ipAddress, ttl: 300,});
return { recordId: record.recordId, fqdn: record.fqdn ?? record.domainName, value: record.value,};Supported record types are A, AAAA, ANAME, CNAME, MX, TXT, SRV, and NS. TTL has a minimum of 300 seconds and defaults to 300. MX records require priority.
Call domains.dns.list({ domainName }) to obtain record IDs before updating or deleting. An update accepts only the fields that should change, but the agent should read current state first when it must avoid overwriting a concurrent change.
Renew or transfer deliberately
Section titled “Renew or transfer deliberately”Use domains.get before renewal to inspect current expiry and renewal price. Transfer-out is disruptive: it can unlock the domain and returns an authorization code for the receiving registrar. Keep that code out of logs, shared state, and ordinary agent output, and expose it only through the approved transfer workflow.
Test the behavior locally
Section titled “Test the behavior locally”Local Run replaces domain and DNS calls with deterministic results. The built-in availability stub marks every requested name available, so never use its default as evidence that a real domain can be purchased.
Override the entire decision path for each test case:
{ "version": 1, "steps": { "register-domain": { "domains.check": [ { "domainName": "approved-example.dev", "available": true, "purchasePrice": "12.99", "renewalPrice": "12.99", "premium": false } ], "domains.register": { "domainName": "approved-example.dev", "status": "active", "registeredAt": "2099-01-01T00:00:00.000Z", "expiresAt": "2100-01-01T00:00:00.000Z", "purchasePrice": "12.99" } } }}Use separate fixtures for unavailable, premium, over-budget, DNS, renewal, and transfer branches. After each run, assert the terminal output and require both unusedStubs and stubWarnings to be empty. Local Run never registers, renews, modifies DNS, or starts a transfer.
Manage lifecycle and usage
Section titled “Manage lifecycle and usage”Track expiry outside the final renewal window, retain the returned domain and record IDs, and verify DNS after changes through the system that will consume it. Domain registration, renewal, and DNS propagation have different lifecycles.
Use the live quotes returned by check and get, plus the signed-in capability catalog for current availability and limits. Do not embed a domain price in agent source.
© 2026 Sapiom, Inc.