---
title: "Retire Endpoint"
method: POST
path: "/endpoints/{endpoint_id}/retire"
tags: ["endpoints"]
---

# Retire Endpoint

`POST /endpoints/{endpoint_id}/retire`

## Request

- Base URL: `https://api.os3robotics.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.os3robotics.com/endpoints/{endpoint_id}/retire`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

desired -> retired; provisioning/warming/healthy -> draining (the driver tears the
replica down and retires it); already draining or retired: unchanged, 200. A replica of a
desired endpoint, a retired one too, stops that desired endpoint and moves each of its
replicas so.

## Path parameters

- `endpoint_id` string, uuid, required

## Response `200`

Successful Response

- Endpoint
  - `id` string, uuid, required
  - `tenant_id` string, uuid, required
  - `workspace_id` string, uuid, required
  - `name` string, required
  - `endpoint_type` 'vla_policy' | 'planner_llm' | 'harness' | 'llm_vllm' | 'llm_sglang', required
  - `model_version_id` string, uuid, nullable, required
  - `expect` union, required
    - HandshakeExpectation: What the connecting controller requires. Defaults are the wire contract (fail closed).
      - `checkpoint_sha256` string, required
      - `action_space_id` string
      - `action_dim` integer
      - `wire_contract_version` string
      - `camera_shapes` object, required
      - `controller_api_version` string, required
      - `endpoint_type` 'vla_policy' | 'planner_llm' | 'harness' | 'llm_vllm' | 'llm_sglang'
      - `observation` ObservationSchema
        - `schema_version` 'os3.observation_schema.v1', required
        - `modalities` object, required
      - `action_adapter` ActionAdapter
        - `schema_version` 'os3.action_adapter.v1', required
        - `action_space_id` string, required
        - `names` string[], required
        - `units` string[], required
        - `relative_channels` integer[]
        - `relative_to` string, nullable
    - LlmExpectation: An LLM endpoint's `expect`: a base of the lora_trl catalog (the bases adapters are trained on), with that catalog entry's repo and revision, so no endpoint names other weights. `serving` (llm_vllm only): the engine's serving configuration, the one an eval job's variant on its upstream names; left out of the JSON when unset. Its MTP drafter is the base's own. `reasoning` (llm_vllm only, a base with a reasoning mode): the engine serves the base with thinking on and returns the thinking apart from the answer; unset, final answers only.
      - `endpoint_type` 'llm_vllm' | 'llm_sglang', required
      - `base` string, required
      - `repo` string, required
      - `revision` string, required
      - `digest` string, nullable
      - `serving` ServingConfig: How an llm_vllm endpoint's engine serves its base and the adapters it loads, beyond the base's own serving: vLLM v0.30.0's online FP8 quantization of the base's linear weights at load time (`--quantization`; H100s run both schemes as W8A8; the adapters stay bf16), an FP8 KV cache (`--kv-cache-dtype`), speculative decoding (n-gram, the base's MTP drafter at another depth, or none; each replaces the drafter a base serves with by default), the batch size (`--max-num-seqs`, else the base's), the LoRA slots (`--max-loras`, at most the base's: fewer slots decode faster, while a batch holding more adapters than slots defers the rest), a step's token budget (`--max-num-batched-tokens`: 512, 1,024 or 2,048) and the requests the engine runs at once (`--max-num-active-seqs`, at most the batch size). Unset fields are the engine's defaults and are left out of the configuration's JSON. It sets at least one field: the default serving is no configuration.
        - `quantization` 'fp8_per_tensor' | 'fp8_per_block', nullable
        - `kv_cache_dtype` 'fp8', nullable
        - `speculative` union
          - NgramSpeculation: vLLM's n-gram speculative decoding (prompt lookup, `--speculative-config`): drafts are the tokens that followed the last `prompt_lookup_max`..`prompt_lookup_min` tokens earlier in the request, so no draft model is loaded, and it works with any base and with LoRA (vLLM v0.30.0; unset `prompt_lookup_min`: the engine's, `prompt_lookup_max`).
            - `method` 'ngram'
            - `num_speculative_tokens` integer, required
            - `prompt_lookup_max` integer, required
            - `prompt_lookup_min` integer, nullable
          - MtpSpeculation: vLLM's MTP speculative decoding (`--speculative-config`) with the base's own drafter (Gemma 4's assistant model), which drafts from the base's hidden states, so it drafts for every adapter too. `model` at `revision` is that drafter, and no other is accepted; the replica downloads it from the Hub as it does the base.
            - `method` 'mtp', required
            - `model` string, required
            - `revision` string, required
            - `num_speculative_tokens` integer, required
          - NoSpeculation: No speculative decoding, where the base drafts with its own drafter by default; refused for a base without one (its default serving already drafts nothing).
            - `method` 'off', required
        - `max_num_seqs` integer, nullable
        - `max_loras` integer, nullable
        - `max_num_batched_tokens` 512 | 1024 | 2048, nullable
        - `max_num_active_seqs` integer, nullable
      - `reasoning` boolean
  - `desired_replicas` integer, required
  - `state` 'desired' | 'provisioning' | 'warming' | 'healthy' | 'draining' | 'retired', required
  - `reason` string, nullable, required
  - `tailscale_tag` string, required
  - `api_key_ref` string, required
  - `tls_required` boolean, required
  - `max_size` integer, required
  - `url` string, nullable, required
  - `last_handshake` object, nullable, required
  - `health` object, nullable, required
  - `launch_request` string, nullable
  - `box` string, nullable
  - `box_slot` integer, nullable
  - `dedicated_pool` string, nullable
  - `dedicated_slot` integer, nullable
  - `pool` string, nullable
  - `pool_slot` integer, nullable
  - `desired_endpoint_id` string, uuid, nullable
  - `desired_state` 'running' | 'stopped', nullable
  - `desired_name` string, nullable
  - `last_good` boolean
  - `gpu` string, nullable
  - `released_adapters` integer, nullable
  - `released_loaded` integer, nullable
  - `failure` EndpointFailure: Why a replica the driver refused stopped (driver._refuse): its `refused` event's reason code, message and detail (what did not match, how long it waited; never a secret's value), and when. The API reads it for a draining or retired row whose reason is that code, so a replica retired on request, scaled to zero or superseded has none.
    - `reason` string, required
    - `message` string, required
    - `detail` string[], required
    - `at` string, date-time, required
  - `operator_note` EndpointNote: OS3's latest words to the endpoint's owner about its failure: what OS3 found and does about it, and when.
    - `message` string, required
    - `at` string, date-time, required
  - `created_at` string, date-time, required
  - `state_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/os3robotics/apis/os3-api.md) - [All operations](https://skmtc.dev/os3robotics/apis/os3-api/llms.txt) - [OpenAPI document](https://skmtc.dev/os3robotics/apis/os3-api/revisions/af32cd4f14bb?raw)
