Docs

Updates and connection

After initial setup, your deployment card stays on the page for the life of the deployment. Two states need care: a release that waits for the customer's admin, and a deployment that stopped reporting. Both apply when you launch the portal from your product with a Deploy button, and when you build it into your product with your own setup screen.

Example UI /Update needs the admin

Document processing

Settings · Deploy in your cloud

Action needed

Version 13 needs your AWS admin

Version 12 keeps running. Version 13 adds a permission, so an admin must update the setup in AWS.

Review the setup changeSend to an admin

A permanent green badge hides failed updates and lost connections. Keep a compact card instead:

  • The release, the size, the endpoint, and "Last report" from lastHeartbeatAt.
  • Your own Active flag, from Verify and activate.
  • The last confirmed state with its time, instead of a guess.

Updates that need the admin

A release that adds a permission or a frozen resource can't apply on its own: only the admin's initial setup can create those. The deployment stays running on the old release, and updateState.active explains why. The example at the top of this page shows this state.

Show it when updateState.active.status is blocked. blocker.kind says why: setup, input, or other.

  • Still running. The deployment stays running on the old release. A page that reads only status hides the wait.
  • Retry doesn't help. Only the admin rerunning initial setup, or the missing input, moves the update.
  • Missing input. For blocker.kind: "input", name the input from blocker.inputId and ask for its value.
  • Hold other changes. Disable size changes until the blocker clears, and say why.
  • Name both releases. "Version 12 keeps running. Version 13 needs your AWS admin."
GET /v1/deployments/{id}
{
  "status": "running",
  "updateState": {
    "active": {
      "id": "duop_1x8kq2m4n6p8r0t2v4w6y8z0ab",
      "status": "blocked",
      "reasons": ["release"],
      "targetReleaseId": "rel_13…",
      "blocker": { "kind": "setup", "message": "Permission profile \"application\" was modified." },
      "actionRequired": "Apply the updated setup to continue this update.",
      "requestedAt": "2026-01-21T08:30:00Z"
    },
    "next": null,
    "latest": null
  }
}
FieldMeaning
statusblocked, queued, applying, succeeded, failed, or superseded
blocker.kindsetup: the admin must rerun initial setup. input: a value is missing (blocker.inputId). other: read blocker.message.
blocker.messageWhat changed, for the admin
actionRequiredThe next step, written for people
targetReleaseIdThe release waiting to apply

Review the setup change sends the admin to the deployment portal with a setup link, where Continue update shows the steps for their setup method.

Not reporting

lastHeartbeatAt is the last time the deployment reported. The service keeps running when it loses its connection to Alien, so a late report doesn't prove an outage.

Example UI /Not reporting

Document processing

Settings · Deploy in your cloud

Not reporting

We can’t confirm the current state

The service last reported 25 minutes ago. It may still be running.

Last confirmed
Running version 12 at 09:21
Last report
25 minutes ago
Check nowContact support

Show it when lastHeartbeatAt is older than your threshold, such as 10 minutes.

  • Not an outage. A stale heartbeat means Alien can't see the deployment. The service may still serve requests.
  • Last confirmed state. Show what you last knew with its time: "Running version 12 at 09:21."
  • No traffic switch. Don't move traffic away on a stale heartbeat alone. Use your own health check for that.
  • Heartbeats off. With stackSettings.heartbeats: "off", the customer turned health checks off. Don't show a stale heartbeat as a warning.
GET /v1/deployments/{id}
{
  "status": "running",
  "lastHeartbeatAt": "2026-01-15T09:21:03Z",
  "stackSettings": { "heartbeats": "on" }
}

Pick a threshold, such as 10 minutes, and use it for a "Last report" line:

lib/connection.ts
const STALE_AFTER_MS = 10 * 60 * 1000

export function connection(lastHeartbeatAt: Date | null) {
  if (!lastHeartbeatAt) return { label: "Not connected yet" }
  const age = Date.now() - lastHeartbeatAt.getTime()
  if (age > STALE_AFTER_MS) return { label: "Not reporting", lastHeartbeatAt }
  return { label: "Connected", lastHeartbeatAt }
}

Test it

  • Block an update. Release a version that adds a permission, and check your page says the admin must act while the old version keeps serving.
  • Stop the heartbeat clock. Set lastHeartbeatAt 25 minutes back in a test response. The page says Not reporting, not Down.
  • Heartbeats off. Set stackSettings.heartbeats to off, and confirm the page shows no warning.

Next

On this page