# Node.js Hosting concepts (https://developer.godaddy.com/en/docs/api-users/concepts/nodejs-hosting-concepts)

***

title: Node.js Hosting concepts
description: Variants, deployments, async jobs, and secrets — the mental model behind the Node.js Hosting API.
related:
tutorials:

* title: Get started
  href: /docs/hosting/getting-started
  guides:
* title: Authentication
  href: /docs/hosting/authentication
  apis:
* title: Node.js Hosting API reference
  href: /docs/references/rest/nodejs-hosting

***

The API is small — five resource groups, roughly fifteen endpoints — but three concepts run through all of them: **variants**, **async jobs**, and **deployments**. Once you have those, the rest of the surface reads itself.

## Variants

Every app has two runtime variants:

| Variant   | What it is                                                    | Typical use                              |
| --------- | ------------------------------------------------------------- | ---------------------------------------- |
| `preview` | Working copy. Receives new source uploads and secret changes. | Iteration, integration testing, staging. |
| `publish` | Production copy. Serves live traffic.                         | Whatever your users actually hit.        |

Uploads land on `preview`. **Publishing** promotes the current preview to `publish`. **Rollback** points `publish` at a prior deployment. `preview` is never rolled back — only overwritten by the next upload.

Per-variant reads differ by endpoint. `GET /status` returns both variants in one response with no filter parameter. `GET /secrets` accepts an optional `variant` query parameter. `GET /logs` uses a required `target` query parameter (`preview` or `publish`), plus `source`, `since`, and optional `lines`. Secret writes take `variant` in the request body.

## Async jobs

Operations that outlive a single request return immediately with a job or deployment record. Poll a status endpoint until they reach a terminal state.

### Terminal states

| Job type           | Poll endpoint                                                  | Terminal states                                                                                               |
| ------------------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Create app         | `GET /apps/jobs/{jobId}`                                       | `active` (ready), `failed`                                                                                    |
| Source upload      | `GET /apps/{appId}/source/status?jobId=...`                    | `succeeded`, `failed` (exact enum values are in the [reference](https://developer.godaddy.com/docs/references/rest/nodejs-hosting/source)) |
| Publish / rollback | `GET /apps/{appId}/deployments` and `GET /apps/{appId}/status` | Latest deployment reports a completed status; runtime status flips to `running` on the affected variant       |

### Polling guidance

* **Interval:** 2–5 seconds is a good starting point. Back off on longer jobs.
* **Give-up window:** most create/upload jobs complete in under a minute. If you're still in `pending` after several minutes, treat it as stuck and surface an error.
* **Idempotency:** re-polling is free. The status endpoints have no side effects.

## Deployments

A **deployment** is a snapshot of source + config that ran (or is running). Deployments are numbered and durable — even after publish overwrites the live one, older deployments remain listable and are eligible rollback targets.

```
POST /apps/{appId}/source           # upload zip → job → new source on preview
POST /apps/{appId}/deployments      # publish preview → new deployment on publish
GET  /apps/{appId}/deployments      # history (paginate with limit, default 20, max 50)
POST /apps/{appId}/rollback         # publish variant → prior deploymentId
```

Runtime status (`GET /apps/{appId}/status`) is a separate concern from deployments — it tells you whether the variant is actually up and serving, independent of what deployment it points at.

## Secrets

Secrets are set per-variant. They can be added, updated, or deleted in a single call, up to 50 of each per request:

```json
{
  "variant": "preview",
  "operations": {
    "additions": [{ "name": "STRIPE_KEY", "value": "sk_test_..." }],
    "updates":   [{ "name": "DB_URL",    "value": "postgres://..." }],
    "deletions": [{ "name": "OLD_FLAG" }]
  }
}
```

The response contains **metadata only** — names, last-updated timestamps, etc. Values are never returned by any endpoint, including reads. If you need to know what a secret is set to, look it up in whatever system generated it.

Listing secrets (`GET /apps/{appId}/secrets`) currently requires the `secrets:write` scope even though it's a read operation. Treat that as the effective requirement for now.

## Putting it together

Every step above is a single API call plus polling. That's the whole model.

For the end-to-end deploy walkthrough, go to [Get started](https://developer.godaddy.com/docs/hosting/getting-started). For tokens and scopes, go to [Authentication](https://developer.godaddy.com/docs/hosting/authentication). For endpoints, go to the [Node.js Hosting API reference](https://developer.godaddy.com/docs/references/rest/nodejs-hosting).
