← All posts

Shipping this site with gddy and an AI agent

  • godaddy
  • gddy
  • nodejs
  • agents

This site went from a résumé PDF to a private preview on GoDaddy's Node.js Hosting in one evening. I did it by pairing with Claude Code: I steered, and the agent did the typing, testing, and most of the poking at APIs. Every GoDaddy interaction went through gddy, GoDaddy's command-line interface for its developer platform.

This post covers what worked, what surprised us, and what I'd tell anyone else pointing an agent at gddy.

The shape of the project

The requirements were short:

  • Turn the résumé into a portfolio site.
  • Host it on a domain I already own.
  • Leave room for my side projects to live under paths on the same domain, like /<app>/.
  • Keep personal contact details off the public page.
  • Later: add a blog that's easy to write for.

The result is a plain HTML/CSS site, a Node server with no runtime dependencies, and a Markdown blog generated at build time. Nothing clever. The interesting part was the platform work around it.

Step 1: picking a domain from the CLI

gddy domain list returned every domain on my account as JSON: name, status, expiry, auto-renew. That's exactly what an agent wants. It didn't have to scrape a dashboard; it could filter the name domains in one pass and then run gddy dns list <domain> on each candidate.

The DNS records told the real story:

  • One domain was parked and otherwise empty — a clean slate.
  • One carried MX and SPF records for my email. Touching that one would break mail, so it was out.
  • One returned ZONE_NOT_FOUND. It's registered at GoDaddy, but its nameservers point somewhere else, so GoDaddy has no zone to show. gddy domain get confirmed it by listing the external nameservers.

Lesson: registration and DNS hosting are separate things, and the CLI keeps them separate too. domain get tells you who answers DNS; dns list only works when the answer is GoDaddy.

I landed on andrewwilliamson.org.

Step 2: permissions arrive one at a time

gddy asks for OAuth scopes as it needs them. The first domain list opened a browser for domains.domain:read. Later, listing hosting subscriptions asked again for hosting.subscription:read, then creating an app asked for hosting.application:create, and so on.

That's good security design, but it changes how you work with an agent:

  • Someone has to be at the keyboard. When I stepped away, the CLI waited for the OAuth callback and eventually timed out.
  • Not every scope will be granted. A call to a general-purpose subscriptions endpoint wanted commerce.subscription:read. The browser flow came back with no authorization code in callback, which in practice meant "that scope isn't available to this client."

Lesson: expect a browser prompt the first time you touch a new command family, and treat a failed consent as "this API isn't for you" rather than a bug to retry.

Step 3: "you have no hosting plans" (I do)

This one confused both of us. gddy hosting subscription list --hosting-product WEB_HOSTING came back with zero items. I do have hosting with GoDaddy.

The catch: the hosting commands cover GoDaddy's newer Node.js Hosting product. Classic hosting products don't show up there at all, and asking for MANAGED_WORDPRESS returned a 501 NOT_APPLICABLE. An empty list meant "no plans of this kind," not "no plans."

The catalog was easier. gddy shopping catalog search --category webHosting listed the Node.js plans with prices. Prices come back in cents (799 is $7.99), which is worth knowing before an agent quotes you a number.

Lesson: read an empty result as "empty for this product line," and check which product a command actually covers before concluding anything.

Step 4: fitting the platform's contract

GoDaddy publishes a short list of requirements for Node.js Hosting, and they're refreshingly ordinary:

  • package.json with name, version, main, and build and start scripts
  • listen on process.env.PORT
  • no node_modules in the upload; the platform runs npm install
  • zip under 100 MB

A static site doesn't need a Node server, but this platform runs Node apps, so the site got a small one: under 200 lines, no runtime dependencies. It serves files, answers /healthz, and blocks path traversal.

It also solved my "apps under paths" requirement. Node.js Hosting attaches a domain to an app, so there isn't an obvious way to mount several apps under paths of one domain. The server reverse-proxies instead: a routes.json entry maps /myapp to wherever that app really runs, redirects /myapp to /myapp/, and rewrites the app's redirects so they stay under the prefix.

Lesson: if the platform's unit is "one app per domain," your front door can be an app too.

Step 5: create, upload, preview

The deploy itself was a clean, pollable pipeline:

gddy hosting app create --app-type NODEJS --name portfolio   # returns an operation ID
gddy hosting operation get --operation-id <id>               # poll until COMPLETED -> app ID
gddy hosting source upload --app-id <app> --file portfolio.zip
gddy hosting source status --app-id <app> --import-id <id>   # poll until COMPLETED
gddy hosting app get --app-id <app>                          # preview + publish URLs
gddy hosting log list --app-id <app>                         # did it actually start?

Every response included a next_actions block naming the command to run next, with the IDs already filled in. For an agent, that's the difference between guessing and following instructions. It went through the whole flow without reading documentation.

Two details:

  • The preview URL only works while you're signed in to GoDaddy. That's great for privacy, but an agent can't open it on its own.
  • The publish URL answers right away with a "Coming Soon" page. A 200 there doesn't mean your app is live; publishing needs a plan attached first.

Step 6: the GitHub link

I wanted pushes to main to redeploy automatically. The CLI can re-import from a GitHub repo (gddy hosting source github), but only one that's already linked in the web UI, and the link itself is made there.

In the UI, my brand-new repo wasn't in the picker. The list looked cut off around 30 entries and included repos I only collaborate on, so my guess is it only shows the first page. We shipped the preview from a zip of the exact commit on main (git archive HEAD), so it still matches the repo.

Lesson: decide early whether you want zip-driven or Git-driven deploys, because the Git link is a UI step.

What I'd tell someone else

  • gddy is agent-friendly by default. JSON output, next_actions hints, --dry-run on mutations, and async operations you can poll. It's one of the easier platform CLIs to hand to an agent.
  • Stay near the browser. Scopes are granted as you go, and the consent screen is yours to click.
  • Know which product a command covers. "No results" often means "wrong product line."
  • Keep the agent on a short leash for anything outward-facing. Mine asked before creating cloud resources, never touched the domains I told it to leave alone, and kept my phone number and email off the site without being reminded twice.

The site you're reading is the output. The next step is attaching a plan and pointing the domain at it. I'll write that up too.