Skip to content

API overview

Slipway’s API is Connect-RPC: protobuf-defined services served over HTTP/2 and HTTP/1.1, callable as gRPC, gRPC-Web, or the Connect protocol with plain JSON. The browser app, the CLI and your scripts all use the same API.

  • Protos live in proto/slipway/v1/ (package slipway.v1), one service per domain.
  • Typed clients are generated for Go and TypeScript. A Terraform provider is planned.
  • An OpenAPI description is served at /api/v1/openapi.json. See OpenAPI.

IdentityService, ProjectService, PipelineService, RunService, RunnerService (runner to server, bidirectional stream), LogService (server stream), ArtifactService, SecretService, ScmService, DeployService, ReleaseService, EnvironmentService, ApprovalService, RunbookService, IntegrationService, WebhookService, BillingService, AuditService and AdminService.

The Connect protocol lets you call any unary RPC with a JSON POST to /<package>.<Service>/<Method>:

Terminal window
curl -sS https://slipway.example.com/slipway.v1.RunService/ListRuns \
-H "Authorization: Bearer $SLIPWAY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"project_id":"proj_01H...","page_size":20,"filter":"status == \"failed\" && branch == \"main\""}'

JSON field names are the proto field names in lowerCamelCase or snake_case (both are accepted on input). Enums are strings, timestamps are RFC 3339 strings, durations are strings like "30s", and 64-bit integers are strings.

import (
"connectrpc.com/connect"
slipwayv1 "github.com/slipway-systems/slipway/gen/go/slipway/v1"
"github.com/slipway-systems/slipway/gen/go/slipway/v1/slipwayv1connect"
)
client := slipwayv1connect.NewRunServiceClient(http.DefaultClient, "https://slipway.example.com")
req := connect.NewRequest(&slipwayv1.ListRunsRequest{ProjectId: "proj_01H...", PageSize: 20})
req.Header().Set("Authorization", "Bearer "+token)
resp, err := client.ListRuns(ctx, req)
import { createClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-web";
import { RunService } from "@slipway/api-client";
const transport = createConnectTransport({
baseUrl: "https://slipway.example.com",
interceptors: [(next) => (req) => { req.header.set("Authorization", `Bearer ${token}`); return next(req); }],
});
const runs = createClient(RunService, transport);
const { items } = await runs.listRuns({ projectId: "proj_01H...", pageSize: 20 });

Any gRPC client works against the same endpoint (HTTP/2 with TLS). Use grpcurl with the published protobuf descriptors:

Terminal window
grpcurl -H "Authorization: Bearer $SLIPWAY_TOKEN" slipway.example.com:443 slipway.v1.DeployService/ListServices
Topic Rule
Resource names Messages are named after domain entities: Run, Release, Deployment
Methods ListX, GetX, CreateX, UpdateX (with an update_mask), DeleteX
IDs Prefixed ULIDs: run_01H.... The organisation comes from your credentials, never the request body; project-scoped calls take project_id
Timestamps and durations google.protobuf.Timestamp and Duration
Free-form JSON google.protobuf.Struct

Next: Authentication, Pagination and filtering, Errors, Streaming, Webhooks and events.