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
Last updated on
Servers API
HTTP API reference for browsing and filtering CodeSpar's catalog of MCP servers across payments, fiscal, logistics, messaging, banking, ERP, and crypto.
Wallets API
HTTP API reference for Programmable Wallets — create wallets, post ledger entries, bind funding sources, execute mandate-gated payments, triage reconciliation anomalies.