Cosmoner Docs
API Reference

Projects

Manage projects, members, roles, invitations, and billing responsibility.

Projects map to Better-Auth organizations. Every resource (app, server, domain, etc.) belongs to a project.

List Projects

GET /v1/projects

Returns all projects the authenticated user is a member of, with resource counts.

Auth: Required

Response (200):

{
  "success": true,
  "data": [
    {
      "id": "org_...",
      "name": "My Project",
      "slug": "my-project",
      "servers": 2,
      "domains": 3,
      "members": 4,
      "apps": 1,
      "objectStorage": 1,
      "containerRegistries": 0
    }
  ]
}

Get Project

GET /v1/projects/:projectId

Returns a single project with resource counts. Accepts project ID or slug.

Auth: Required


Get Project Stats

GET /v1/projects/:projectId/stats

Returns resource creation history for the last 6 months, aggregated by month.

Auth: Required (member)

Response (200):

{
  "success": true,
  "data": [
    {
      "month": "2025-01",
      "servers": 1,
      "domains": 2,
      "apps": 0,
      "objectStorage": 0,
      "containerRegistries": 0
    }
  ]
}

Create Project

POST /v1/projects/create

Creates a new project. Provisions a DigitalOcean project and a platform organization.

Auth: Required

Request Body:

{
  "name": "My New Project"
}

Response (201):

{
  "success": true,
  "data": {
    "id": "org_...",
    "name": "My New Project",
    "slug": "..."
  }
}

Rename Project

PATCH /v1/projects/:projectId

Auth: Required (owner or admin)

Request Body:

{
  "name": "New Name"
}

Update Billing Email

PATCH /v1/projects/:projectId/billing-email

Sets or clears the project's billing email. This address receives invoices and receipts sent by Stripe (it is mirrored onto the Stripe customer) as well as billing notifications such as receipts and payment-failure notices. Pass null to clear it — delivery then reverts to the biller's account email.

Auth: Required (owner or admin)

Request Body:

{
  "billingEmail": "[email protected]"
}

Response:

{
  "success": true,
  "data": {
    "billingEmail": "[email protected]"
  }
}

Delete Project

DELETE /v1/projects/:projectId

Deletes a project. Fails if any resources (servers, apps, domains, etc.) still exist.

Auth: Required (owner only)


Members

Get My Role

GET /v1/projects/:projectId/members/me

Returns the current user's role in the project.

Auth: Required (member)

List Members

GET /v1/projects/:projectId/members

Returns all members, pending invitations, and biller info.

Auth: Required (member, scope: members:read)

Invite Member

POST /v1/projects/:projectId/members

Auth: Required (write access, scope: members:write)

Request Body:

{
  "email": "[email protected]",
  "role": "developer"
}

Remove Member

DELETE /v1/projects/:projectId/members/:memberId

Auth: Required (write access, scope: members:write)

The project's biller cannot be removed while they hold billing responsibility. Attempting to remove them returns 409 with a code of BILLER_CANNOT_LEAVE — transfer billing to another member first.

Update Member Role

PATCH /v1/projects/:projectId/members/:memberId/role

Auth: Required (write access, scope: members:write)

Request Body:

{
  "role": "admin"
}

Valid roles: viewer, developer, admin, owner

Cancel Invitation

DELETE /v1/projects/:projectId/members/invitations/:invitationId

Auth: Required (write access, scope: members:write)


Billing Responsibility Transfer

Initiate Transfer

POST /v1/projects/:projectId/members/biller/transfer

Transfers billing responsibility to another member. The nominated member is notified (email + in-app) with a link to accept. Accepting and declining also notify the outgoing biller.

Before initiating a transfer, the outgoing biller can optionally refund any remaining project credit to their payment method via Refund Credit Balance — otherwise the credit stays with the project for the incoming biller. That refund is issued minus non-recoverable payment-processing (transaction) fees, so the amount received is less than the credit balance; see Refund Credit Balance for details.

Accept Transfer

POST /v1/projects/:projectId/members/biller/accept

Accepting a transfer requires the new biller to add a payment method to the project. First create an org setup intent (POST /v1/projects/:projectId/billing/setup-intent) and confirm the card in the browser, then pass the resulting payment method id here.

Request Body:

{
  "paymentMethodId": "pm_..."
}

The supplied card becomes the project's new default. The previous biller's card is detached once the transfer commits.

Decline Transfer

POST /v1/projects/:projectId/members/biller/decline

On this page