| name | eliza-cloud-buy-domain |
| description | Use whenever a user wants to register or buy a custom domain for an Eliza Cloud app — including in the same request as building the app ("build me X and put it on Y.com"). Uses cloudflare as registrar, no human in the loop, paid from the user's existing cloud credit balance. Pairs with `build-monetized-app` (build first, then buy domain) and `eliza-cloud-manage-domain` (post-purchase: list, edit dns records, detach). Skip when the user is fine with the auto-assigned `*.apps.elizacloud.ai` subdomain. |
Buy a domain for your app on Eliza Cloud
Use this skill when an Eliza Cloud app needs a real custom domain (e.g. myapp.com) instead of the auto-assigned *.apps.elizacloud.ai subdomain.
The cloud handles everything: domain availability check, registration through cloudflare, DNS pointing at your app's container, and attachment to your app record. You pay from your existing cloud credit balance — no separate cloudflare account, no manual DNS config, no credit card paste.
Prerequisites
- An app registered on Eliza Cloud (use
build-monetized-app first if you haven't shipped one yet)
- Enough cloud credit balance to cover the domain (cloudflare wholesale + a fixed eliza cloud margin; a
.com is roughly $14–15 USD/year)
ELIZAOS_CLOUD_API_KEY in env (provided by the runtime)
Default flow
import { ElizaCloudClient } from "@elizaos/cloud-sdk";
const cloud = new ElizaCloudClient({
apiKey: process.env.ELIZAOS_CLOUD_API_KEY,
baseUrl: process.env.ELIZA_CLOUD_BASE_URL,
});
const quote = await cloud.routes.postApiV1AppsByIdDomainsCheck({
appId,
json: { domain: "myapp.com" },
});
if (!quote.available) {
return;
}
const totalUsd = quote.price.totalUsdCents / 100;
const result = await cloud.routes.postApiV1AppsByIdDomainsBuy({
appId,
json: { domain: "myapp.com" },
});
const status = await cloud.routes.postApiV1AppsByIdDomainsStatus({
appId,
json: { domain: "myapp.com" },
});
Failure modes
The buy route handles refunds and surfaces specific HTTP statuses; treat them like:
| Status | Meaning | Action |
|---|
| 400 | invalid domain format | re-prompt user for valid domain |
| 402 | insufficient credit balance | tell user to top up at /dashboard/billing |
| 404 | app not found / wrong org | re-check appId |
| 409 | domain already registered | suggest alternates or add a suffix |
| 502 | cloudflare returned an error (refund issued) | retry with different domain |
| 500 | partial failure (rare; user owns the domain but DNS not set) | escalate — manual DNS may be needed |
The skill assumes idempotency at the step boundary: if step 3 fails after the credit debit, eliza cloud automatically refunds. If the user retries, they get a fresh credit-debit attempt.
Read these references in order
references/api-shape.md — the actual request/response shape for each cloud endpoint
references/dns-and-ssl.md — what happens after the buy (CNAME setup, SSL provisioning timing)
references/failure-modes.md — recovery table for the failures you'll actually hit
After the buy succeeds, future "list / edit / delete dns / detach" requests on this domain are handled by the eliza-cloud-manage-domain skill — point the user there if they ask follow-up questions.
What this skill is NOT
- Not for "attaching a domain you already own elsewhere." That path goes through
POST /api/v1/apps/[id]/domains directly (which generates a _eliza-cloud-verify.<domain> TXT record the user adds at their existing dns provider, then re-checks via POST /api/v1/apps/[id]/domains/verify). Use this buy-domain skill only when the user does NOT already own the domain.
- Not for cancelling a registration. Cloudflare registrations are non-refundable after they're complete; you can detach from the app via
DELETE /api/v1/apps/[id]/domains but the registration itself stays active until expiration.
- Not for transferring an existing domain into eliza cloud. Out of scope for v1.