> ## Documentation Index
> Fetch the complete documentation index at: https://www.shipfox.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API Reference

> The Shipfox HTTP API: base URL, bearer-token authentication, the user-facing endpoints for projects, definitions, runs, runners, providers, and integrations, and the error shape.

Shipfox exposes an HTTP API that the dashboard uses and that you can call directly to
automate projects, definitions, runs, and runners. This page covers the endpoints
meant for user automation. Endpoints that runners and provisioners use to execute
jobs are a separate machine protocol — see [Internal protocols](#internal-protocols).

## Base URL

The API is served at the root path — there is no version prefix.

* **Managed:** `https://api.shipfox.io`
* **Local / self-hosted:** `http://localhost:16101` by default (the port is
  configurable).

## Authentication

User endpoints authenticate with a **bearer token**. Obtain one by signing in, then
send it in the `Authorization` header.

```bash theme={null}
# Sign in
curl -X POST https://api.shipfox.io/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "…"}'
# → { "token": "<JWT>", "user": {…}, "membership": {…} }

# Call an authenticated endpoint
curl https://api.shipfox.io/workspaces \
  -H "Authorization: Bearer <JWT>"
```

Access tokens are short-lived. `POST /auth/refresh` issues a new one from the
HttpOnly refresh cookie set at login (a browser flow). Runner registration tokens,
job lease tokens, and provisioner tokens are **not** general API credentials — they
belong to the internal protocols below.

## Endpoints

<Note>
  The tables list the primary endpoints per resource; obvious CRUD sub-routes are
  omitted. All require `Authorization: Bearer <JWT>` unless the Auth column says
  otherwise.
</Note>

### Auth & session

| Method | Path                   | Purpose                          | Auth   |
| ------ | ---------------------- | -------------------------------- | ------ |
| POST   | `/auth/signup`         | Create an account                | None   |
| POST   | `/auth/login`          | Sign in; returns an access token | None   |
| POST   | `/auth/refresh`        | Refresh the access token         | Cookie |
| POST   | `/auth/logout`         | Sign out                         | User   |
| GET    | `/auth/me`             | Current signed-in user           | User   |
| POST   | `/auth/password/reset` | Request a password reset         | None   |

### Workspaces

| Method | Path                                    | Purpose                         |
| ------ | --------------------------------------- | ------------------------------- |
| GET    | `/workspaces`                           | List your workspace memberships |
| POST   | `/workspaces`                           | Create a workspace              |
| GET    | `/workspaces/{workspaceId}/members`     | List members                    |
| POST   | `/workspaces/{workspaceId}/invitations` | Invite a member                 |

### Projects

| Method | Path                    | Purpose                                              |
| ------ | ----------------------- | ---------------------------------------------------- |
| POST   | `/projects`             | Create a project bound to a repository               |
| GET    | `/projects`             | List projects (`workspace_id`, pagination, `search`) |
| GET    | `/projects/{projectId}` | Get a project                                        |

### Workflow definitions

| Method | Path                          | Purpose                                         |
| ------ | ----------------------------- | ----------------------------------------------- |
| POST   | `/definitions`                | Create or update a definition from YAML         |
| GET    | `/definitions`                | List definitions (`workspace_id`, `project_id`) |
| GET    | `/definitions/{definitionId}` | Get a definition                                |
| POST   | `/definitions/validate`       | Validate workflow YAML without saving           |

### Workflow runs

| Method | Path                                               | Purpose                                                |
| ------ | -------------------------------------------------- | ------------------------------------------------------ |
| POST   | `/workflow-definitions/{definitionId}/fire-manual` | Fire a manual trigger                                  |
| GET    | `/workflows/runs`                                  | List runs (`project_id`, `status`, `definition_id`, …) |
| GET    | `/workflows/runs/{id}`                             | Run detail with jobs and steps                         |
| POST   | `/workflows/runs/{id}/cancel`                      | Cancel a run                                           |
| POST   | `/workflows/runs/{id}/rerun`                       | Rerun a run                                            |
| GET    | `/steps/{stepId}/attempts/{attempt}/logs`          | Read a page of step logs                               |

### Runners & provisioners

| Method | Path                                                           | Purpose                            |
| ------ | -------------------------------------------------------------- | ---------------------------------- |
| POST   | `/workspaces/{workspaceId}/runners/manual-registration-tokens` | Create a manual registration token |
| GET    | `/workspaces/{workspaceId}/runners/active`                     | List active runners                |
| POST   | `/workspaces/{workspaceId}/provisioners/tokens`                | Create a provisioner token         |
| GET    | `/workspaces/{workspaceId}/provisioners/active`                | List active provisioners           |

### Agent providers

| Method | Path                                                   | Purpose                             |
| ------ | ------------------------------------------------------ | ----------------------------------- |
| GET    | `/agent/provider-catalog`                              | List available providers and models |
| GET    | `/workspaces/{workspaceId}/agent`                      | List configured providers           |
| PUT    | `/workspaces/{workspaceId}/agent`                      | Configure a provider                |
| POST   | `/workspaces/{workspaceId}/agent/{providerId}/default` | Set the default provider            |

See [Model Providers](/reference/model-providers) for the catalog and resolution
rules.

### Integrations & trigger events

| Method | Path                           | Purpose                                  |
| ------ | ------------------------------ | ---------------------------------------- |
| GET    | `/integration-connections`     | List connections (`workspace_id`)        |
| GET    | `/integration-providers`       | List available integration providers     |
| POST   | `/integrations/github/install` | Start a GitHub App installation          |
| GET    | `/trigger-events`              | List received trigger events (audit log) |
| GET    | `/trigger-events/{eventId}`    | Get one trigger event                    |

## Webhook ingest endpoints

These are **provider callbacks**, not user API endpoints — external providers POST
to them with a signature. See Integrations.

| Method | Path                            | Provider                       |
| ------ | ------------------------------- | ------------------------------ |
| POST   | `/webhooks/integrations/github` | GitHub (`X-Hub-Signature-256`) |
| POST   | `/webhooks/integrations/sentry` | Sentry (signed)                |
| POST   | `/webhook/{connectionId}`       | Custom webhook                 |

## Errors

Errors return a JSON body with a stable `code`, optional client-safe `details`, and
an appropriate HTTP status:

```json theme={null}
{ "code": "project-already-exists", "details": { "existing_project_id": "…" } }
```

Common codes include `validation-error` (400), `unauthorized` (401), `forbidden`
(403), `not-found` (404), and resource conflicts like `project-already-exists`
(409). Schema-validation failures use `validation-error` with a `message` naming the
offending field.

## Internal protocols

Runners and provisioners authenticate with their own tokens (runner registration
`sf_mrt_`/`sf_ert_`, runner session, job lease, provisioner `sf_pt_`) against a
separate set of endpoints — claiming jobs, fetching steps, reporting results,
appending logs, and polling for demand. These are an internal machine protocol, not
part of the user API; don't call them directly. See
Runners and Runner provisioners.
