x402-hosting: full-stack Next.js hosting for agents

x402-hosting

4 min read Original article ↗

[ Base URL: api.x402-hosting.com ]

Prepaid, full-stack Next.js hosting operated by agents. One command builds the project in your current directory and publishes it to a production URL; the wallet that pays owns the project. No account, no dashboard — every operation below is a plain HTTP endpoint, paid in USDC over x402 where a price is listed. Reads are free.

$ npx x402-hosting@latest deploy --days 30

$0.20 per project-day, $0.01 for the first upload. USDC over x402, prepaid, no subscription. Errors return application/problem+json.

Uploads Paid artifact upload sessions. The verified payer of the initial upload becomes the project owner.

POST/v1/uploadsCreate the initial upload session$0.01

Parameters travel in the query string and the body is empty. PUT the zip artifact to the returned uploadUrl, then call POST /v1/projects.

Parameters

NameInDescription
Idempotency-Keyrequired

uuid

headerClient-generated; also the operation id.
namerequired

string

query—
sizerequired

integer

query—
sha256required

string

query64 lowercase hex chars.
contentTyperequired

string

queryMust be application/zip.

Returns · UploadSession + operationId

{
  "uploadId": "uuid",
  "uploadUrl": "uri",
  "expiresAt": "date-time",
  "headers": { "string": "string" },
  "operationId": "uuid"
}

Responses

201Upload session created.
400Invalid request.
402Payment required.
413Artifact too large.
POST/v1/projects/{id}/uploadsCreate a deployment upload session$0.01

Only the owner wallet can pay. Upload the artifact, then call POST /v1/projects/{id}/deployments.

Parameters

NameInDescription
idrequired

uuid

path—
Idempotency-Keyrequired

uuid

headerClient-generated; also the operation id.
sizerequired

integer

query—
sha256required

string

query64 lowercase hex chars.
contentTyperequired

string

queryMust be application/zip.

Returns · UploadSession + operationId

{
  "uploadId": "uuid",
  "uploadUrl": "uri",
  "expiresAt": "date-time",
  "headers": { "string": "string" },
  "operationId": "uuid"
}

Responses

201Upload session created.
402Payment required.

Projects Stable websites controlled by their owner wallet.

POST/v1/projectsCreate a project and trigger its initial deploymentfree

The owner is inherited from the paid upload's verified payer. Idempotent on uploadId: a repeat returns the existing project.

Request body

{ "uploadId": "uuid", "name": "my-site" }

Returns · QueuedOperation

{
  "projectId": "uuid",
  "operationId": "uuid",
  "operationUrl": "uri",
  "state": "queued",
  "url": "uri"
}

Responses

202Bootstrap queued; poll the returned operationUrl.
400Invalid request.
409State conflict.
GET/v1/projects/{id}Read project statusfree

The unguessable project id is the read capability; no wallet or token needed.

Parameters

NameInDescription
idrequired

uuid

path—

Returns · Project

{
  "projectId": "uuid",
  "name": "my-site",
  "slug": "app-682fe91de571a7338dd1",
  "url": "uri",
  "state": "active",
  "walletAddress": "0x…",
  "expiresAt": "date-time",
  "activationDeadline": "date-time | null",
  "renewableUntil": "date-time | null",
  "currentDeploymentId": "uuid | null",
  "pendingDeploymentId": "uuid | null"
}

Responses

200Project metadata, including walletAddress and expiresAt.
404Resource not found.
POST/v1/projects/{id}/activateActivate a created project$0.20 / day

Only the owner wallet bound at creation can pay; other wallets are rejected before settlement.

Parameters

NameInDescription
idrequired

uuid

path—
daysrequired

integer

query1–730.
Idempotency-Keyrequired

uuid

headerClient-generated; also the operation id.

Returns · QueuedOperation

{
  "projectId": "uuid",
  "operationId": "uuid",
  "operationUrl": "uri",
  "state": "queued",
  "url": "uri"
}

Responses

202Activation accepted; settlement activates the project.
402Payment required.
409State conflict.
POST/v1/projects/{id}/renewRenew an active or expired project$0.20 / day

Parameters

NameInDescription
idrequired

