# OpenStrate reconstruction API (headless / API-only)

**Audience:** Autonomous agents (e.g. OpenClaw-style tools), CI jobs, and backends that integrate **without** the browser SPA or WebGL viewer.

**Base URL:** `https://openstrate.com`

**Auth:** The public upload → reconstruct → poll → download flow described here does **not** require an API key. JSON bodies use `Content-Type: application/json`. CORS allows browser calls; agents typically use server-side `curl` or HTTP clients.

---

## Minimal end-to-end flow

1. **Upload** video with `POST /api/upload` (`multipart/form-data`, field `file`). For video, reconstruction starts in the same response; response includes `job_id` when started.
2. **Poll** `GET /api/reconstruct/status/{job_id}` every few seconds until `status` is `complete` or `failed`.
3. **Artifacts:** Use `view_url` from the job when complete, or `GET /api/files/{id}.{ext}` / `GET /view/{id}.{ext}` for download vs interactive viewer page.

**Alternate path:** If the video is already at a **public HTTPS URL** OpenStrate can fetch, skip multipart and call `POST /api/reconstruct` with `{"video_url":"…"}`.

---

## Endpoints

### `POST /api/upload`

- **Content-Type:** `multipart/form-data`
- **Field:** `file` (single file)

**Allowed types (upload):** `.mp4`, `.mov`, `.avi`, `.mkv`, `.webm`. **Max size:** 100 MB (public) / 500 MB (with admin session).

**Response (200)** includes file metadata plus:

- `job_id` — pass to status endpoint (when reconstruction started)
- `reconstruction_started` — boolean
- `reconstruction_error` — if pipeline could not be reached

**Example:**

```bash
curl -X POST https://openstrate.com/api/upload \
  -F "file=@walkthrough.mp4"
```

---

### `POST /api/reconstruct`

- **Body:** `{ "video_url": "https://…", "filename": "optional-label.mp4" }`
- `video_url` must be reachable by OpenStrate’s worker (e.g. a prior `url` from upload).

**Response 200:** `{ "job_id": "…", "status": "processing" }`  
**Response 503:** worker unavailable; body may include `job_id` and `error`.

---

### `GET /api/reconstruct/status/{job_id}`

Returns the job document. Poll while `status` is `pending` or `processing`.

**`status` values:** `pending`, `processing`, `complete`, `failed`

**Useful fields:**

| Field | Meaning |
|--------|---------|
| `status` | Job state |
| `current_frame` / `total_frames` | Progress when reported |
| `view_url` | Viewer link when `complete` |
| `mesh_viewer_url`, `glb_asset_url` | Optional extra links |
| `mission_id`, `relay_base` | Progressive / live viewer flows |
| `error` | Human-readable message when `failed` |

**Example:**

```bash
curl -s "https://openstrate.com/api/reconstruct/status/YOUR_JOB_ID"
```

---

### Artifacts (after job completes or direct mesh upload)

| Operation | Path |
|-----------|------|
| Download file | `GET /api/files/{id}.{ext}` |
| Browser viewer page | `GET /view/{id}.{ext}` |
| Preview image (unfurls) | `GET /api/preview/{id}.{ext}` |

---

### Not for integrators

These are called **by** the reconstruction service, not by end-user agents:

- `POST /api/reconstruct/progress/{job_id}`
- `POST /api/reconstruct/complete/{job_id}`
- `POST /api/reconstruct/session/{job_id}`

---

## HTTP errors (typical)

| Code | Cause |
|------|--------|
| 400 | Missing `file`, invalid type, or missing `video_url` on reconstruct |
| 404 | Unknown `job_id` or file id |
| 503 | Reconstruction worker unreachable |
| 500 | Storage or internal error |

---

## Related URLs

- **OpenAPI 3 spec (YAML, machine-readable):** https://openstrate.com/openstrate-reconstruction-api.openapi.yaml
- **Human-readable docs (HTML):** https://openstrate.com/reconstruction-api/
- **Site index for agents:** https://openstrate.com/llms.txt
- **Live stream ingest (browser-oriented):** https://openstrate.com/streamer
- **Embed / iframe guide:** https://openstrate.com/spatialembedding/

---

*This file is plain Markdown served as `text/markdown` for easy fetching and parsing by tools and agents.*
