# Provision a WordPress site and publish to it

Take a domain from "just registered" to "live WordPress site with content" without ever opening a dashboard: provision **Cloud for WordPress**, mint a WordPress credential scoped for automation, then publish over the WordPress REST API.

## 1. Pick a plan

```bash
curl -s https://api.porkbun.com/api/json/v3/hosting/plans \
  -H "X-API-Key: pk1_..." -H "X-Secret-API-Key: sk1_..."
```

Rows where `product` is `cloudWordPress` are WordPress plans (`CLOUDWORDPRESSM1` = Starter monthly, $12.00/mo). Note the `sku` and the `price` in cents — you pass both to the next call.

## 2. Provision the site

```bash
curl -X POST https://api.porkbun.com/api/json/v3/hosting/create/example.com \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"pk1_...","secretapikey":"sk1_...",
       "sku":"CLOUDWORDPRESSM1",
       "acknowledgedCost":1200,
       "agreeToTerms":"yes",
       "agreeToNameserverChange":true}'
```

- `acknowledgedCost` must equal the plan price in cents — it forces the cost to be surfaced to the human before anything auto-renews.
- Provisioning switches the domain to Porkbun nameservers, so `agreeToNameserverChange` is required unless it's already on them.
- The domain's **first** provision is a 15-day free trial (nothing charged now) that auto-renews at the plan price. One free trial per domain.
- Add `"dryRun":true` first to validate everything without provisioning or charging.

The response includes `hosting.status` and, for WordPress plans, `hosting.wordpress.restUrl` + `adminUrl`. If `status` is `PENDING`, poll `GET /hosting/get/example.com` until it is `ACTIVE`.

## 3. Mint a credential for automation

```bash
curl -X POST https://api.porkbun.com/api/json/v3/hosting/createWpCredentials/example.com \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"pk1_...","secretapikey":"sk1_...","name":"My-Agent"}'
```

This creates a WordPress **Application Password** and returns it **once** — store it immediately, because WordPress keeps only a hash.

This works on any Cloud for WordPress site in the account — it doesn't matter whether the API or the website provisioned it. (Free $0 preview/parked sites are excluded and return `PREVIEW_SITE_NOT_SUPPORTED`; upgrade to a paid plan first.)

By default it belongs to a dedicated `porkbun-agent` user with the **editor** role: it can create and edit content but **cannot install plugins or change site settings**. That's the right credential for an automated integration. If you genuinely need full control, pass `"role":"administrator"` plus `"acknowledgeFullAccess":true` — an administrator application password can install plugins, which means it can run arbitrary code on the site. (The site's actual administrator account is looked up rather than assumed, so a renamed admin user is handled.)

## 4. Publish

Authenticate to the REST API with HTTP Basic using the username and application password (the response also hands you a ready-made `authorization` header value):

```bash
curl -X POST https://example.com/wp-json/wp/v2/posts \
  -u "porkbun-agent:<applicationPassword>" \
  -H 'Content-Type: application/json' \
  -d '{"title":"Hello from the API","content":"<p>Published programmatically.</p>","status":"publish"}'
```

From here the whole [WordPress REST API](https://developer.wordpress.org/rest-api/) is available — posts, pages, media, categories, comments.

## 5. Audit and revoke

```bash
# list (metadata only — passwords can never be re-read)
curl -s "https://api.porkbun.com/api/json/v3/hosting/getWpCredentials/example.com" \
  -H "X-API-Key: pk1_..." -H "X-Secret-API-Key: sk1_..."

# revoke one, or all for a user
curl -X POST https://api.porkbun.com/api/json/v3/hosting/deleteWpCredentials/example.com \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"pk1_...","secretapikey":"sk1_...","uuid":"<uuid from the list>"}'
```

Revocation takes effect immediately. The owner can also see and remove these under **Users → Profile → Application Passwords** in wp-admin.

## Notes

- The file endpoints (`/hosting/deploy`, `/hosting/files`, `/hosting/makeDir`, `/hosting/deleteFile`) are for **Secure Static Hosting**. On a WordPress site they return `NOT_SUPPORTED_FOR_PRODUCT` — manage content through WordPress instead.
- Application passwords require the site to be served over HTTPS, which Porkbun provisions automatically.
- Hosting is not simulated in the sandbox: a `pk1_sb_` key gets `SANDBOX_UNSUPPORTED` on these endpoints.
- Prefer the least-privilege `editor` credential for agents, and revoke it when the integration is done.
- Per-key scoping applies: if the API key is restricted to specific domains, these calls only work on those domains (`DOMAIN_NOT_ALLOWED` otherwise).
- Velocity limits: 10 provisions and 20 credential mints per account per hour. `dryRun` calls don't count.


---

## More

- Guides (how-tos): https://porkbun.com/llms/guides
- Topic index: https://porkbun.com/llms
- Full reference (one file): https://porkbun.com/llms-full.txt
- OpenAPI spec (full schemas): https://porkbun.com/api/json/v3/spec
- Short overview: https://porkbun.com/llms.txt
- Official MCP server: https://porkbun.com/mcp (`npx -y @porkbunllc/mcp-server`)
- Create API keys: https://porkbun.com/account/api
