Projects API
HTTP API reference for creating, listing, updating, and deleting projects -- the second level of CodeSpar's account -> project tenancy model.
Projects API
The Projects API manages the second level of CodeSpar's tenancy model: Account -> Project. See the Projects concept for the full model.
Base URL: https://api.codespar.dev
All endpoints require authentication via Bearer token. See Authentication.
Project object
| Field | Type | Description |
|---|---|---|
id | string | Project ID in the form prj_<16chars> |
org_id | string | Parent account ID |
name | string | Display name (free-form) |
slug | string | URL-safe identifier, unique per account |
is_default | boolean | true for the account's default project (exactly one per account) |
created_at | string | ISO 8601 timestamp |
Slug rules
- Lowercase alphanumeric characters plus
_and- - Max length: 64 characters
defaultis reserved (only the auto-created default project uses it)- Must be unique within the account
Violations return slug_invalid, slug_reserved, or slug_conflict (see Errors).
GET /v1/projects
Lists all projects in the authenticated account.
Auth required: Yes
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
is_default | boolean | -- | Filter to only the default project (true) or non-default projects (false) |
limit | number | 50 | Results per page (max 100) |
offset | number | 0 | Pagination offset |
curl example
curl https://api.codespar.dev/v1/projects \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"data": [
{
"id": "prj_a1b2c3d4e5f6g7h8",
"org_id": "org_xyz789",
"name": "Default",
"slug": "default",
"is_default": true,
"created_at": "2026-04-01T10:00:00Z"
},
{
"id": "prj_i9j0k1l2m3n4o5p6",
"org_id": "org_xyz789",
"name": "Staging",
"slug": "staging",
"is_default": false,
"created_at": "2026-04-15T09:12:00Z"
}
],
"total": 2,
"limit": 50,
"offset": 0
}GET /v1/projects/:id
Retrieves a single project by ID.
Auth required: Yes
curl example
curl https://api.codespar.dev/v1/projects/prj_a1b2c3d4e5f6g7h8 \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"id": "prj_a1b2c3d4e5f6g7h8",
"org_id": "org_xyz789",
"name": "Default",
"slug": "default",
"is_default": true,
"created_at": "2026-04-01T10:00:00Z"
}POST /v1/projects
Creates a new project in the authenticated account.
Auth required: Yes
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name |
slug | string | Yes | URL-safe identifier (see slug rules) |
New projects are always created with is_default: false. To promote a project to default, use PATCH /v1/projects/:id with {"is_default": true}.
curl example
curl -X POST https://api.codespar.dev/v1/projects \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "Production",
"slug": "prod"
}'Response -- 201 Created
{
"id": "prj_q7r8s9t0u1v2w3x4",
"org_id": "org_xyz789",
"name": "Production",
"slug": "prod",
"is_default": false,
"created_at": "2026-04-20T14:22:00Z"
}PATCH /v1/projects/:id
Updates a project's name, slug, or default status.
Auth required: Yes
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | New display name |
slug | string | No | New slug (subject to slug rules) |
is_default | boolean | No | Set to true to promote this project to default. Atomic: the previous default is demoted in the same transaction. |
is_default can only be set to true. You cannot un-set it directly -- to change the default, promote a different project instead. Sending {"is_default": false} on the current default project is a no-op or error (exact behavior: TODO -- confirm).
curl example -- promote to default
curl -X PATCH https://api.codespar.dev/v1/projects/prj_q7r8s9t0u1v2w3x4 \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"is_default": true}'Response -- 200 OK
{
"id": "prj_q7r8s9t0u1v2w3x4",
"org_id": "org_xyz789",
"name": "Production",
"slug": "prod",
"is_default": true,
"created_at": "2026-04-20T14:22:00Z"
}DELETE /v1/projects/:id
Deletes a project and all of its scoped resources (API keys, triggers, session history, connection records).
Auth required: Yes
Deletion cascades. There is no undo. Export audit logs first if you need to retain them.
curl example
curl -X DELETE https://api.codespar.dev/v1/projects/prj_q7r8s9t0u1v2w3x4 \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"id": "prj_q7r8s9t0u1v2w3x4",
"deleted": true
}Deletion fails with cannot_delete_default or cannot_delete_last_project (see below).
Project members (RBAC overrides)
Every user with account membership inherits a base role (owner, admin, member) that applies across every project in that account. The four endpoints below let an account admin narrow or widen that role for a specific project — useful when a contractor should see exactly one project, or a member needs admin rights on staging without becoming a full account admin.
A user absent from project_members inherits their account-level role unchanged. Explicit rows are overrides, not the source of truth.
GET /v1/projects/:id/members
Lists every user with effective access to the project, including account-level inherited members. The source field tells you whether the role came from a project override or from the account membership.
curl https://api.codespar.dev/v1/projects/prj_a1b2c3d4e5f6g7h8/members \
-H "Authorization: Bearer csk_live_..."Response — 200 OK
{
"members": [
{
"user_id": "user_owner123",
"role": "owner",
"source": "org",
"email": "founder@codespar.dev",
"display_name": "Founder",
"avatar_url": null,
"added_at": "2026-04-15T10:00:00Z"
},
{
"user_id": "user_contractor456",
"role": "admin",
"source": "project",
"email": "ana@contractor.com",
"display_name": "Ana",
"avatar_url": null,
"added_at": "2026-04-22T18:30:00Z"
}
]
}Sorted: owner first, then admin, then member — oldest first within each tier.
POST /v1/projects/:id/members
Adds or upserts a project-level override. Requires account-level admin or owner.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
user_id | string | Yes | Must already be a member of the account. |
role | admin | member | Yes | Cannot override an account owner — they always retain full access. |
curl -X POST https://api.codespar.dev/v1/projects/prj_.../members \
-H "Authorization: Bearer csk_live_..." \
-H "Content-Type: application/json" \
-d '{"user_id": "user_contractor456", "role": "admin"}'PATCH /v1/projects/:id/members/:user_id
Updates an existing override's role. Same gate (admin+ at account level).
curl -X PATCH https://api.codespar.dev/v1/projects/prj_.../members/user_contractor456 \
-H "Authorization: Bearer csk_live_..." \
-H "Content-Type: application/json" \
-d '{"role": "member"}'DELETE /v1/projects/:id/members/:user_id
Removes the override. The user falls back to their account-level role for this project.
curl -X DELETE https://api.codespar.dev/v1/projects/prj_.../members/user_contractor456 \
-H "Authorization: Bearer csk_live_..."Member-related error codes
| Status | Error code | When |
|---|---|---|
403 | requires_org_admin | POST/PATCH/DELETE called by a non-admin account member |
404 | member_not_in_org | user_id is not a member of this account |
404 | override_not_found | PATCH/DELETE on a user that has no override row (they only inherit) |
409 | cannot_override_owner | Tried to override an account owner's role |
Errors
All endpoints follow the standard error format:
{
"error": "error_code",
"message": "Human-readable error description.",
"status": 400
}Project-specific error codes
| Status | Error code | When |
|---|---|---|
400 | slug_invalid | Slug contains disallowed characters, exceeds 64 chars, or is empty |
400 | slug_reserved | Slug is default (reserved for the auto-created default project) |
409 | slug_conflict | Another project in the account already uses this slug |
409 | cannot_delete_default | DELETE on the default project. Promote another project first. |
409 | cannot_delete_last_project | DELETE on the only remaining project. Every account must have at least one project. |
Standard error codes
| Status | Error code | When |
|---|---|---|
401 | unauthorized | Invalid or missing API key |
403 | forbidden | API key lacks permission (e.g. a project-scoped key trying to manage a different project) |
404 | not_found | Project ID does not exist or does not belong to the authenticated account |
429 | rate_limited | Too many requests |
500 | internal_error | Server error. Retry with exponential backoff. |
Next steps
Servers API
HTTP API reference for browsing and filtering CodeSpar's catalog of MCP servers across payments, fiscal, logistics, messaging, banking, ERP, and crypto.
@codespar/api-types
Zod schemas + TypeScript types for every /v1/* REST shape on api.codespar.dev. Used internally by the SDK and dashboard; published for callers building HTTP clients directly.