Skip to Content
SeyloDocs

API reference

The panel's HTTP API - base URL, authentication, request style, errors and rate limits. Every action in the panel is available here.

Edit on GitHub

The API is the same set of actions the web app, the command line, the MCP server and the AI assistant use, generated from one definition per action. Anything you can click, you can call. Each action has its own page in the sidebar, grouped by area, with its request and response schema and the permission it needs.

Base URL

Your panel's own address plus /api/v1/ and the action's id:

https://panel.example.com/api/v1/<action id>

Before the panel has a domain, that is http://<server-ip>:3000/api/v1/.... There is no hosted API: every panel serves its own.

Authentication

Create an API key in Settings → API keys and MCP (see API keys) and send it as a bearer token:

curl https://panel.example.com/api/v1/projects.list \
  -H "Authorization: Bearer $SEYLO_TOKEN"

A key acts as the person who made it, narrowed to the actions and projects picked for it, and read-only keys can only call queries. A call outside its scope gets 403 FORBIDDEN.

The web app uses a session cookie (seylo_session) instead. A request with a bearer token ignores the cookie. Requests that change something with only a cookie must come from the panel's own origin.

MCP tokens (seylo_mcp_...) work here too, but only for the actions that are available to AI tools, and actions that delete something return 403 APPROVAL_REQUIRED until a person approves them (see MCP and AI).

Request style

Each action is one path named after its id: projects.list, deployments.deploy, domains.add.

  • Queries (they only read) are GET with the input as query parameters.
  • Everything else is POST with the input as a JSON body.
curl -X POST https://panel.example.com/api/v1/deployments.deploy \
  -H "Authorization: Bearer $SEYLO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"serviceId": "k3x9q2m7v8w1z0ab"}'

Fields an action does not know are dropped. A successful call answers 200 with the action's output as JSON. Ids are 16 characters of lowercase letters and digits; times are ISO 8601 strings. A request body may be up to 4 MiB; a larger one gets 400 BAD_REQUEST. Source archives go through their own upload endpoint, not through an action.

Long-running actions return right away. A deploy, for example, returns the new deployment; follow it with deployments.get and deployments.log.

Errors

Every error has the matching HTTP status and the same JSON body:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Invalid serviceId: Expected string to match '^[a-z0-9]{16}$'.",
    "details": { "field": "serviceId" }
  }
}

message is safe to show to people. details is optional and holds strings, such as the field that failed validation or a reason. Branch on code, not on the status:

CodeStatusMeaning
BAD_REQUEST400The input failed validation (details.field names the field), or the request makes no sense in this state
UNAUTHENTICATED401No credentials, or the key or session is not valid any more
FORBIDDEN403The caller may not run this action on this resource. details.reason reauth: a browser session needs a sign-in from the last 15 minutes for this action; confirm with auth.reauth, then repeat the call
APPROVAL_REQUIRED403An AI tool called an action that needs a person's approval first
NOT_FOUND404No such resource, or the caller can't see it
CONFLICT409Conflicts with the current state, for example the protected panel service (details.reason says why)
RATE_LIMITED429Too many requests; wait for the seconds in the Retry-After header
INTERNAL500Something broke on the panel; the panel's log has the details
NOT_IMPLEMENTED501The action, or the node it needs, cannot do this yet (for example an agent too old for a feature)
UNAVAILABLE503A node or an outside service needed for this is unreachable (details.reason is offline when the node is)

Rate limits

Each caller gets a bucket of 120 requests that refills at 20 per second. Sign-in and token checks have a stricter bucket: 10 tries, then one every 6 seconds. Over the limit, the answer is 429 RATE_LIMITED with Retry-After.

Same actions, other doors

  • Command line: seylo login, deploy, logs, env and tunnel cover the everyday tasks. See Command line.
  • MCP: the actions available to AI tools are MCP tools, read-only by default. See MCP and AI.
  • The OpenAPI document behind this reference is openapi.json in the app repository, generated from the same definitions.

On this page