BlueForge Docs

Hosting Projects

Hosting projects represent deployed applications with isolated environments, app counts, and lifecycle management.

Endpoint

MethodPathAuthIdempotent
GET
/api/projects
Beareryes
POST
/api/projects
Bearerno
GET
/api/projects/:identifier
Beareryes
PATCH
/api/projects/:id
Bearerno
DELETE
/api/projects/:id
Beareryes

Parameters

NameTypeRequiredDefaultNotes
name
stringyesHuman-readable project name
slug
stringnoauto-generated from
name
URL-safe identifier; generated via
slugify()
(lowercased, non-alphanumeric collapsed to hyphens, max 255 chars)
identifier
stringyes (path)Resolved against both
id
(UUID) and
slug
; the first match wins
id
stringyes (path for PATCH/DELETE)Project UUID

Response

// GET /api/projects — list all projects with enriched app count
{
  projects: Array<{
    id: string;
    name: string;
    slug: string;
    // ... other hosting project fields ...
    appCount: number;   // count of apps belonging to this project
  }>;
}

// GET /api/projects/:identifier — single project object
{
  id: string;
  name: string;
  slug: string;
  // ... other hosting project fields ...
}

// POST /api/projects (201) — created project object
{
  id: string;
  name: string;
  slug: string;
  // ... other hosting project fields ...
}

// PATCH /api/projects/:id — updated project object
{
  id: string;
  name: string;
  slug: string;
  // ... other hosting project fields ...
}

// DELETE /api/projects/:id — soft-delete confirmation
{ success: true }

// Error envelope (all routes)
{ error: { code: string; message: string } }

Examples

# List all hosting projects
curl -H "Authorization: Bearer $BF_API_KEY" \
  https://api.blueforge.studio/api/projects

# Create a hosting project
curl -X POST https://api.blueforge.studio/api/projects \
  -H "Authorization: Bearer $BF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My App", "slug": "my-app"}'

# Get project by slug
curl -H "Authorization: Bearer $BF_API_KEY" \
  https://api.blueforge.studio/api/projects/my-app

# Update project metadata
curl -X PATCH https://api.blueforge.studio/api/projects/prj_xxx \
  -H "Authorization: Bearer $BF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My App v2"}'

# Soft-delete a project
curl -X DELETE https://api.blueforge.studio/api/projects/prj_xxx \
  -H "Authorization: Bearer $BF_API_KEY"
import { Client } from "@blueforge/client"

const client = new Client({ apiKey: process.env.BF_API_KEY })

// List projects
const { projects } = await client.get("/api/projects")
console.log(projects.map(p => `${p.name} (${p.appCount} apps)`))

// Create project
const created = await client.post("/api/projects", { name: "My App" })

// Get by slug
const found = await client.get(`/api/projects/my-app`)

// Update
const updated = await client.patch(`/api/projects/${created.id}`, { name: "Renamed" })

// Delete
await client.delete(`/api/projects/${created.id}`)

Pitfalls

  • The
    identifier
    path param resolves against both
    id
    and
    slug
    in parallel. If a project's slug happens to collide with another project's UUID prefix, either may match first. Use UUIDs for exact lookups.
  • DELETE is a soft delete. The row is marked as deleted in the database but not physically removed.
  • The
    slug
    is capped at 255 characters after slugification. Very long names are silently truncated.
  • The list endpoint enriches each project with
    appCount
    via a per-project COUNT query — performance degrades linearly with the number of projects.

See also

Tested against

  • @blueforge/hosting-api: 2.4.1
  • Last verified: 2026-07-15