# Factory Ratings

Source: https://opvs.ai/docs/api/factory-ratings

## `GET` /api/v1/factory/coder-profiles

**List Coder Profiles**

Return this brand's effective catalog over the platform defaults.

**Parameters**

- `coder` (query, any, optional)
- `task_type` (query, any, optional)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/coder-profiles' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/coder-profiles",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/coder-profiles", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/coder-profiles", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/coder-profiles/{key}

**Get Coder Profile**

Return one effective profile, scoped to the authenticated brand.

**Parameters**

- `key` (path, string, required)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/coder-profiles/{key}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/coder-profiles/{key}", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/capabilities

**Get Workspace Capabilities**

Return the authenticated brand's resolved workspace default.

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/capabilities' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/capabilities",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/capabilities", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/capabilities", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response

## `PUT` /api/v1/factory/capabilities

**Put Workspace Capabilities**

Replace the authenticated brand's workspace capability default.

**Request body**

```bash
curl -X PUT 'https://app.opvs.ai/api/v1/factory/capabilities' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "version": 1,
  "web_search": false,
  "web_fetch": false,
  "browser": false,
  "network_install": false,
  "mcp_servers": [
    {
      "name": "string",
      "transport": "url",
      "command": "string",
      "url": "string",
      "integration_id": 0,
      "login_env": {}
    }
  ],
  "clis": [
    {
      "name": "string",
      "install": "string",
      "check_command": "string",
      "integration_id": 0,
      "login_env": {}
    }
  ],
  "skills": false,
  "media": {
    "images": [
      "string"
    ],
    "video": [
      "string"
    ]
  },
  "scratch_folder": false,
  "output_type": "pr",
  "wall_minutes": 120
}'
```

