Support

Hosting core concepts

View as Markdown

Variants, deployments, async jobs, and secrets — the mental model behind the Hosting API.

Overview

This page explains the mental model behind the Hosting API. Three concepts run through all resource groups: variants, async jobs, and deployments. Understanding these makes the rest of the surface readable on first contact.

The Hosting API supports Node.js apps. Other product types will be supported in future releases.

Go to Deploy your Node.js app for a hands-on walkthrough. Go to the Hosting API reference for endpoint details.

Variants

Every hosted app needs a way to test a change without exposing it to the traffic your users are already hitting. The Hosting API solves this by giving every app two parallel runtime copies, called variants, instead of leaving you to provision and wire up separate staging and production environments yourself. Each variant has its own source, its own secrets, and its own URL; however, they belong to the same app and share the same id.

The following table describes the two variants:

VariantWhat it isTypical use
previewWorking copy. Receives new source uploads and secret changes.Iteration, integration testing, staging.
publishProduction copy. Serves live traffic.Whatever your users actually hit.

Uploads land on preview. Publishing promotes the current preview to publish. Only the next upload overwrites preview.

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 accepts an optional variant query parameter (PREVIEW or PUBLISH, defaults to PREVIEW), plus optional filters for source (stream), level (severity), and since (timestamp). 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.

The following diagram shows the create-app polling sequence:

Rendering diagram...

Terminal states

The following table lists the terminal states for each job type and the endpoint to poll:

Job typePoll endpointTerminal states
Create appGET /app-operations/{operationId}COMPLETED (ready), FAILED
Source importGET /apps/{appId}/imports/{importId}COMPLETED, FAILED
PublishGET /apps/{appId}/deployments/{deploymentId} and GET /apps/{appId}/statusLatest deployment reaches COMPLETED; then inspect variants on the status response for the affected environment

Polling guidance

The following list provides guidance for polling async jobs:

  • Interval: two to five seconds is a good starting point. Back off on longer jobs.
  • Give-up window: most create and 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.
  • Idempotency-Key header: Include Idempotency-Key: <uuid> on mutation requests (POST, PATCH) to make retries safe. If the server receives a duplicate request with the same key, it returns the original response without creating a duplicate resource.

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.

The following calls create and list deployments:

POST /apps/{appId}/imports          # 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)

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

You configure secrets per variant using a standard RFC 6902 JSON Patch array. Pass the environment as the variant query parameter (PREVIEW or PUBLISH). Each path is /{SECRET_NAME}. A single PATCH request can add, replace, or remove secrets. The combined total must not exceed 50 operations per request. The following request body shows all three operation types in one call:

[
  { "op": "add",     "path": "/STRIPE_KEY", "value": "sk_test_..." },
  { "op": "replace", "path": "/DB_URL",     "value": "postgres://..." },
  { "op": "remove",  "path": "/OLD_FLAG" }
]

The response contains metadata only (like names and last-updated timestamps). No endpoint returns secret values, including reads. If you need to know what a secret is set to, look it up in whatever system generated it.

Putting it together

The following diagram shows the full iteration loop across variants:

Rendering diagram...

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

For the end-to-end deploy walkthrough, go to Deploy your Node.js app. For endpoints, go to the Hosting API reference.

Scopes reference

Every Hosting API operation requires a specific scope on your Personal Access Token (PAT). Select only the scopes your integration needs. Narrower tokens are easier to reason about when something goes wrong.

Go to Personal Access Tokens to create or update a token.

The following table describes each scope and what it unlocks:

ScopeWhat it unlocks
hosting.application:readRead application details
hosting.application:createCreate new applications
hosting.application:updateUpdate application settings
hosting.application:deleteDelete applications
hosting.deployment:executeTrigger deployments and restarts
hosting.source:readRead source import status
hosting.source:writeUpload or link source code
hosting.secret:readList application secrets
hosting.secret:writeCreate or update application secrets
hosting.log:readRead application logs
hosting.domain:readRead attached domains
hosting.domain:writeAttach or remove domains
hosting.subscription:readRead subscription data
hosting.subscription:writeAttach subscriptions to applications

Last updated on

How is this guide?

On this page