API

Deployments

Submit builds, follow progress, and manage releases.

A deployment builds and releases a project's configured source. Use this page to submit builds, inspect progress, handle decisions, and redeploy or roll back. For generated files and folder uploads, start with Source files.

The operations apply to self-hosted and Cloud deployments when the selected provider supports them. Cloud scope requirements still apply.

Deploy a Git project

Redeploys an already-linked project from its git source. To deploy a local folder instead, use the upload flow that ends at /build/access.

const result = await ship.deployments.create({
  projectId: "proj_123",
  branch: "main",
});
console.log(result);
curl -X POST "$OPENSHIP_URL/api/deployments" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"proj_123","branch":"main"}'

Prop

Type

Detect build configuration

Side-effect-free: point it at a git repo or a local path and it returns the detected framework, package manager, and build/start commands so the wizard can pre-fill. Creates nothing.

POST /api/deployments/prepare

Prop

Type

Local source is self-hosted only

source: "local" is rejected with 403 in cloud mode — cloud has no host filesystem to read.

Preparation masks environment values by default. Import editors can request them in the same response with includeEnv: true; see Reveal environment values.

Submit an uploaded build

Create a deployment and start its build. For a folder-upload deploy, pass projectId (from projects/ensure) and uploadSessionId (from projects/folder/session); for a git project, pass projectId and optionally branch. Returns { success, deployment_id, project_id }.

const result = await ship.deployments.buildAccess({
  projectId: "proj_123",
  branch: "main",
  buildStrategy: "server",
});
console.log(result);
curl -X POST "$OPENSHIP_URL/api/deployments/build/access" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"proj_123","branch":"main","buildStrategy":"server"}'

Prop

Type

Each publicEndpoints entry is { port?, targetPath?, domain?, customDomain?, domainType? } where domainType is "free" or "custom". A services entry mirrors a compose/monorepo service (name, image?, build?, dockerfile?, ports, dependsOn, environment, volumes, and the optional per-app build fields).

Don't force deployTarget on self-hosted

Setting deployTarget: "cloud" on a self-hosted instance triggers a promote-to-cloud flow. For a normal folder upload, leave deployTarget unset and let the upload session's mode decide.

Wait, decisions, and cancellation

A deployment submission returns IDs before the workload is ready. Read persisted build status to decide whether it succeeded. The SDK's deployment(id) handle adds polling and a normalized outcome.

const outcome = await ship.deployment("dep_123").wait({ timeoutMs: 120_000 });
if (!outcome.success) throw new Error(outcome.message ?? outcome.status);
curl "$OPENSHIP_URL/api/deployments/dep_123/build" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"

The REST request returns one status snapshot; poll it while the deployment runs. The SDK waits until a terminal state or a decision is required. ready and no_changes are successful. Handle failures, cancellation, partial failure, and rejection explicitly.

wait() returns status, success, decisionPending, and cancellationPending, with an optional prompt, message, or warning. Without an onPrompt callback it returns action_required when a decision is pending. To connect your own decision UI:

import type { PromptPayload } from "openship";

export async function waitWithDecisions(
  deploymentId: string,
  chooseAction: (prompt: PromptPayload) => Promise<string>,
) {
  return ship.deployment(deploymentId).wait({
    timeoutMs: 120_000,
    onPrompt: chooseAction,
  });
}

Return an action ID offered by the prompt. REST callers submit the same selected action as { "action": "<offered-id>" } to POST /api/deployments/:id/build/respond.

Aborting or timing out a wait stops observation. To cancel execution, call deployments.cancel(id) and inspect the subsequent state. Cancellation can remain pending while work settles; it does not roll back an already created release.

Read progress events

for await (const event of ship.deployments.events("dep_123", {
  signal: AbortSignal.timeout(30_000),
})) {
  console.log(event);
}
curl -N "$OPENSHIP_URL/api/deployments/dep_123/stream" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"

REST returns Server-Sent Events. SDK events contain an event name and serialized data; consumeDeploymentEvents() decodes log chunks. Use since to resume from a known event cursor while it is available. Durable replay across worker restarts is not implemented. A stream ending does not establish deployment success; read status.

Redeploy

const submitted = await ship.deployments.redeploy("dep_123", { useExistingCommit: true });
console.log(submitted.deployment_id);
curl -X POST "$OPENSHIP_URL/api/deployments/dep_123/redeploy" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"useExistingCommit":true}'

Re-runs the build. By default it resolves the latest commit on the branch (the auto-redeploy semantic); send { "useExistingCommit": true } to rebuild against the exact commit the original deployment used.

Rollback and pin

Rollback restores a previous deployment's artifact/commit as the active release. Pinning marks a deployment as protected so it isn't reclaimed by the rollback-window cleanup — POST /:id/pin defaults to { "pinned": true }; send { "pinned": false } to unpin.