uuid

path—
daysrequired

integer

query1–730.
deploymentId

uuid

queryDefaults to the pending or current deployment.
Idempotency-Keyrequired

uuid

headerClient-generated; also the operation id.

Returns · QueuedOperation

{
  "projectId": "uuid",
  "operationId": "uuid",
  "operationUrl": "uri",
  "state": "queued",
  "url": "uri"
}

Responses

202Renewal queued; publishing starts after settlement.
402Payment required.
409State conflict.
POST/v1/projects/{id}/transferTransfer the controlling wallet$0.01

Parameters

NameInDescription
idrequired

uuid

path—
toAddressrequired

string

queryEVM address, 0x + 40 hex chars.
Idempotency-Keyrequired

uuid

headerClient-generated; also the operation id.

Returns · QueuedOperation

{
  "projectId": "uuid",
  "operationId": "uuid",
  "operationUrl": "uri",
  "state": "queued",
  "url": "uri"
}

Responses

202Transfer queued and applied after settlement.
402Payment required.
DELETE/v1/projects/{id}Queue project deletion$0.01

Irreversible. Deletion work starts after settlement.

Parameters

NameInDescription
idrequired

uuid

path—
Idempotency-Keyrequired

uuid

headerClient-generated; also the operation id.

Returns · QueuedOperation

{
  "projectId": "uuid",
  "operationId": "uuid",
  "operationUrl": "uri",
  "state": "queued",
  "url": "uri"
}

Responses

202Deletion queued.
402Payment required.
409State conflict.

Deployments Immutable uploaded releases belonging to a project.

POST/v1/projects/{id}/deploymentsTrigger a deployment from an uploadfree

Request body

{ "uploadId": "uuid" }

Returns · QueuedOperation

{
  "projectId": "uuid",
  "operationId": "uuid",
  "operationUrl": "uri",
  "state": "queued",
  "url": "uri"
}

Responses

202Build queued; poll the returned operationUrl.
409State conflict.
GET/v1/projects/{id}/deploymentsList deployments, one page at a timefree

Parameters

NameInDescription
idrequired

uuid

path—
limit

integer

query1–100, default 20.
cursor

uuid

query—

Returns · { projectId, deployments: Deployment[], nextCursor }

{
  "projectId": "uuid",
  "deployments": [ "Deployment" ],
  "nextCursor": "uuid | null"
}

Responses

200One page of deployments plus nextCursor.
GET/v1/projects/{id}/deployments/{deploymentId}Read one deploymentfree

Parameters

NameInDescription
idrequired

uuid

path—
deploymentIdrequired

uuid

path—

Returns · Deployment

{
  "deploymentId": "uuid",
  "projectId": "uuid",
  "deploymentNumber": 3,
  "state": "ready",
  "current": true,
  "pending": false,
  "sha256": "hex",
  "size": 1024,
  "createdAt": "date-time",
  "readyAt": "date-time | null"
}

Responses

POST/v1/projects/{id}/rollbackPromote a previous deployment$0.01

Parameters

NameInDescription
idrequired

uuid

path—
deploymentIdrequired

uuid

query—
Idempotency-Keyrequired

uuid

headerClient-generated; also the operation id.

Returns · QueuedOperation

{
  "projectId": "uuid",
  "operationId": "uuid",
  "operationUrl": "uri",
  "state": "queued",
  "url": "uri"
}

Responses

202Rollback queued; publishing starts after settlement.
402Payment required.
409State conflict.

Operations Free polling and payment reconciliation.

GET/v1/operations/{operationId}Poll a workflow or reconcile a paymentfree

The Idempotency-Key of a paid call is its operation id. If a payment tool errors, poll here before paying again.

Parameters

NameInDescription
operationIdrequired

uuid

path—

Returns · Operation

{
  "operationId": "uuid",
  "projectId": "uuid",
  "type": "deploy",
  "state": "succeeded",
  "result": {},
  "payment": {
    "transaction": "hash",
    "network": "string",
    "payer": "0x…",
    "amount": "string",
    "settledAt": "date-time"
  } | null
}

Responses

200Operation, serialized result, and settlement receipt.
404Resource not found.