# Initiate

Start an Orbit Auto Migration on one or more topics

```
POST /api/v1/initiate_orbit_topic_auto_migration
```

Selects topics by literal name, by regex, or both, and initiates the cutover for each. Requires an **admin** (or **app** / **agent**) API key scoped to the target virtual cluster.

Per-topic validation failures are returned in the `errors` array with a `200`, not as a non-2xx. A non-2xx is returned only for request-level rejections (authentication, a malformed `virtual_cluster_id`, the feature gate, or a request-wide guardrail such as the selector limit).

### Request

| Parameter                   | Type      | Required                                    | Default      | Description                                                                                                                                                                                                                                                                                                                 |
| --------------------------- | --------- | ------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `virtual_cluster_id`        | string    | Yes                                         | —            | Target virtual cluster, e.g. `vci_...`. Must be a well-formed VCID.                                                                                                                                                                                                                                                         |
| `topic_names`               | string\[] | One of `topic_names` / `topic_name_regexes` | —            | Literal topic names to select. Entries must be non-empty.                                                                                                                                                                                                                                                                   |
| `topic_name_regexes`        | string\[] | One of `topic_names` / `topic_name_regexes` | —            | Regex topic names to select.                                                                                                                                                                                                                                                                                                |
| `dry_run`                   | bool      | No                                          | `false`      | Run selector expansion and per-topic validation but skip actual initiation. Response shape is identical to a real run— use it to preview which topics would be initiated.                                                                                                                                                   |
| `limit`                     | int       | No                                          | `100`        | Upper bound on the number of distinct topics the selectors may resolve to. If the deduplicated set exceeds it, the **entire** request is rejected with `400 selector_match_limit_exceeded` (a guardrail against a typo'd regex matching thousands of topics). Must be `0`–`1000`; `0` (or omitted) uses the default of 100. |
| `max_time_lag_seconds`      | int       | No                                          | `180` (3m)   | Per-topic time-lag ceiling, in seconds, at the moment of initiation. **Mutually exclusive** with `max_offset_lag`. Must be ≥ 0. Used by default when both lag fields are unset; time lag is the better estimate of how long a topic will take to drain once produces are blocked.                                           |
| `max_offset_lag`            | int       | No                                          | `0` (unused) | Per-topic offset-lag ceiling at the moment of initiation; topics above it are reported in `errors` and not initiated. **Mutually exclusive** with `max_time_lag_seconds`. Must be ≥ 0. Prefer `max_time_lag_seconds` unless you have a specific reason not to.                                                              |
| `migration_timeout_seconds` | int       | No                                          | `300` (5m)   | Maximum seconds a topic may remain in `MIGRATING` before the scheduler rolls it back to `PROXY`.                                                                                                                                                                                                                            |

> Set **at most one** of `max_time_lag_seconds` and `max_offset_lag` — supplying both positive values is rejected with `400 conflicting_lag_thresholds`. We recommend using `max_time_lag_seconds`.

#### Example

```bash
curl -X POST https://api.warpstream.com/api/v1/initiate_orbit_topic_auto_migration \
  -H "Authorization: Bearer <api-key>" -H "Content-Type: application/json" \
  -d '{
    "virtual_cluster_id": "vci_...",
    "topic_name_regexes": ["^orders-.*"],
    "max_time_lag_seconds": 120,
    "migration_timeout_seconds": 600,
    "dry_run": true
  }'
```

### Response

`initiated` lists the topics whose cutover was initiated (or would have been, under `dry_run`). `errors` lists topics that were considered but not initiated, each with a human-readable `reason`.

```json
{
  "initiated": ["orders-eu", "orders-us"],
  "errors": [
    { "topic_name": "orders-archive", "reason": "offset lag above threshold" }
  ]
}
```