API reference
Deployments
List deployments, read build and runtime logs, redeploy and promote.
See Builds and Environments for how deployments are created by pushes and what each status means.
POST /v1/orgs/:orgId/projects/:projectId/uploads
A presigned PUT URL (15 minutes) for one source archive of size bytes (gzipped tar, at most 250 MB). Send the archive with exactly the returned headers, then start a deployment with the uploadId.
Auth: user access token or platform agent key · Scope: deployments:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:projectId | Project id (prj_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
size | integer | Yes | 1–262144000 |
Response 201
{
uploadId: string
url: string
headers: {
"content-type": string
"content-length": string
}
expiresIn: number
}Errors
| Status | Message |
|---|---|
404 | Project not found |
POST /v1/orgs/:orgId/projects/:projectId/deployments
Starts a deployment of the project. git: a commit of the linked repository on branch, with target (default: production for the production branch, else preview); a commit that already has a building or ready deployment for that target returns it (200) unless force. upload: the archive uploaded with uploadId, built as target.
Auth: user access token or platform agent key · Scope: deployments:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:projectId | Project id (prj_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
source | "git" | "upload" | Yes | ||
branch | string | No | 1–255 characters; trimmed | |
commitSha | string | No | matches ^[0-9a-f]{40}$ | |
uploadId | string | No | matches ^up_[A-Za-z0-9_-]{16,64}$ | |
target | "production" | "preview" | No | ||
force | boolean | No | false | |
manifest | object | No | values: any JSON | |
meta | object | No | ||
meta.branch | string | No | up to 255 characters | |
meta.commit | string | No | matches ^[0-9a-f]{7,40}$ | |
meta.dirty | boolean | No | ||
meta.machine | string | No | up to 64 characters |
Response 200
{
deployment: {
deploymentId: string
host?: string
target: "preview" | "production"
}
existing: true
}Response 201
{
deployment: {
deploymentId: string
host: string
target: "preview" | "production"
}
existing: false
}Errors
| Status | Message |
|---|---|
400 | A git deployment needs branch and commitSha. |
400 | An upload deployment needs uploadId and target. |
404 | Project not found |
404 | Not found |
404 | Commit not found |
409 | Link a repository to this project first. |
409 | The upload wasn't found. Upload the archive first. |
413 | The archive is larger than 250 MB. |
502 | Couldn't start the build. Try again. |
GET /v1/orgs/:orgId/deployments/:deploymentId/build-log
Build output after cursor (from the first step on), with the deployment's status. Poll with the returned cursor until done: the deployment has finished and no output is left.
Auth: user access token or platform agent key · Scope: logs:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deploymentId | Deployment id (dpl_…). |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
cursor | string | No | up to 2,048 characters |
Response 200
{
lines: []
cursor: null | string
status: "error" | "queued" | "building" | "deploying" | "ready" | "canceled" | "expired" | "skipped"
error: null | string
done: boolean
}
| {
status: "error" | "queued" | "building" | "deploying" | "ready" | "canceled" | "expired" | "skipped"
error: null | string
done: boolean
lines: {
t: number
m: string
}[]
cursor: string
}Errors
| Status | Message |
|---|---|
404 | Deployment not found |
GET /v1/orgs/:orgId/deployments/:deploymentId/runtime-logs/tail
Server function log events from since (epoch ms, at most an hour back; default the last minute) to now, oldest first, with event ids. q filters case-insensitively. Poll again from next, re-reading a few seconds (late events) and skipping ids already seen.
Auth: user access token or platform agent key · Scope: logs:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deploymentId | Deployment id (dpl_…). |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
since | integer | No | ≥ 0; coerced from a string |
q | string | No | up to 200 characters; trimmed |
Response 200
{
available: false
lines: []
next: number
more: false
}
| {
lines: {
t: number
level: "error" | "platform" | "warn" | "info" | "debug"
requestId?: string
message: string
truncated?: boolean
id: string
}[]
next: number
more: boolean
available: true
}Errors
| Status | Message |
|---|---|
404 | Deployment not found |
GET /v1/orgs/:orgId/deployments
Lists deployments across projects, newest first. Pass the returned cursor to get the next page.
Auth: user access token or platform agent key · Scope: deployments:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
| Query parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
projectId | string | No | at least 1 character | |
target | "production" | "preview" | No | ||
status | "queued" | "building" | "deploying" | "ready" | "error" | "canceled" | "expired" | "skipped" | No | ||
branch | string | No | 1–255 characters | |
cursor | string | No | at least 1 character | |
limit | integer | No | 50 | 1–100; coerced from a string |
Response 200
{
deployments: {
error?: string
status?: "error" | "queued" | "building" | "deploying" | "ready" | "canceled" | "expired" | "skipped"
createdAt?: number
updatedAt?: number
region?: string
orgId: string
createdBy?: string
projectId: string
location: string
deploymentId: string
target: "preview" | "production"
branch?: string
commitSha?: string
commitMessage?: string
commitAuthor?: string
host?: string
buildId?: string
buildDurationMs?: number
readyAt?: number
crons?: string
envHash?: string
previousDeploymentId?: string
reason?: string
source?: "git" | "upload"
sourceArchive?: string
buildMetrics?: {
restoreMs?: number
installMs?: number
buildMs?: number
uploadMs?: number
saveMs?: number
depsCache?: "hit" | "partial" | "miss" | "off"
nextCache?: "hit" | "partial" | "miss" | "off"
packageManager?: string
installDir?: string
}
}[]
cursor: null | string
}Errors
| Status | Message |
|---|---|
404 | Project not found |
404 | Not found |
404 | Commit not found |
GET /v1/orgs/:orgId/deployments/:deploymentId
A deployment and a summary of its project.
Auth: user access token or platform agent key · Scope: deployments:read · Allowed: domains:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deploymentId | Deployment id (dpl_…). |
Response 200
{
deployment?: {
error?: string
status?: "error" | "queued" | "building" | "deploying" | "ready" | "canceled" | "expired" | "skipped"
createdAt?: number
updatedAt?: number
region?: string
orgId: string
createdBy?: string
projectId: string
location: string
deploymentId: string
target: "preview" | "production"
branch?: string
commitSha?: string
commitMessage?: string
commitAuthor?: string
host?: string
buildId?: string
buildDurationMs?: number
readyAt?: number
crons?: string
envHash?: string
previousDeploymentId?: string
reason?: string
source?: "git" | "upload"
sourceArchive?: string
buildMetrics?: {
restoreMs?: number
installMs?: number
buildMs?: number
uploadMs?: number
saveMs?: number
depsCache?: "hit" | "partial" | "miss" | "off"
nextCache?: "hit" | "partial" | "miss" | "off"
packageManager?: string
installDir?: string
}
}
project: {
projectId: string
name: string
slug: string
productionDeploymentId?: string
repoId?: string
framework?: "static" | "nextjs" | "node"
location: string
rootDirectory?: string
}
productionHost?: string
domains?: {
hostname: string
status?: "error" | "active" | "pending" | "verifying"
redirectTo?: string
}[]
function: null | {
region: string
name: string
memoryMb: 1024
timeoutSeconds: 30
architecture: "arm64"
runtime: "nodejs22.x"
}
}Errors
| Status | Message |
|---|---|
404 | Deployment not found |
404 | Project not found |
404 | Not found |
404 | Commit not found |
GET /v1/orgs/:orgId/deployments/:deploymentId/logs
Build output, starting at the first build step.
Auth: user access token or platform agent key · Scope: logs:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deploymentId | Deployment id (dpl_…). |
Response 200
{
lines: {
t?: number
m: string
}[]
}Errors
| Status | Message |
|---|---|
404 | Deployment not found |
GET /v1/orgs/:orgId/deployments/:deploymentId/runtime-logs
Server function logs from the last hour, newest first. q filters messages case-insensitively. available is false for deployments without a server function.
Auth: user access token or platform agent key · Scope: logs:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deploymentId | Deployment id (dpl_…). |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
q | string | No | up to 200 characters; trimmed |
Response 200
{
available: false
lines: []
}
| {
lines: {
t: number
level: "error" | "platform" | "warn" | "info" | "debug"
requestId?: string
message: string
truncated?: boolean
}[]
from: number
to: number
limited: boolean
available: true
}Errors
| Status | Message |
|---|---|
404 | Deployment not found |
POST /v1/orgs/:orgId/deployments/:deploymentId/redeploy
Builds the deployment's commit again as a new deployment with the same target.
Auth: user access token or platform agent key · Scope: deployments:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deploymentId | Deployment id (dpl_…). |
Response 201
{
deployment: {
deploymentId: string
host: string
target: "preview" | "production"
}
}Errors
| Status | Message |
|---|---|
404 | Deployment not found |
404 | Project not found |
409 | This deployment is still in progress. |
409 | This upload has expired. Deploy again from your terminal. |
409 | This deployment has no commit to build. |
409 | Link a repository to this project first. |
502 | Couldn't start the build. Try again. |
POST /v1/orgs/:orgId/deployments/:deploymentId/promote
Makes a ready deployment production without rebuilding: promotes a preview, or rolls back to an earlier production deployment.
Auth: user access token or platform agent key · Scope: deployments:write
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deploymentId | Deployment id (dpl_…). |
Response 200
{
deployment: {
error?: string
status?: "error" | "queued" | "building" | "deploying" | "ready" | "canceled" | "expired" | "skipped"
createdAt?: number
updatedAt?: number
region?: string
orgId: string
createdBy?: string
projectId: string
location: string
deploymentId: string
target: "preview" | "production"
branch?: string
commitSha?: string
commitMessage?: string
commitAuthor?: string
host?: string
buildId?: string
buildDurationMs?: number
readyAt?: number
crons?: string
envHash?: string
previousDeploymentId?: string
reason?: string
source?: "git" | "upload"
sourceArchive?: string
buildMetrics?: {
restoreMs?: number
installMs?: number
buildMs?: number
uploadMs?: number
saveMs?: number
depsCache?: "hit" | "partial" | "miss" | "off"
nextCache?: "hit" | "partial" | "miss" | "off"
packageManager?: string
installDir?: string
}
}
productionHost: string
}Errors
| Status | Message |
|---|---|
404 | Deployment not found |
404 | Project not found |
409 | This deployment has expired. Redeploy it instead. |
409 | Only ready deployments can be promoted. |
409 | This is already the production deployment. |
409 | This deployment's server function was removed. Redeploy it instead. |
502 | Couldn't update production routing. Try again. |