# Workspace Planner

Source: https://opvs.ai/docs/api/workspace-planner

## `GET` /api/v1/planner/plans

**List Plans**

List workspace plans for the current brand.

**Parameters**

- `status` (query, any, optional) — Filter by plan status
- `skip` (query, integer, optional)
- `limit` (query, integer, optional)
- `format` (query, any, optional) — Response format: yaml or md

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

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans", {
  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/planner/plans", 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/planner/plans

**Create Plan**

Start a new workspace plan. Creates planner board. One active plan per brand.

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "plan_type": "onboarding",
  "parent_plan_id": "string"
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/planner/plans",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"plan_type": "onboarding", "parent_plan_id": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"plan_type": "onboarding", "parent_plan_id": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"plan_type": "onboarding", "parent_plan_id": "string"}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/planner/plans", 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/planner/plans/{plan_id}

**Get Plan**

Get plan state. Agent reads this on session start.

**Parameters**

- `plan_id` (path, string, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}", {
  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/planner/plans/{plan_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

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

## `PATCH` /api/v1/planner/plans/{plan_id}

**Update Plan**

Update plan metadata (status transitions).

**Parameters**

- `plan_id` (path, string, required)

**Request body**

```bash
curl -X PATCH 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "status": "string"
}'
```

```python
import httpx

resp = httpx.patch(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"status": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"status": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"status": "string"}`)
	req, _ := http.NewRequest("PATCH", "https://app.opvs.ai/api/v1/planner/plans/{plan_id}", 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/planner/plans/{plan_id}

**Archive Plan**

Archive a plan (soft delete). Brand admin only.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X DELETE 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}", {
  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/planner/plans/{plan_id}", 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/planner/plans/{plan_id}/context

**Update Context**

Update discovery_context with extracted facts. Agent calls after each exchange.

**Parameters**

- `plan_id` (path, string, required)

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/context' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "business_name": "string",
  "industry": "string",
  "company_size": "string",
  "primary_goals": [
    "string"
  ],
  "target_market": "string",
  "geographic_scope": "string",
  "existing_workflows": [
    "string"
  ],
  "existing_tools": [
    "string"
  ],
  "communication_channels": [
    "string"
  ],
  "team_structure": "string",
  "success_metrics": [
    "string"
  ],
  "budget_constraints": "string",
  "timeline_urgency": "string"
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/context",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"business_name": "string", "industry": "string", "company_size": "string", "primary_goals": ["string"], "target_market": "string", "geographic_scope": "string", "existing_workflows": ["string"], "existing_tools": ["string"], "communication_channels": ["string"], "team_structure": "string", "success_metrics": ["string"], "budget_constraints": "string", "timeline_urgency": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/context", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"business_name": "string", "industry": "string", "company_size": "string", "primary_goals": ["string"], "target_market": "string", "geographic_scope": "string", "existing_workflows": ["string"], "existing_tools": ["string"], "communication_channels": ["string"], "team_structure": "string", "success_metrics": ["string"], "budget_constraints": "string", "timeline_urgency": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"business_name": "string", "industry": "string", "company_size": "string", "primary_goals": ["string"], "target_market": "string", "geographic_scope": "string", "existing_workflows": ["string"], "existing_tools": ["string"], "communication_channels": ["string"], "team_structure": "string", "success_metrics": ["string"], "budget_constraints": "string", "timeline_urgency": "string"}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/context", 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/planner/plans/{plan_id}/progress

**Get Progress**

Get discovery progress checklist.

**Parameters**

- `plan_id` (path, string, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/progress' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/progress", {
  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/planner/plans/{plan_id}/progress", 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/planner/plans/{plan_id}/upload

**Upload Context Doc**

Upload a context document (PDF, DOCX, CSV, text, JSON). Stores as AgentDocs page.

**Parameters**

- `plan_id` (path, string, required)

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "file": "string"
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"file": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"file": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"file": "string"}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload", 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/planner/plans/{plan_id}/upload/{page_id}

**Get Upload Content**

Get the full extracted text of an uploaded document. Used by the planner agent.

**Parameters**

- `plan_id` (path, string, required)
- `page_id` (path, string, required)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload/{page_id}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload/{page_id}", {
  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/planner/plans/{plan_id}/upload/{page_id}", 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/planner/plans/{plan_id}/upload/{page_id}/analyze

**Analyze Upload**

Trigger AI analysis of an uploaded document. Agent calls after upload.

**Parameters**

