# SubVision local API reference

Default base URL: `http://127.0.0.1:17321`. The service is loopback-only by
default and requires no authentication. Errors use:

```json
{"error":"human-readable message"}
```

## Endpoints

### `GET /api/health`

Returns service identity, version, and bundled model availability:

```json
{
  "ok": true,
  "name": "SubVision",
  "version": "0.1.2",
  "models": {"sileroVADCoreML": true}
}
```

### `GET /api/jobs`

Returns in-memory job snapshots for the current service process, newest first.
Jobs do not survive a service restart.

### `POST /api/jobs/path`

Preferred for local videos. The service process must be able to read the path:

```json
{
  "videoPath": "/absolute/path/video.mp4",
  "options": {
    "roi": {"x": 0.10, "y": 0.72, "width": 0.80, "height": 0.16},
    "fps": 3,
    "silenceFps": 0.5,
    "similarityThreshold": 0.006,
    "textSimilarityThreshold": 0.86,
    "minDuration": 0.25,
    "recognitionLevel": "accurate",
    "languages": ["zh-Hans", "zh-Hant", "en-US", "ja-JP", "ko-KR"],
    "maxFrameWidth": 1280,
    "useAudioVAD": true,
    "vadSensitivity": 1.0,
    "speechPaddingBefore": 0.5,
    "speechPaddingAfter": 1.0,
    "vadMergeGap": 0.7
  }
}
```

Returns HTTP 201 and a job snapshot.

| Field | Default | Normalized range |
|---|---:|---|
| `roi` | `{x:0,y:0.62,width:1,height:0.30}` | edges clamped to `0...1`; minimum width/height `0.01` |
| `fps` | `3` | `0.2...12` |
| `silenceFps` | `0.5` | `0.05...3` |
| `similarityThreshold` | `0.006` | `0.0001...0.25` |
| `textSimilarityThreshold` | `0.86` | `0.50...1` |
| `minDuration` | `0.25` | `0...5` seconds |
| `recognitionLevel` | `accurate` | `fast` or `accurate` |
| `languages` | `zh-Hans, zh-Hant, en-US, ja-JP, ko-KR` | non-empty Vision language list |
| `maxFrameWidth` | `1280` | `320...3840` |
| `useAudioVAD` | `true` | boolean |
| `vadSensitivity` | `1.0` | `0.2...3` |
| `speechPaddingBefore` | `0.5` | `0...3` seconds |
| `speechPaddingAfter` | `1.0` | `0...4` seconds |
| `vadMergeGap` | `0.7` | `0...3` seconds |

The Pi tool requires an explicit visually determined ROI even though the raw
service has a broad default.

### `POST /api/jobs/upload`

Accepts multipart form-data with required file part `video`. Optional fields:
`roiX`, `roiY`, `roiWidth`, `roiHeight`, `fps`, `silenceFps`,
`similarityThreshold`, `textSimilarityThreshold`, `minDuration`,
`recognitionLevel`, comma-separated `languages`, `maxFrameWidth`, `useAudioVAD`,
`vadSensitivity`, `speechPaddingBefore`, `speechPaddingAfter`, and
`vadMergeGap`.

The current server buffers the entire multipart body. The Pi package therefore
uses `/api/jobs/path` and does not expose upload as an Agent tool.

### `GET /api/jobs/{id}`

Returns one snapshot. `state` is `queued`, `running`, `completed`, or `failed`;
`progress` is `0...1`. A failed job contains `error`.

### `GET /api/jobs/{id}/srt`

Only available after completion. Returns `application/x-subrip`.

## Exported TypeScript client

`@speclip/pi-subvision` exports `SubVisionClient` plus request/response types.
The client validates loopback addressing and service identity and provides:

- `health()`
- `listJobs()`
- `submitPathJob(videoPath, options)`
- `getJob(jobId)`
- `waitForJob(jobId, options)`
- `downloadSrt(jobId)`
