---
title: "Make one fine-tuned version testable"
method: POST
path: "/v1/projects/{project_id}/preview-deployments"
tags: ["preview-deployments"]
---

# Make one fine-tuned version testable

`POST /v1/projects/{project_id}/preview-deployments`

## Request

- Base URL: `https://api.pioneer.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.pioneer.ai/v1/projects/{project_id}/preview-deployments`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer
- TypeScript: <https://skmtc.dev/pioneer/apis/brain-api/docs/v1/projects/:project_id/preview-deployments/post.ts> (a function with typed inputs; its response is checked against the schema)

Prepare one exact version for testing without changing live routing.

Args:
    project_id: Project the version belongs to.
    request: The exact version to prepare.
    auth: Authenticated caller.

Returns:
    The state to render now: already ready, already in flight, or newly
    provisioning.

## Path parameters

- `project_id` string, uuid, required

## Request body

- PreviewDeploymentRequest: Request body naming the exact version to make testable.
  - `training_job_id` string, uuid, required: UUID of the exact fine-tuned version to prepare. Always a training job, never a project: a preview targets one artifact, not whatever the project currently routes to.

## Response `200`

Successful Response

- PreviewDeploymentResponse: What a caller can currently do with one exact fine-tuned version.
  - `training_job_id` string, required: The exact version this status describes.
  - `state` 'ready' | 'warming' | 'provisioning' | 'inactive' | 'failed' | 'unavailable', required: What a caller can do with an exact fine-tuned version right now.
  - `detail` string, required: Customer-safe explanation of the state.
  - `can_send_requests` boolean, required: Whether an inference request against this version will be answered now. True for ready and warming -- a warming version is routable and the request itself brings the replica up, so the pane should send rather than wait for a state that only a request can advance.
  - `reason` 'project_mismatch' | 'job_deleted' | 'job_incomplete' | 'job_failed' | 'job_cancelled' | 'missing_artifact' | 'provider_incompatible': Why a training job may not be promoted to serve traffic.
  - `retry_after_seconds` integer, nullable: How long to wait before polling again; set only for transient states.
  - `can_activate` boolean, required: Whether this caller may trigger provisioning. False for members without the deploy permission, so the UI shows a truthful unavailable state instead of a button the server would reject.
  - `attempt_count` integer, required: How many activations have been requested for this version.
  - `retry_exhausted` boolean: Whether repeated failures have used up this version's retry budget. When true the state is failed but activation will be refused, so the UI should stop offering a retry and point at the version instead.

## Other responses

- `403`: The caller may not prepare this project's versions.
- `404`: The project or version does not exist.
- `409`: The version's artifact cannot serve requests, or it has failed activation too many times to retry.
- `422`: Validation Error

## Changes

- **2026-09-24** `0e5e86e2bae5`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/pioneer/apis/brain-api/changes/v1/projects/:project_id/preview-deployments/post.md)

---

[API](https://skmtc.dev/pioneer/apis/brain-api.md) - [All operations](https://skmtc.dev/pioneer/apis/brain-api/llms.txt) - [OpenAPI document](https://skmtc.dev/pioneer/apis/brain-api/revisions/0e5e86e2bae5?raw)