POST /api/deployments/:id/rollback
POST /api/deployments/:id/pin

Cancel a running deploy

const cancellation = await ship.deployments.cancel("dep_123");
console.log(cancellation);
curl -X POST "$OPENSHIP_URL/api/deployments/dep_123/cancel" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"

Partial-failure compose deploys: keep or reject

When a multi-service (compose) deploy has some services succeed and others fail, it is held in partial_failure with decision: pending ("Action Required"). Resolve it explicitly:

  • Keep accepts the services that succeeded and leaves the rest on their prior version.
  • Reject rolls back the changed services to their previous state.
POST /api/deployments/:id/keep
POST /api/deployments/:id/reject

SSL status and renew

Both take the domain in the JSON body. /ssl/status is a side-effect-free probe (POST only so the hostname travels in the body); /ssl/renew re-issues the certificate.

POST /api/deployments/ssl/status
POST /api/deployments/ssl/renew
const result = await ship.deployments.sslStatus({
  domain: "app.example.com",
});
console.log(result);
curl -X POST "$OPENSHIP_URL/api/deployments/ssl/status" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain":"app.example.com"}'

Prop

Type

Errors

400 — bad request / failed operation

Missing a required field (domain is required, source must be 'github' or 'local') or the operation couldn't run (e.g. cancelling a deployment that already finished, or keep/reject on a deployment that isn't awaiting a decision). The response body carries { success: false, error }.

403 — local source in cloud mode

prepare with source: "local" (or a folder deploy) isn't available on Openship Cloud — there's no host filesystem. Use a git source instead.

404 on a per-deployment route

The :id doesn't belong to your organization (or was deleted). List with GET /api/deployments to get valid IDs.

Operations

Submit

OperationSDKREST API
Submit a deployment for a configured project.deployments.create(input)POST /api/deployments
deployment:write
Submit a new deployment based on an existing release.deployments.redeploy(id, input?)POST /api/deployments/:id/redeploy
deployment:write
Detect and prepare source configuration before submission.deployments.prepare(input)POST /api/deployments/prepare
deployment:write
Submit a prepared upload/build workflow.deployments.buildAccess(input)POST /api/deployments/build/access
deployment:write
Start an already prepared deployment.deployments.start(id)POST /api/deployments/:id/build
deployment:write

Observe

OperationSDKREST API
Read the persisted deployment record.deployments.get(id)GET /api/deployments/:id
deployment:read
Read a page of deployments using project and environment filters.deployments.list(input?)GET /api/deployments
deployment:list
Read captured deployment logs.deployments.logs(id, input?)GET /api/deployments/:id/logs
deployment:read
Read persisted status, pending prompts, and cancellation state.deployments.buildStatus(id)GET /api/deployments/:id/build
deployment:read
Inspect whether rollback needs retained artifacts or a rebuild.deployments.restorePlan(id)GET /api/deployments/:id/restore-plan
deployment:read
Stream deployment progress events.deployments.events(id, options?)GET /api/deployments/:id/stream
deployment:read
Read runtime/container information.deployments.containerInfo(id)GET /api/deployments/:id/info
deployment:read
Read current CPU, memory, disk, and network usage.deployments.containerUsage(id)GET /api/deployments/:id/usage
deployment:read
Read unresolved actions for the deployment.deployments.pendingActions(id)GET /api/deployments/:id/pending
deployment:read

Control

OperationSDKREST API
Request cancellation and return whether settlement is pending.deployments.cancel(id)POST /api/deployments/:id/cancel
deployment:write
Answer a pending deployment prompt with an offered action ID.deployments.respond(id, input)POST /api/deployments/:id/build/respond
deployment:write
Restore the selected deployment through the rollback workflow.deployments.rollback(id)POST /api/deployments/:id/rollback
deployment:write
Pin or unpin retained rollback artifacts.deployments.pin(id, input?)POST /api/deployments/:id/pin
deployment:write
Accept a release waiting for a keep/reject decision.deployments.keep(id)POST /api/deployments/:id/keep
deployment:write
Reject a held release and restore the prior deployment when possible.deployments.reject(id)POST /api/deployments/:id/reject
deployment:write
Remove an eligible deployment and its retained resources.deployments.remove(id)DELETE /api/deployments/:id
deployment:admin
Restart the deployment’s runtime.deployments.restart(id)POST /api/deployments/:id/restart
deployment:write
Skip the specified advisory port check.deployments.skipPortCheck(id, input)POST /api/deployments/:id/skip-port-check
deployment:write

Certificates

OperationSDKREST API
Read certificate status for a domain.deployments.sslStatus(input)POST /api/deployments/ssl/status
deployment:read
Request certificate renewal for a domain.deployments.renewSsl(input)POST /api/deployments/ssl/renew
deployment:write

On this page