Skip to content
The API is in beta and may change without prior notice.

Projects Endpoints

All project endpoints are under /projects.

Create Project

POST /projects/

Authentication: Required

Request Body:

json
{
  "name": "My App",
  "description": "My awesome application",
  "is_public": true
}
FieldTypeRequiredDescription
namestringYesProject name
descriptionstringNoProject description
is_publicbooleanNoPublic or private (default: false)

INFO

The slug is always auto-generated from the project name and cannot be specified in the request body.

Response 201:

json
{
  "id": "uuid",
  "name": "My App",
  "slug": "my-app",
  "description": "My awesome application",
  "is_public": true,
  "owner_id": "user-uuid",
  "created_at": "2024-01-01T00:00:00.000Z"
}

List Projects

GET /projects/

Authentication: Required

Returns all projects the user is a member of.


Get Project

GET /projects/:slug

Authentication: Required


Update Project

PATCH /projects/:slug

Authentication: Required (owner or admin)

Request Body (all optional):

json
{
  "name": "Updated Name",
  "description": "Updated description",
  "is_public": false
}

Delete Project

DELETE /projects/:slug

Authentication: Required (owner only)


Join Project

Join a public project.

POST /projects/:slug/join

Authentication: Required

INFO

Only works for public projects. For private projects, use invites.


Leave Project

DELETE /projects/:slug/leave

Authentication: Required

WARNING

The project owner cannot leave. Transfer ownership first.


List Members

GET /projects/:slug/members

Authentication: Required (project member)

Response 200:

json
[
  {
    "id": "member-uuid",
    "user_id": "user-uuid",
    "role": "owner",
    "user": {
      "id": "user-uuid",
      "email": "owner@example.com",
      "display_name": "Project Owner"
    },
    "permissions": [],
    "created_at": "2024-01-01T00:00:00.000Z"
  }
]

Add Member

POST /projects/:slug/members

Authentication: Required (owner or admin)

Request Body:

json
{
  "email": "user@example.com",
  "role": "member",
  "permissions": ["can_deploy"]
}
FieldTypeRequiredDescription
emailstringYesEmail of the user to add
role"admin" | "member"NoRole (default: member)
permissionsstring[]NoArray of permission keys

Update Member

PATCH /projects/:slug/members/:memberId

Authentication: Required (owner or admin)

Request Body:

json
{
  "role": "admin",
  "permissions": ["can_deploy", "can_edit"]
}

INFO

Permissions use string keys (e.g., "can_deploy", "editor"), not UUIDs.


Remove Member

DELETE /projects/:slug/members/:memberId

Authentication: Required (owner or admin)


Transfer Ownership

POST /projects/:slug/transfer-ownership

Authentication: Required (owner only)

Request Body:

json
{
  "new_owner_id": "new-owner-uuid"
}

The current owner becomes an admin after transfer.


Permissions

List Permissions

GET /projects/:slug/permissions

Create Permission

POST /projects/:slug/permissions

Request Body:

json
{
  "key": "can_deploy",
  "display_name": "Can Deploy",
  "description": "Allow deployment to production",
  "is_default": false
}
FieldTypeRequiredDescription
keystringYesUnique permission identifier
display_namestringYesHuman-readable name
descriptionstringNoPermission description
is_defaultbooleanNoWhether assigned to new members by default (default: false)

Update Permission

PATCH /projects/:slug/permissions/:permissionId

Delete Permission

DELETE /projects/:slug/permissions/:permissionId

Project OAuth Clients

Create Client

POST /projects/:slug/clients

Request Body:

json
{
  "name": "My App OAuth Client",
  "redirect_uri": "https://myapp.com/callback"
}

List Clients

GET /projects/:slug/clients

Project Invites

List Invites

GET /projects/:slug/invites

Create Invite

POST /projects/:slug/invites

Request Body:

json
{
  "email": "user@example.com",
  "role": "member",
  "redirect_url": "https://myapp.com/welcome"
}
FieldTypeRequiredDescription
emailstringYesEmail of the user to invite
role"admin" | "member"NoRole (default: member)
redirect_urlstringNoURL to redirect after accepting

INFO

Invites expire after 7 days.

Cancel Invite

DELETE /projects/:slug/invites/:inviteId

HitKey Service License.