```python
import httpx

resp = httpx.put(
    "https://app.opvs.ai/api/v1/factory/capabilities",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"version": 1, "web_search": false, "web_fetch": false, "browser": false, "network_install": false, "mcp_servers": [{"name": "string", "transport": "url", "command": "string", "url": "string", "integration_id": 0, "login_env": {}}], "clis": [{"name": "string", "install": "string", "check_command": "string", "integration_id": 0, "login_env": {}}], "skills": false, "media": {"images": ["string"], "video": ["string"]}, "scratch_folder": false, "output_type": "pr", "wall_minutes": 120},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/capabilities", {
  method: "PUT",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"version": 1, "web_search": false, "web_fetch": false, "browser": false, "network_install": false, "mcp_servers": [{"name": "string", "transport": "url", "command": "string", "url": "string", "integration_id": 0, "login_env": {}}], "clis": [{"name": "string", "install": "string", "check_command": "string", "integration_id": 0, "login_env": {}}], "skills": false, "media": {"images": ["string"], "video": ["string"]}, "scratch_folder": false, "output_type": "pr", "wall_minutes": 120})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"version": 1, "web_search": false, "web_fetch": false, "browser": false, "network_install": false, "mcp_servers": [{"name": "string", "transport": "url", "command": "string", "url": "string", "integration_id": 0, "login_env": {}}], "clis": [{"name": "string", "install": "string", "check_command": "string", "integration_id": 0, "login_env": {}}], "skills": false, "media": {"images": ["string"], "video": ["string"]}, "scratch_folder": false, "output_type": "pr", "wall_minutes": 120}`)
	req, _ := http.NewRequest("PUT", "https://app.opvs.ai/api/v1/factory/capabilities", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/capabilities/history

**Get Workspace Capability History**

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/capabilities/history' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/capabilities/history",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/capabilities/history", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/capabilities/history", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response

## `GET` /api/v1/factory/coder-profiles/{key}/history

**Get Coder Profile History**

Return this brand's override changes, newest first.

**Parameters**

- `key` (path, string, required)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/history' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/history",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/history", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/history", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/coder-profiles/{key}/capabilities/history

**Get Coder Profile Capability History**

**Parameters**

- `key` (path, string, required)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/capabilities/history' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/capabilities/history",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/capabilities/history", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/capabilities/history", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `PUT` /api/v1/factory/coder-profiles/{key}/override

**Put Coder Profile Override**

Set one or more bounded override fields for the authenticated brand.

**Parameters**

- `key` (path, string, required)

**Request body**

```bash
curl -X PUT 'https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": null,
  "effort": null,
  "limit_value": null,
  "capabilities": null
}'
```

```python
import httpx

resp = httpx.put(
    "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"model": null, "effort": null, "limit_value": null, "capabilities": null},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override", {
  method: "PUT",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"model": null, "effort": null, "limit_value": null, "capabilities": null})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"model": null, "effort": null, "limit_value": null, "capabilities": null}`)
	req, _ := http.NewRequest("PUT", "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `DELETE` /api/v1/factory/coder-profiles/{key}/override/{field}

**Delete Coder Profile Override Field**

Reset one brand override field to its current platform default.

**Parameters**

- `key` (path, string, required)
- `field` (path, string, required)

```bash
curl -X DELETE 'https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override/{field}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.delete(
    "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override/{field}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override/{field}", {
  method: "DELETE",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override/{field}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/runs

**List Runs**

Raw run history for the brand (audit / drill-down), most recent first.

**Parameters**

- `task_id` (query, any, optional) — Filter to one card's runs (per-task drill-down)
- `task_type` (query, any, optional)
- `requested_model` (query, any, optional)
- `limit` (query, integer, optional)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/runs' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/runs",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/runs", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/runs", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/factory/runs

**Report Run**

Record a finished factory run + recompute its model's rating.

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/factory/runs' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "task_id": "string",
  "runtime": "claude_code",
  "requested_model": "string",
  "task_type": "string",
  "outcome": "passed",
  "board_id": "string",
  "agent_id": "string",
  "actual_model": "string",
  "gate_passed": true,
  "gate_exit_code": 0,
  "gate_duration_ms": 0,
  "turns": 0,
  "cost_usd": 0.0,
  "input_tokens": 0,
  "output_tokens": 0,
  "session_id": "string",
  "harness_session_id": "string",
  "cost_source": "worker",
  "error": "string",
  "first_failed_test": "string"
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/factory/runs",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"task_id": "string", "runtime": "claude_code", "requested_model": "string", "task_type": "string", "outcome": "passed", "board_id": "string", "agent_id": "string", "actual_model": "string", "gate_passed": true, "gate_exit_code": 0, "gate_duration_ms": 0, "turns": 0, "cost_usd": 0.0, "input_tokens": 0, "output_tokens": 0, "session_id": "string", "harness_session_id": "string", "cost_source": "worker", "error": "string", "first_failed_test": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/runs", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"task_id": "string", "runtime": "claude_code", "requested_model": "string", "task_type": "string", "outcome": "passed", "board_id": "string", "agent_id": "string", "actual_model": "string", "gate_passed": true, "gate_exit_code": 0, "gate_duration_ms": 0, "turns": 0, "cost_usd": 0.0, "input_tokens": 0, "output_tokens": 0, "session_id": "string", "harness_session_id": "string", "cost_source": "worker", "error": "string", "first_failed_test": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"task_id": "string", "runtime": "claude_code", "requested_model": "string", "task_type": "string", "outcome": "passed", "board_id": "string", "agent_id": "string", "actual_model": "string", "gate_passed": true, "gate_exit_code": 0, "gate_duration_ms": 0, "turns": 0, "cost_usd": 0.0, "input_tokens": 0, "output_tokens": 0, "session_id": "string", "harness_session_id": "string", "cost_source": "worker", "error": "string", "first_failed_test": "string"}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/factory/runs", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `201` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/ratings

**Get Ratings**

The Planner's read: models for ``task_type`` ranked best-under-budget.

**Parameters**

- `task_type` (query, string, required) — The kind of work, e.g. 'coding'
- `max_cost_usd` (query, any, optional) — Cap on a model's avg cost per run
- `min_runs` (query, integer, optional) — Drop models with fewer than this many runs (too little history)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/ratings' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/ratings",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/ratings", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/ratings", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/ratings/causes

**Get Failure Causes**

Recent per-model failures; only model-owned causes affect pass rate.

**Parameters**

- `days` (query, integer, optional)
- `format` (query, any, optional)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/ratings/causes' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/ratings/causes",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/ratings/causes", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/ratings/causes", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/role-ratings

**Get Role Ratings**

The employee face's read: the brand's builder roles ranked by track record.

**Parameters**

- `builder_hire_id` (query, any, optional) — Narrow to one builder role's rating (else all the brand's)
- `min_runs` (query, integer, optional) — Drop roles with fewer than this many runs (too little history)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/role-ratings' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/role-ratings",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/role-ratings", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/role-ratings", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/route

**Route Card**

The capstone (RU.1): pick a CONCRETE model for a card from the ledger.

**Parameters**

- `task_type` (query, string, required) — The kind of work, e.g. 'coding'
- `max_cost_usd` (query, any, optional) — Budget cap on the chosen model's avg cost per run
- `runtime` (query, string, optional) — Runtime to stamp on the card (openhands | claude_code | …)
- `provider` (query, any, optional) — The card's own credential-lane field (e.g. 'anthropic-claude-code', 'openai-codex') — None/absent means a completion (PROXY) lane

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/route' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/route",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/route", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/route", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/factory/reconcile

**Reconcile**

Re-price worker-reported ($0) factory runs from SpiderGate's ledger.

**Parameters**

- `dry_run` (query, boolean, optional) — Preview the flip without writing (counts only)
- `client_id` (query, any, optional) — SpiderGate client/brand id for the usage read
- `from` (query, any, optional)
- `to` (query, any, optional)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/factory/reconcile' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/factory/reconcile",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/reconcile", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/factory/reconcile", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/factory/budget

**Get Budget**

The A6 budget panel's spend + build-count read for the brand.

**Parameters**

- `window` (query, string, optional) — Spend window: day | month

```bash
curl -X GET 'https://app.opvs.ai/api/v1/factory/budget' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/factory/budget",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/factory/budget", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/factory/budget", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## List Coder Profiles

`GET https://app.opvs.ai/api/v1/factory/coder-profiles`

Also as: MCP `tool_call software-factory.listCoderProfiles` · skill `software-factory`

Return this brand's effective catalog over the platform defaults.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Coder Profile

`GET https://app.opvs.ai/api/v1/factory/coder-profiles/{key}`

Also as: MCP `tool_call software-factory.getCoderProfile` · skill `software-factory`

Return one effective profile, scoped to the authenticated brand.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Workspace Capabilities

`GET https://app.opvs.ai/api/v1/factory/capabilities`

Also as: MCP `tool_call software-factory.getFactoryCapabilities` · skill `software-factory`

Return the authenticated brand's resolved workspace default.

## Put Workspace Capabilities

`PUT https://app.opvs.ai/api/v1/factory/capabilities`

Also as: MCP `tool_call software-factory.setFactoryCapabilities` · skill `software-factory`

Replace the authenticated brand's workspace capability default.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Workspace Capability History

`GET https://app.opvs.ai/api/v1/factory/capabilities/history`

Also as: MCP `tool_call software-factory.getFactoryCapabilityHistory` · skill `software-factory`

## Get Coder Profile History

`GET https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/history`

Also as: MCP `tool_call software-factory.getCoderProfileHistory` · skill `software-factory`

Return this brand's override changes, newest first.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Coder Profile Capability History

`GET https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/capabilities/history`

Also as: MCP `tool_call software-factory.getCoderProfileCapabilityHistory` · skill `software-factory`

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Put Coder Profile Override

`PUT https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override`

Also as: MCP `tool_call software-factory.setCoderProfileOverride` · skill `software-factory`

Set one or more bounded override fields for the authenticated brand.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Delete Coder Profile Override Field

`DELETE https://app.opvs.ai/api/v1/factory/coder-profiles/{key}/override/{field}`

Also as: MCP `tool_call software-factory.deleteCoderProfileOverrideField` · skill `software-factory`

Reset one brand override field to its current platform default.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## List Runs

`GET https://app.opvs.ai/api/v1/factory/runs`

Also as: MCP `tool_call software-factory.listRuns` · skill `software-factory`

Raw run history for the brand (audit / drill-down), most recent first.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Report Run

`POST https://app.opvs.ai/api/v1/factory/runs`

Also as: MCP `tool_call software-factory.reportRun` · skill `software-factory`

Record a finished factory run + recompute its model's rating.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Ratings

`GET https://app.opvs.ai/api/v1/factory/ratings`

Also as: MCP `tool_call software-factory.getRatings` · skill `software-factory`

The Planner's read: models for ``task_type`` ranked best-under-budget.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Failure Causes

`GET https://app.opvs.ai/api/v1/factory/ratings/causes`

Also as: MCP `tool_call software-factory.getFailureCauses` · skill `software-factory`

Recent per-model failures; only model-owned causes affect pass rate.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Role Ratings

`GET https://app.opvs.ai/api/v1/factory/role-ratings`

Also as: MCP `tool_call software-factory.getRoleRatings` · skill `software-factory`

The employee face's read: the brand's builder roles ranked by track record.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Route Card

`GET https://app.opvs.ai/api/v1/factory/route`

Also as: MCP `tool_call software-factory.routeCard` · skill `software-factory`

The capstone (RU.1): pick a CONCRETE model for a card from the ledger.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Reconcile

`POST https://app.opvs.ai/api/v1/factory/reconcile`

Also as: MCP `tool_call software-factory.reconcileFactoryRuns` · skill `software-factory`

Re-price worker-reported ($0) factory runs from SpiderGate's ledger.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Budget

`GET https://app.opvs.ai/api/v1/factory/budget`

Also as: MCP `tool_call software-factory.getFactoryBudget` · skill `software-factory`

The A6 budget panel's spend + build-count read for the brand.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |
