POST /api/project
Creates a new project, registers a GitHub push webhook on the target repository, and queues an initial build from the latest commit on the specified branch. Requires JWT.Request body
Project name. Must be unique across all projects. This value is used as the subdomain when Shipyard serves the deployed output (e.g., a project named
my-app is served at my-app.<BASE_DOMAIN>). Validated to be non-empty and unique.The HTTPS URL of the GitHub repository (e.g.,
https://github.com/owner/repo). Shipyard parses the owner and repo name from this URL to register the webhook via the GitHub API.The branch to watch. Shipyard only triggers builds for push events that target this branch.
Command to install dependencies. Defaults to
npm install if omitted. Run inside the Docker container before the build command.Command to produce the build output. If omitted, Shipyard skips the build phase and uses the repository contents directly.
Not accepted on project creation — use
PUT /api/project/projects/:projectId to set this after creation. Defaults to ./. Shipyard auto-detects dist for Vite projects and .next for Next.js projects at build time regardless of this setting.Array of environment variable key-value pairs. Each secret is encrypted with AES-256-GCM before being stored. Secrets are decrypted only at build time and are never returned in API responses.
Environment variable name.
Environment variable value. Encrypted before storage.
Curl example
Response
buildStatusUpdate Socket.io event using the returned initialBuildId.
Error responses
| Status | Condition |
|---|---|
401 | JWT is missing or invalid |
422 | Validation failed — name, branch, or repoUrl is missing or the project name is already taken |
500 | Failed to register the GitHub webhook or insert the project |
GET /api/project/projects
Returns all projects belonging to the authenticated user, each with their full build history and deployments. Requires JWT.Curl example
Response
Secret values are returned as stored (AES-256-GCM ciphertext). They are never decrypted in API responses — only at build time inside the containerized pipeline.
PUT /api/project/projects/:projectId
Updates settings on an existing project. The server verifies that the project belongs to the authenticated user before applying any changes. Only fields present in the request body are updated; omitted fields retain their existing values. Requires JWT.Path parameters
Numeric ID of the project to update.
Request body
New project name. Must be unique across all projects if changed.
New branch to watch for push events.
Updated build command.
Updated install command.
Updated output directory.
Curl example
Response
Error responses
| Status | Condition |
|---|---|
400 | projectId path parameter is missing |
401 | JWT is missing or invalid |
403 | The project does not belong to the authenticated user |
404 | No project found with the given ID |
DELETE /api/project/projects/:projectId
Deletes a project and removes the associated GitHub webhook. All related records — builds, build logs, deployments, and secrets — are deleted via database cascade. Requires JWT.Path parameters
Numeric ID of the project to delete.
Curl example
Response
Error responses
| Status | Condition |
|---|---|
400 | projectId or user ID is missing |
401 | JWT is missing or invalid |
403 | The project does not belong to the authenticated user |
404 | No project found with the given ID |
DELETE /api/project/secret/:secretId
Permanently deletes a single encrypted secret by its ID. The server verifies that the secret belongs to a project owned by the authenticated user. Requires JWT.Path parameters
Numeric ID of the secret to delete. Secret IDs are returned in the
secrets array of the GET /api/project/projects response.Curl example
Response
Error responses
| Status | Condition |
|---|---|
400 | secretId or user ID is missing |
401 | JWT is missing or invalid |
403 | The secret’s project does not belong to the authenticated user |
500 | Deletion failed unexpectedly |