- `plan_id` (path, string, required)
- `page_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload/{page_id}/analyze' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload/{page_id}/analyze",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload/{page_id}/analyze", {
  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/planner/plans/{plan_id}/upload/{page_id}/analyze", 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/planner/plans/{plan_id}/blueprint/generate

**Generate Blueprint**

Generate a workspace blueprint from discovery context. Agent calls via skill.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint/generate' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint/generate", {
  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/planner/plans/{plan_id}/blueprint/generate", 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/planner/plans/{plan_id}/blueprint

**Get Blueprint**

Get the current blueprint. Agent reads this to present conversationally.

**Parameters**

- `plan_id` (path, string, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint", {
  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/planner/plans/{plan_id}/blueprint", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

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

## `PATCH` /api/v1/planner/plans/{plan_id}/blueprint

**Edit Blueprint**

Apply edits to the blueprint. Creates a new AgentDocs revision.

**Parameters**

- `plan_id` (path, string, required)

**Request body**

```bash
curl -X PATCH 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "changes_description": "string",
  "workstream_edits": {},
  "add_workstreams": [
    {}
  ],
  "remove_workstreams": [
    "string"
  ]
}'
```

```python
import httpx

resp = httpx.patch(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"changes_description": "string", "workstream_edits": {}, "add_workstreams": [{}], "remove_workstreams": ["string"]},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"changes_description": "string", "workstream_edits": {}, "add_workstreams": [{}], "remove_workstreams": ["string"]})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"changes_description": "string", "workstream_edits": {}, "add_workstreams": [{}], "remove_workstreams": ["string"]}`)
	req, _ := http.NewRequest("PATCH", "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint", 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

## `POST` /api/v1/planner/plans/{plan_id}/blueprint/approve

**Approve Blueprint**

Approve the blueprint. Brand admin only. Transitions to approved status.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint/approve' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint/approve", {
  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/planner/plans/{plan_id}/blueprint/approve", 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/planner/plans/{plan_id}/provisioning

**Get Provisioning**

Get provisioning status and log.

**Parameters**

- `plan_id` (path, string, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/provisioning' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/provisioning", {
  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/planner/plans/{plan_id}/provisioning", 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/planner/plans/{plan_id}/provisioning/retry

**Retry Provisioning**

Retry failed provisioning steps. Brand admin only.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/provisioning/retry' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/provisioning/retry", {
  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/planner/plans/{plan_id}/provisioning/retry", 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/planner/plans/{plan_id}/quick-deploy

**Quick Deploy Agent**

Deploy a single agent from a template.

**Parameters**

- `plan_id` (path, string, required)

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/quick-deploy' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "template": "string",
  "agent_name": "string",
  "agent_id": "string",
  "board_name": "string",
  "board_id": "string",
  "placeholders": {}
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/quick-deploy",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"template": "string", "agent_name": "string", "agent_id": "string", "board_name": "string", "board_id": "string", "placeholders": {}},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/quick-deploy", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"template": "string", "agent_name": "string", "agent_id": "string", "board_name": "string", "board_id": "string", "placeholders": {}})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"template": "string", "agent_name": "string", "agent_id": "string", "board_name": "string", "board_id": "string", "placeholders": {}}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/quick-deploy", 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/planner/plans/{plan_id}/resources

**Get Resources**

Get all resources created by provisioning.

**Parameters**

- `plan_id` (path, string, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/resources' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/resources", {
  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/planner/plans/{plan_id}/resources", 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/planner/plans/{plan_id}/audit

**Get Audit**

Get latest audit findings.

**Parameters**

- `plan_id` (path, string, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/audit' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/audit", {
  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/planner/plans/{plan_id}/audit", 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/planner/plans/{plan_id}/audit

**Trigger Audit**

Trigger a workspace health audit. Agent calls this.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/audit' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/audit", {
  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/planner/plans/{plan_id}/audit", 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/planner/plans/{plan_id}/memory/daily-note

**Write Daily Note**

Append to today's daily log via Management API.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/daily-note' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/daily-note",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/daily-note", {
  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/planner/plans/{plan_id}/memory/daily-note", 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/planner/plans/{plan_id}/memory/learning

**Add Learning**

Append a correction rule to LEARNINGS.md via Management API.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/learning' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

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

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/learning", {
  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/planner/plans/{plan_id}/memory/learning", 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/planner/plans/{plan_id}/memory/user-profile

**Save User Profile**

Write/update user profile via Management API.

**Parameters**

- `plan_id` (path, string, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/user-profile' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/user-profile",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/user-profile", {
  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/planner/plans/{plan_id}/memory/user-profile", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

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

## List Plans

`GET https://app.opvs.ai/api/v1/planner/plans`

Also as: MCP `tool_call workspace-planner.listPlans` · skill `workspace-planner`

List workspace plans for the current brand.

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

## Create Plan

`POST https://app.opvs.ai/api/v1/planner/plans`

Also as: MCP `tool_call workspace-planner.createPlan` · skill `workspace-planner`

