> ## Documentation Index
> Fetch the complete documentation index at: https://internal.september.wtf/llms.txt
> Use this file to discover all available pages before exploring further.

# Lifecycle endpoints

> Provision, start, stop, destroy, and rotate-key for one user's engine.

Five endpoints drive the engine state machine. All require
`X-Platform-Key`. They translate directly to transitions in the
[lifecycle state machine](../../lifecycle).

## POST /engines/provision

Create a new engine for a user.

### Request

```http theme={null}
POST /engines/provision
X-Platform-Key: pk-sept-...
Content-Type: application/json

{
  "user_id": "demo-user-001",
  "engine_version": "september-engine:2.3.0"
}
```

| Field            | Type   | Required | Default             | Purpose                                                             |
| ---------------- | ------ | -------- | ------------------- | ------------------------------------------------------------------- |
| `user_id`        | string | yes      | —                   | Per-product unique user identifier.                                 |
| `engine_version` | string | no       | `ORCH_ENGINE_IMAGE` | Override the default engine image (e.g. for testing a new version). |

### Response (200)

```json theme={null}
{
  "engine_id": "5c2f...",
  "user_id": "demo-user-001",
  "status": "running",
  "url": "http://engine-...:8000",
  "api_key": "sk-sept-..."
}
```

The plaintext `api_key` is returned **once**. Save it.

### Errors

* `409 ENGINE_ALREADY_EXISTS` — there's already an engine for this
  user\_id. Use `/admit` if you want idempotent behavior.
* `429 QUOTA_EXCEEDED` — product at `max_engines` cap.
* `503 PORT_EXHAUSTION` — no free port in the allocator range.
* `504 BOOT_TIMEOUT` — engine didn't become healthy within
  `ORCH_BOOT_TIMEOUT_S`.

## DELETE /engines/{user_id}

Destroy a user's engine. Removes the container, the brain volume, the
port allocation, and the registry row.

### Request

```http theme={null}
DELETE /engines/demo-user-001
X-Platform-Key: pk-sept-...
```

No body.

### Response (200)

```json theme={null}
{
  "status": "destroyed",
  "engine_id": "5c2f..."
}
```

### Errors

* `404 ENGINE_NOT_FOUND` — no engine for this user\_id.

The destroy is **irreversible**. Brain data is gone. Take a backup
first if you need it.

## POST /engines/{user_id}/start

Start a stopped or sleeping engine.

### Request

```http theme={null}
POST /engines/demo-user-001/start
X-Platform-Key: pk-sept-...
```

No body.

### Response (200)

```json theme={null}
{
  "status": "running",
  "url": "http://engine-...:8000"
}
```

### Errors

* `404 ENGINE_NOT_FOUND` — no engine for this user\_id.
* `409 ENGINE_ALREADY_RUNNING` — engine is already running. No-op.

## POST /engines/{user_id}/stop

Stop a running engine. The container is stopped (SIGTERM, 30s grace,
then SIGKILL). Brain volume preserved.

### Request

```http theme={null}
POST /engines/demo-user-001/stop
X-Platform-Key: pk-sept-...
```

No body.

### Response (200)

```json theme={null}
{
  "status": "stopped"
}
```

### Errors

* `404 ENGINE_NOT_FOUND` — no engine for this user\_id.
* `409 ENGINE_NOT_RUNNING` — engine isn't currently running.

## POST /engines/{user_id}/rotate-key

Generate a new engine API key, swap it on the engine, return the new
plaintext.

### Request

```http theme={null}
POST /engines/demo-user-001/rotate-key
X-Platform-Key: pk-sept-...
```

No body.

### Response (200)

```json theme={null}
{
  "new_api_key": "sk-sept-..."
}
```

The old key is invalid immediately. Update your product's cached
key.

### Errors

* `404 ENGINE_NOT_FOUND` — no engine for this user\_id.
* `409 ENGINE_NOT_RUNNING` — can't rotate a non-running engine.

## See also

* [Lifecycle](../../lifecycle) — the state machine these endpoints
  drive.
* [Discovery endpoints](./discovery) — `/admit` for idempotent
  provision.
* [Errors](../errors) — full error catalog.
