Endpoint reference
Every endpoint below is prefixed with https://octopuslabapi-production.up.railway.app/api/v1 and gated by an API key from Settings → API keys. See Authentication for the header shape.
GET /public/me
Returns the org bound to the calling key plus the key's scopes.
curl -H "Authorization: Bearer ok_…" \
https://…/api/v1/public/me{
"org": {
"id": "edac38fa-3b59-4373-8485-f68be75bc6dc",
"slug": "aurora-labs",
"name": "Aurora Labs",
"plan": "pro"
},
"scopes": ["*"]
}GET /public/projects
Lists this org's projects, newest first. Capped at 200 rows.
curl -H "Authorization: Bearer ok_…" \
https://…/api/v1/public/projects[
{
"id": "811792d9-0f73-4651-b6e6-4479f667c6e1",
"slug": "a-landing-page-for-80ry",
"name": "A landing page for",
"status": "live",
"createdAt": "2026-06-04T11:00:00Z",
"updatedAt": "2026-06-05T12:00:00Z"
}
]GET /public/projects/:id
Single project by id. 404 if it isn't in this org.
POST /public/projects
Creates a new project from a prompt. The prompt becomes the first user message of the project's conversation — the AI generation kicks off asynchronously, so the response comes back with status: "generating" and you should poll GET /public/projects/:id until it flips to live / failed.
curl -X POST \
-H "Authorization: Bearer ok_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Pricing experiments",
"slug": "pricing-experiments",
"prompt": "A landing page comparing three pricing plans for a SaaS, dark theme."
}' \
https://…/api/v1/public/projectsRequest body:
name(string, 1–80 chars) — human-readable title shown in the dashboard.slug(string, lowercase letters / digits / hyphens, 1–63 chars) — must be unique inside the org. Becomes the production subdomain.prompt(string, 1–8000 chars) — first user message.stack(optional, "next" | "astro" | "react" | "static") — defaults to"next".
On 403 "Project with this slug already exists in the org" change the slug and retry — we don't auto-disambiguate (so your script doesn't accidentally generate twice).
GET /public/projects/:id/deployments
50 most recent deployments for the project, newest first.
[
{
"id": "1e71724f-…",
"shortId": "ab7f0c0",
"status": "ready",
"commitMessage": "Manual promote to production",
"createdAt": "2026-06-08T19:00:00Z",
"isActiveProd": true
}
]isActiveProd: true marks the deployment currently aliased to your custom domain / subdomain. Exactly one row at a time has it set.
GET /public/projects/:id/audits
50 most recent SEO/AEO audits for the project.
[
{
"id": "…",
"url": "https://a-landing-page-for-80ry.octopus-lab.app",
"status": "done",
"overallScore": 92,
"startedAt": "…",
"finishedAt": "…"
}
]Coming in v1.1
POST /public/projects/:id/deploy— trigger a redeploy.POST /public/projects/:id/audits/run— trigger an audit.GET /public/projects/:id/audits/:auditId— the findings list.POST /public/projects/:id/messages— append a chat message programmatically (and stream the AI's reply via SSE).