Start a new workspace plan. Creates planner board. One active plan per brand.

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

## Get Plan

`GET https://app.opvs.ai/api/v1/planner/plans/{plan_id}`

Also as: MCP `tool_call workspace-planner.getPlan` · skill `workspace-planner`

Get plan state. Agent reads this on session start.

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

## Update Plan

`PATCH https://app.opvs.ai/api/v1/planner/plans/{plan_id}`

Also as: MCP `tool_call workspace-planner.updatePlanStatus` · skill `workspace-planner`

Update plan metadata (status transitions).

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

## Archive Plan

`DELETE https://app.opvs.ai/api/v1/planner/plans/{plan_id}`

Also as: MCP `tool_call workspace-planner.archivePlan` · skill `workspace-planner`

Archive a plan (soft delete). Brand admin only.

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

## Update Context

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/context`

Also as: MCP `tool_call workspace-planner.updateDiscoveryContext` · skill `workspace-planner`

Update discovery_context with extracted facts. Agent calls after each exchange.

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

## Get Progress

`GET https://app.opvs.ai/api/v1/planner/plans/{plan_id}/progress`

Also as: MCP `tool_call workspace-planner.getDiscoveryProgress` · skill `workspace-planner`

Get discovery progress checklist.

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

## Upload Context Doc

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload`

Also as: MCP `tool_call workspace-planner.uploadDocument` · skill `workspace-planner`

Upload a context document (PDF, DOCX, CSV, text, JSON). Stores as AgentDocs page.

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

## Get Upload Content

`GET https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload/{page_id}`

Also as: MCP `tool_call workspace-planner.getUploadContent` · skill `workspace-planner`

Get the full extracted text of an uploaded document. Used by the planner agent.

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

## Analyze Upload

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/upload/{page_id}/analyze`

Also as: MCP `tool_call workspace-planner.analyzeUpload` · skill `workspace-planner`

Trigger AI analysis of an uploaded document. Agent calls after upload.

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

## Generate Blueprint

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint/generate`

Also as: MCP `tool_call workspace-planner.generateBlueprint` · skill `workspace-planner`

Generate a workspace blueprint from discovery context. Agent calls via skill.

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

## Get Blueprint

`GET https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint`

Also as: MCP `tool_call workspace-planner.getBlueprint` · skill `workspace-planner`

Get the current blueprint. Agent reads this to present conversationally.

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

## Edit Blueprint

`PATCH https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint`

Also as: MCP `tool_call workspace-planner.editBlueprint` · skill `workspace-planner`

Apply edits to the blueprint. Creates a new AgentDocs revision.

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

## Approve Blueprint

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/blueprint/approve`

Also as: MCP `tool_call workspace-planner.approveBlueprint` · skill `workspace-planner`

Approve the blueprint. Brand admin only. Transitions to approved status.

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

## Get Provisioning

`GET https://app.opvs.ai/api/v1/planner/plans/{plan_id}/provisioning`

Also as: MCP `tool_call workspace-planner.getProvisioning` · skill `workspace-planner`

Get provisioning status and log.

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

## Retry Provisioning

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/provisioning/retry`

Also as: MCP `tool_call workspace-planner.retryProvisioning` · skill `workspace-planner`

Retry failed provisioning steps. Brand admin only.

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

## Quick Deploy Agent

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/quick-deploy`

Also as: MCP `tool_call workspace-planner.quickDeployAgent` · skill `workspace-planner`

Deploy a single agent from a template.

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

## Get Resources

`GET https://app.opvs.ai/api/v1/planner/plans/{plan_id}/resources`

Also as: MCP `tool_call workspace-planner.getResources` · skill `workspace-planner`

Get all resources created by provisioning.

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

## Get Audit

`GET https://app.opvs.ai/api/v1/planner/plans/{plan_id}/audit`

Also as: MCP `tool_call workspace-planner.getAudit` · skill `workspace-planner`

Get latest audit findings.

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

## Trigger Audit

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/audit`

Also as: MCP `tool_call workspace-planner.runAudit` · skill `workspace-planner`

Trigger a workspace health audit. Agent calls this.

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

## Write Daily Note

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/daily-note`

Also as: MCP `tool_call workspace-planner.writeDailyNote` · skill `workspace-planner`

Append to today's daily log via Management API.

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

## Add Learning

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/learning`

Also as: MCP `tool_call workspace-planner.addLearning` · skill `workspace-planner`

Append a correction rule to LEARNINGS.md via Management API.

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

## Save User Profile

`POST https://app.opvs.ai/api/v1/planner/plans/{plan_id}/memory/user-profile`

Also as: MCP `tool_call workspace-planner.saveUserProfile` · skill `workspace-planner`

Write/update user profile via Management API.

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