---
title: "Lifecycle and reliability"
description: "Control idle workspaces, retain immutable source, and recover uncertain API requests."
canonical_url: "https://hoplite.sh/docs/platform/operations"
markdown_url: "https://hoplite.sh/docs/platform/operations.md"
---

# Lifecycle and reliability
URL: /docs/platform/operations
LLM index: /llms.txt
Description: Control idle workspaces, retain immutable source, and recover uncertain API requests.

# Lifecycle and reliability

Source versions outlive sandboxes. A completed run has a durable source result; terminating an idle runtime does not discard that version. Reopening restores files into a new runtime. Installed dependencies, running processes, and local Git history are not part of the source bundle. An app's [sandbox image](/docs/platform#sandbox-images) can supply preinstalled dependencies to every new or restored runtime.

## Set an editor’s idle deadline

Call `POST /api/platform/v1/apps/{appId}/threads/{threadId}/workspace/activity` with `{"idleTimeoutMinutes":20}` when a user starts or continues editing. The timeout accepts 1–60 minutes. Omit `idleTimeoutMinutes` to use the app’s `idleTimeoutMinutes`, or 20 minutes when the app sets none. Repeat with a new idempotency key for new activity; replaying an old key does not renew the deadline.

Read `/workspace/policy` for the saved policy, expiry and `workspaceStatus`. Wait for `archived` to verify that the idle policy took effect. A null policy means the organization’s default idle policy applies. Completing an edit starts a fresh idle interval, and so does starting a preview with `POST …/preview/start`, which keeps the saved timeout. Background preview polling does not extend it.

The worker checks the persisted deadline and archives after active work drains. It saves source before terminating the runtime. Storage or provider failures can delay termination; they must not cause unsaved work to be discarded. Send activity from your authenticated backend, based on actual user interaction rather than an unattended timer.

## Source limits and retention

A bundle can contain up to 10,000 files, 8 MiB per decoded file, and 32 MiB of decoded contents in total. The JSON request limit is 64 MiB. Files may use UTF-8 or canonical padded base64. Executable files retain mode `0755`; others restore as `0644`.

Paths must be relative, unique ignoring case, and free of traversal. `.git`, `.context`, and `.hoplite` are reserved. Symlinks and non-regular files cannot be saved. Keep large media assets in your own object storage and include their approved references in the source.

Saved sources, builds, and registered upload objects are retained while the app exists. Deleting a thread does not delete its source history. Deleting the app removes its source/build metadata and durably queues deletion of the corresponding object-storage keys, including interrupted registered uploads. Cleanup starts after a one-hour grace period for in-flight transfers and retries failed deletions. This is asynchronous cleanup, not immediate erasure.

## Retry without duplicating work

Every service-credential write needs an `Idempotency-Key`. Use a new key for a new operation and preserve it across network retries. Changing the payload under the same key returns a conflict. For an uncertain receipt, inspect `GET /api/operations/{operationId}` before starting another operation.

Missing source storage returns `source_storage_unavailable`; missing execution configuration returns `source_workspace_unavailable`. New work fails admission when a required dependency is unavailable. A failed editing run leaves the last successful result unchanged. If a runtime disappears unexpectedly, recovery uses the last saved source; unsaved changes can be lost.

Build commands are not automatically rerun after an uncertain worker failure, because the first command may still be executing. Admission stays locked until that execution can no longer be live, then the build fails and can be resubmitted.

## Rate limits

Each service credential has its own quota of 600 requests per 60-second window, counted across every Platform and Direct route it calls. Credentials do not share a quota, including the old and new credential during a rotation.

Responses report the quota in the `RateLimit`, `RateLimit-Policy`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers. A request over the limit is not processed and answers `429`:

```json
{ "ok": false, "error": "rate_limited" }
```

with a `Retry-After` header: the number of seconds until the window resets. Wait that long, then retry; a write keeps its original `Idempotency-Key`. If requests keep answering `429`, lower your request rate instead of retrying in a loop.

Polling is the usual cause. Each status read for a run, apply, build, or preview counts as a request, while an open event stream counts as one. Follow the [event feed](/docs/platform/events) and read a resource when its event arrives, rather than polling every resource on a short interval. [Authentication](/docs/api/authentication#rate-limits) describes each header.

## Progress, cancellation, and cost

Read the conversation with `GET /api/platform/v1/apps/{appId}/threads/{threadId}/messages`, and use the app's [event feed](/docs/platform/events) for live progress. Persist your event cursor and use replay after reconnecting. Apps publish `platform.app.created`, `platform.app.updated`, `platform.app.deleted`, `platform.source.imported`, `platform.apply.<status>`, `platform.build.<status>`, and `platform.head.updated`; the [app event types](/docs/platform/events#app-events) list their fields. Events identify the change; build/apply status endpoints remain the authority for those operations.

Stop an agent run through the [Direct API stop operation](/docs/api/stopRun). Repair runs use the same control and incur ordinary agent charges. Read [thread usage](/docs/api/getThreadUsage) and enforce the thread’s lifetime spend limit for editing and repairs. A browser disconnect is not a cancellation request.

Keep your organization membership checks in your backend. Scope Hoplite credentials to the required apps and permissions, and handle 403/404 responses without exposing whether another tenant’s source exists.

## Sitemap

Sitemap discovery is not enabled for this deployment.
