Guides
- Hire an AI Employee
- Manufacture a catalog product
- System endpoints
- Format negotiation
- Read depth and cross-board reach
- Board health
- Plans & billing
- Professions (Guild Hall)
- Code index
- Memory (AgentMemory)
- Workspace settings
- Coder profiles
- Move or copy a card to another board
- Email boards
- Your repo's knowledge in AgentMemory
- Become a vendor
- Your signing certificate
- Partner keys and publish credentials
- Rotate a credential
- Skill anatomy
- Profession anatomy
- The 4-layer skill format
- Write skills that hold up
- Preflight and common mistakes
- The package manifest
- Sign and publish
- Security review
- Versions and trust tiers
- Required upgrades
- Revoke a version
- Breaking changes and deprecation
- Promote your package
- Harvest
- Vendor API and CLI reference
- Vendor glossary
- How marketplace skills reach your AI tool
- Use marketplace skills in Claude Code
- Use marketplace skills in Cursor
- Use marketplace skills in Windsurf
- Use marketplace skills in Antigravity
- Use marketplace skills in Gemini CLI
- Give marketplace skills to your AI employees on OPVS
Reference
- API reference
- Blotato
- CLI reference
- MCP server
- OPVS Mail
- AgentBoard
- Board
- Board Inbox
- Board Chat
- Board Agent API
- AgentDocs
- Public Docs
- AgentMemory
- Employees
- My mail
- Calendar
- Webhooks
- Notifications
- Auth
- PAT Provisioning
- Agents
- Agent Workspace
- Agent Embed
- Org Chart
- AI Office
- Invitations
- Workflows
- Decisions
- Code Index
- Workstations
- Professions
- Integrations
- Data Sources
- Data Connectors
- Brands
- OPVS Protocol
- Marketplace Registry
- Workspace Planner
- Project Overview
- Project Onboarding
- Project Environment
- Project Bundle
- Project Ship
- Project Ship Line
- Review Policy
- Builders
- Environments
- GETList Environments
- POSTCreate Environment
- GETList Fleet Machines
- GETGet Environment Allowance
- GETGet Fleet Reauth Status
- GETGet Fleet Projections
- POSTRegenerate Environment Pat
- GETList Machine Slots
- POSTAdd Machine Slot
- GETList Mail Wake Bindings
- PUTPut Mail Wake Binding
- DELETEDelete Mail Wake Binding
- GETGet Environment Capabilities
- PUTPut Environment Capabilities
- GETGet Effective Environment Capabilities
- GETGet Environment Capability History
- GETGet Environment
- PATCHUpdate Environment
- DELETEDelete Environment
- GETGet Environment Image
- POSTUpload Environment Image
- DELETEDelete Environment Image
- GETFs Read
- POSTFs Write
- DELETEFs Delete
- POSTFs Move
- POSTClaude Inject
- GETClaude List Skills
- POSTClaude Install Skill
- DELETEClaude Remove Skill
- POSTClaude Set Plan
- GETList Routines
- PUTReplace Routines
- POSTRun Routine
- GETClaude Bundle Preview
- POSTClaude Install Bundle
- POSTTrigger Sync
- GETEnv Health
- POSTOpen Session
- DELETEKill Session
- GETOpenhands Gui Status
- DELETEOpenhands Gui Stop
- POSTOpenhands Gui Start
- DELETEWg Remove Peer
- GETGet Credential Reauth Status
- GETList Environment Observations
- Machines
- Fleet
- GitHub
- GitHub App
- Factory
- Factory Control
- Factory Control Plane
- Factory Claim
- Factory Steer
- Factory Drill
- Factory Events
- Factory Metrics
- Factory Ratings
- Factory Reviews
- Factory Verdicts
- Factory Pay Per Use
- Performance
- Model Evals
- System
Factory
- How the factory works
- Set up your factory
- Fix a machine or desk that won't come up
- Fix a board that doesn't build or ship
- Machines, desks and the sidecar
- Board types and columns
- Projects and project settings
- Builders and engines
- How a card moves
- Connect GitHub
- Set a review policy
- Run your factory with the opvs skill and the agent-ops kit
- Factory CLI reference
Environments
List Environments
/api/v1/environmentsopvs machines listMCPtool_call software-factory.listEnvironmentsskillsoftware-factoryThe caller's fleet, plus the brand this read was scoped to.
curl "https://app.opvs.ai/api/v1/environments" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environmentsUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Create Environment
/api/v1/environmentstool_call software-factory.createEnvironmentskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environmentsThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
List Fleet Machines
/api/v1/environments/machinestool_call software-factory.listFleetMachinesskillsoftware-factoryOne ``MachineSlots`` view per machine the caller's brand has a desk on.
curl "https://app.opvs.ai/api/v1/environments/machines" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/machines",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/machines", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/machines", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/machinesUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Get Environment Allowance
/api/v1/environments/allowancetool_call software-factory.getEnvironmentAllowanceskillsoftware-factoryHow many machines this brand holds, and how many it may hold.
curl "https://app.opvs.ai/api/v1/environments/allowance" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/allowance",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/allowance", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/allowance", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/allowanceUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Get Fleet Reauth Status
/api/v1/environments/credentials/reauth-statustool_call software-factory.getFleetReauthStatusskillsoftware-factoryEvery lapsed subscription login across the caller's whole fleet, in ONE call.
curl "https://app.opvs.ai/api/v1/environments/credentials/reauth-status" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/credentials/reauth-status",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/credentials/reauth-status", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/credentials/reauth-status", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/credentials/reauth-statusUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Get Fleet Projections
/api/v1/environments/projectionstool_call software-factory.getFleetProjectionsskillsoftware-factoryHow many boards and cards each of the brand's machines has written.
curl "https://app.opvs.ai/api/v1/environments/projections" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/projections",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/projections", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/projections", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/projectionsUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Regenerate Environment Pat
/api/v1/environments/{env_id}/regenerate-pattool_call software-factory.regenerateEnvironmentPatskillsoftware-factoryRotate this environment's install PAT and reveal the new one ONCE.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/regenerate-pat" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/regenerate-pat",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/regenerate-pat", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/regenerate-pat", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/regenerate-patThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
List Machine Slots
/api/v1/environments/{env_id}/slotstool_call software-factory.listMachineSlotsskillsoftware-factoryEvery desk on this machine — what the "add another here" dialog reads.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/slots" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/slots",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/slots", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/slots", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/slotsUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Add Machine Slot
/api/v1/environments/{env_id}/slotstool_call software-factory.addMachineSlotskillsoftware-factoryAdd a desk to a machine this brand already has (BYO §6.4).
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/slots" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/slots",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/slots", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/slots", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/slotsThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
List Mail Wake Bindings
/api/v1/environments/{env_id}/mail-waketool_call software-factory.listMailWakeskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/mail-wakeUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Put Mail Wake Binding
/api/v1/environments/{env_id}/mail-waketool_call software-factory.setMailWakeskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X PUT "https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"PUT",
"https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("PUT", "https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()PUT /api/v1/environments/{env_id}/mail-wakeThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Delete Mail Wake Binding
/api/v1/environments/{env_id}/mail-wake/{address}tool_call software-factory.deleteMailWakeskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake/{address}" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake/{address}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake/{address}", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}/mail-wake/{address}", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}/mail-wake/{address}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Get Environment Capabilities
/api/v1/environments/{env_id}/capabilitiestool_call software-factory.getEnvironmentCapabilitiesskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/capabilities",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/capabilities", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/capabilitiesUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Put Environment Capabilities
/api/v1/environments/{env_id}/capabilitiestool_call software-factory.setEnvironmentCapabilitiesskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X PUT "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"PUT",
"https://app.opvs.ai/api/v1/environments/{env_id}/capabilities",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/capabilities", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("PUT", "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()PUT /api/v1/environments/{env_id}/capabilitiesThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Get Effective Environment Capabilities
/api/v1/environments/{env_id}/capabilities/effectivetool_call software-factory.getEffectiveEnvironmentCapabilitiesskillsoftware-factoryReturn the selected build policy narrowed by this desk's machine.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/effective" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/effective",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/effective", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/effective", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/capabilities/effectiveUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Get Environment Capability History
/api/v1/environments/{env_id}/capabilities/historytool_call software-factory.getEnvironmentCapabilityHistoryskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/history" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/history",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/history", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/capabilities/history", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/capabilities/historyUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Get Environment
/api/v1/environments/{env_id}opvs machines getMCPtool_call software-factory.getEnvironmentskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}Used once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Update Environment
/api/v1/environments/{env_id}tool_call software-factory.updateEnvironmentskillsoftware-factoryPatch this box. One of the fields is a CONSENT, and it is gated apart.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X PATCH "https://app.opvs.ai/api/v1/environments/{env_id}" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"PATCH",
"https://app.opvs.ai/api/v1/environments/{env_id}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}", {
method: "PATCH",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("PATCH", "https://app.opvs.ai/api/v1/environments/{env_id}", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()PATCH /api/v1/environments/{env_id}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Delete Environment
/api/v1/environments/{env_id}tool_call software-factory.deleteEnvironmentskillsoftware-factoryDelete this box. Retires its install key; refuses if it is hosting guests.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Get Environment Image
/api/v1/environments/{env_id}/imageStream this box's photo.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/image" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/image",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/image", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/image", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/imageUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Upload Environment Image
/api/v1/environments/{env_id}/imageSet this box's photo. Replaces any existing one.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/image" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/image",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/image", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/image", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/imageThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Delete Environment Image
/api/v1/environments/{env_id}/imagetool_call software-factory.deleteEnvironmentImageskillsoftware-factoryRemove this box's photo — the row pointer AND the stored object.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}/image" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}/image",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/image", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}/image", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}/imageThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Fs Read
/api/v1/environments/{env_id}/fs/{path}tool_call software-factory.deskFsReadskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/fs/{path}Used once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Fs Write
/api/v1/environments/{env_id}/fs/{path}Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/fs/{path}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Fs Delete
/api/v1/environments/{env_id}/fs/{path}tool_call software-factory.deskFsDeleteskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}/fs/{path}", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}/fs/{path}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Fs Move
/api/v1/environments/{env_id}/fs-movetool_call software-factory.deskFsMoveskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/fs-move" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/fs-move",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/fs-move", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/fs-move", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/fs-moveThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Claude Inject
/api/v1/environments/{env_id}/claude/injecttool_call software-factory.claudeInjectskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/claude/inject" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/claude/inject",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/claude/inject", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/claude/inject", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/claude/injectThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Claude List Skills
/api/v1/environments/{env_id}/claude/skillstool_call software-factory.claudeListSkillsskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/claude/skillsUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Claude Install Skill
/api/v1/environments/{env_id}/claude/skills/{name}Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/claude/skills/{name}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Claude Remove Skill
/api/v1/environments/{env_id}/claude/skills/{name}tool_call software-factory.claudeRemoveSkillskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}/claude/skills/{name}", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}/claude/skills/{name}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Claude Set Plan
/api/v1/environments/{env_id}/claude/plans/currenttool_call software-factory.claudeSetPlanskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/claude/plans/current" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/claude/plans/current",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/claude/plans/current", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/claude/plans/current", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/claude/plans/currentThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
List Routines
/api/v1/environments/{env_id}/routinestool_call software-factory.listRoutinesskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/routines" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/routines",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/routines", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/routines", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/routinesUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Replace Routines
/api/v1/environments/{env_id}/routinesErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X PUT "https://app.opvs.ai/api/v1/environments/{env_id}/routines" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"PUT",
"https://app.opvs.ai/api/v1/environments/{env_id}/routines",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/routines", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("PUT", "https://app.opvs.ai/api/v1/environments/{env_id}/routines", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()PUT /api/v1/environments/{env_id}/routinesThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Run Routine
/api/v1/environments/{env_id}/routines/{routine_id}/runtool_call software-factory.runRoutineskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/routines/{routine_id}/run" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/routines/{routine_id}/run",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/routines/{routine_id}/run", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/routines/{routine_id}/run", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/routines/{routine_id}/runThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Claude Bundle Preview
/api/v1/environments/{env_id}/claude/bundle/previewtool_call software-factory.claudeBundlePreviewskillsoftware-factoryDry-run: what a role's method bundle WOULD install onto this desk.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle/preview" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle/preview",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle/preview", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle/preview", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/claude/bundle/previewUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Claude Install Bundle
/api/v1/environments/{env_id}/claude/bundletool_call software-factory.claudeInstallBundleskillsoftware-factoryInstall the OPVS control-plane image (role method bundle) onto this workstation.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/claude/bundle", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/claude/bundleThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Trigger Sync
/api/v1/environments/{env_id}/synctool_call software-factory.triggerDeskSyncskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/sync" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/sync",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/sync", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/sync", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/syncThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Env Health
/api/v1/environments/{env_id}/healthtool_call software-factory.getEnvironmentHealthskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/health" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/health",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/health", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/health", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/healthUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Open Session
/api/v1/environments/{env_id}/sessiontool_call software-factory.openDeskSessionskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/session" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/session",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/session", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/session", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/sessionThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Kill Session
/api/v1/environments/{env_id}/session/{name}tool_call software-factory.killDeskSessionskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}/session/{name}" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}/session/{name}",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/session/{name}", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}/session/{name}", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}/session/{name}This endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Openhands Gui Status
/api/v1/environments/{env_id}/openhands-guitool_call software-factory.openhandsGuiStatusskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/openhands-guiUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
Openhands Gui Stop
/api/v1/environments/{env_id}/openhands-guitool_call software-factory.stopOpenhandsGuiskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}/openhands-guiThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Openhands Gui Start
/api/v1/environments/{env_id}/openhands-gui/starttool_call software-factory.startOpenhandsGuiskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X POST "https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui/start" \
-H "Authorization: Bearer $OPVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'import os
import requests
r = requests.request(
"POST",
"https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui/start",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}", "Content-Type": "application/json"},
data='{}',
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui/start", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/environments/{env_id}/openhands-gui/start", strings.NewReader(`{}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()POST /api/v1/environments/{env_id}/openhands-gui/startThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Wg Remove Peer
/api/v1/environments/{env_id}/wg/peertool_call software-factory.removeWireguardPeerskillsoftware-factoryErrors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl -X DELETE "https://app.opvs.ai/api/v1/environments/{env_id}/wg/peer" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"DELETE",
"https://app.opvs.ai/api/v1/environments/{env_id}/wg/peer",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/wg/peer", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/environments/{env_id}/wg/peer", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()DELETE /api/v1/environments/{env_id}/wg/peerThis endpoint changes data in your workspace, so it is not sent from the docs. Copy the command and run it in your own terminal.
Get Credential Reauth Status
/api/v1/environments/{env_id}/credentials/reauth-statustool_call software-factory.getEnvironmentReauthStatusskillsoftware-factoryDashboard-facing: the env's current interactive-credential re-auth flags.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/credentials/reauth-status" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/credentials/reauth-status",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/credentials/reauth-status", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/credentials/reauth-status", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/credentials/reauth-statusUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.
List Environment Observations
/api/v1/environments/{env_id}/observationstool_call software-factory.listEnvironmentObservationsskillsoftware-factoryReturn newest-first observations without exposing another brand's env.
Errors
| Code | When | What to do |
|---|---|---|
| 422 | Validation Error | — |
curl "https://app.opvs.ai/api/v1/environments/{env_id}/observations" \
-H "Authorization: Bearer $OPVS_TOKEN"import os
import requests
r = requests.request(
"GET",
"https://app.opvs.ai/api/v1/environments/{env_id}/observations",
headers={"Authorization": f"Bearer {os.environ['OPVS_TOKEN']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch("https://app.opvs.ai/api/v1/environments/{env_id}/observations", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.OPVS_TOKEN}` },
});
if (!r.ok) throw new Error(String(r.status));
console.log(await r.json());req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/environments/{env_id}/observations", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPVS_TOKEN"))
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()GET /api/v1/environments/{env_id}/observationsUsed once, saved nowhere. Your token travels for this request through opvs.ai and SpiderPublish to app.opvs.ai, then this page forgets it when the tab closes.