# Service

A workload in an environment — its source, runtime, optional mode, declared domains, and live status. Identified by id; named uniquely within the environment.

**Attributes** (`ServiceDto`)

- `id` · `string` · read-only — Unique identifier of the service (read-only).
- `name` · `string` · required — Service name — lowercase letters, digits and dashes (3–16 chars, starts with a letter). The name is the service identity within the environment: renaming creates a new service.
- `type` · `"web" | "postgres" | "redis"` · required — Service kind: `web` runs your own code; `postgres`/`redis` are managed addons.
- `cpu` · `integer` · required — CPU limit in millicores (250, 500, or whole-vCPU multiples of 1000).
- `memory` · `integer` · required — Memory limit in MiB (256, 512, or whole-GiB multiples of 1024).
- `exposed` · `boolean` · required — Whether the service is publicly reachable with its own URL (web services only).
- `source` · `object` · optional — Where the deployable artifact comes from.
  - `type` · `"git" | "image" | "archive"` · required — Which source kind supplies the deployable artifact.
  - `git` · `object` · optional — Git-repo source config; set when type is git.
    - `provider` · `"github"` · required — Git hosting provider the repo lives on.
    - `repoUrl` · `string <uri>` · required — Clone URL of the source repository.
    - `branch` · `string` · required — Branch built and deployed from.
    - `autoDeploy` · `boolean` · optional — Auto-deploy a new build when the connected branch receives a push. Off by default — opt in per service (requires the git-auto-deploy plan feature).
  - `image` · `object` · optional — Prebuilt-image source config; set when type is image.
    - `ref` · `string` · required — Container image reference (registry/repo:tag) to deploy.
- `imagePullCredentialsSet` · `boolean` · read-only — Read-only: true when private-image registry credentials are stored for this service. The credentials themselves are never returned.
- `runtime` · `object` · optional — Runtime configuration (port, protocol, health check, entrypoint). Variables are managed separately.
  - `port` · `integer` · optional — Port the container listens on for inbound traffic.
  - `protocol` · `"http" | "http2"` · optional — Application protocol spoken on the port.
  - `healthCheckPath` · `string` · optional — HTTP path the platform probes for readiness/liveness (e.g. `/health`). Omit for the default TCP check.
  - `entrypoint` · `object` · optional — Container entrypoint override, exec form — passed 1:1 to the container with no shell wrapping. Omitted parts fall back to the image ENTRYPOINT/CMD.
    - `command` · `string` · optional — The executable to run (overrides the image ENTRYPOINT).
    - `args` · `string[]` · optional — Arguments passed to the command (override the image CMD).
- `serverless` · `object` · optional — Present when the service runs as a scale-to-zero serverless workload.
  - `enabled` · `boolean` · required — Run as a scale-to-zero serverless workload.
- `cron` · `object` · optional — Present when the service runs as a scheduled cron job.
  - `enabled` · `boolean` · required — Run as a scheduled cron job (takes no traffic).
  - `schedule` · `string` · optional — Cron schedule (5-field expression, e.g. `0 2 * * *`) — required when enabled.
- `volume` · `object` · optional — Present when the service has an attached persistent volume.
  - `id` · `string` · required — Id of the persistent volume backing this service.
  - `mountPath` · `string` · required — Path the volume is mounted at in the container.
  - `sizeGb` · `integer` · required — Current size of the volume in GB.
  - `name` · `string` · read-only — The volume's friendly, service-independent name (a random two-word name).
- `locations` · `object[]` · required — Locations this service runs in, each with its replica count.
  - `name` · `string` · required — Location name (a subset of the environment’s locations).
  - `replicas` · `integer` · optional — Replica count in this location. Standard web: fixed count. Serverless: the max-scale ceiling (scales 0→replicas on demand). Cron/volume: no replica concept (normalized to 1).
- `domains` · `object[]` · required — Read-only: the custom domains routing to this service, with DNS records + live status.
  - `hostname` · `string` · read-only — Fully-qualified hostname bound to the service (e.g. app.example.com).
  - `mode` · `"cname" | "ns"` · read-only — DNS mode: `cname` (apex + subdomains, routed via a CNAME to the edge) or `ns` (NS delegation).
  - `status` · `"pending" | "verifying" | "active" | "error"` · read-only — Lifecycle state of the domain binding.
  - `statusReason` · `string | null` · read-only — Why the domain is in an error state, when known — otherwise null. Human-readable.
  - `dnsRecords` · `object[]` · read-only — DNS records to create at your registrar to validate and route the domain.
    - `type` · `"TXT" | "CNAME" | "ALIAS" | "NS" | "A"` · read-only — DNS record type the user must create.
    - `name` · `string` · read-only — DNS record name/host to set at the registrar.
    - `value` · `string` · read-only — DNS record value/target to set at the registrar.
- `status` · `object` · read-only — Read-only: live status of the service.
  - `applied` · `"pending" | "applied" | "error"` · read-only — Pipeline axis: is the desired spec applied to the platform? `pending` = not (yet) applied — a fresh service, an unprovisioned org, or nothing to deploy yet (paired with `build: pending`); `applied` = the current spec is applied; `error` = the last apply/deploy failed (see `errors`). Says NOTHING about runtime health — that is the separate `health` axis.
  - `build` · `"pending" | "building" | "built" | "failed"` · read-only — Build axis — present only for services built from source (git/archive): `pending` = no build yet, `building` = the image builder is running, `built` = image pushed, `failed` = the build failed (see `errors`).
  - `health` · `"online" | "degraded" | "offline" | "sleeping" | "ready"` · read-only — Runtime axis — is it up? Always present; defaults to `offline` and is sticky (never "unknown"). `online` = every location running the latest version, `degraded` = some locations running and some not (see `warnings`), `offline` = nothing running — which also covers a service that is still rolling out, since a version that has not become ready yet is not running. Serverless additionally reports `sleeping` (scaled to zero, wakes on traffic); cron services report `ready` (deployed & scheduled).
  - `errors` · `object[]` · read-only — Fatal failures, one entry per failing axis. Empty when nothing is failing.
    - `source` · `"applied" | "build" | "deploy" | "health"` · read-only — Which axis produced this entry: `applied` = the spec could not be applied to the platform; `build` = the image build failed; `deploy` = the deploy pipeline failed (e.g. deadline); `health` = the running workload is failing (crash, image pull, not ready).
    - `code` · `"dns_propagating" | "image_pull_failed"` · read-only — Stable machine-readable tag, present only on entries whose meaning a client may safely branch on (append-only — tolerate unknown values). Absent entries carry `message` alone.
    - `resource` · `string` · read-only — For `applied` failures: the platform resource that failed (e.g. `workload/web`).
    - `message` · `string` · read-only — The real failure detail, verbatim — never fabricated.
    - `at` · `string <date-time>` · read-only — When this failure was first observed (stable while it persists).
  - `warnings` · `object[]` · read-only — Non-fatal notes (e.g. "2 of 3 replicas ready", "running previous version", "hosting org not provisioned yet", or the `dns_propagating` note that the public URL has not resolved yet). Empty when there is nothing to note. A `health` service can be `online` and still carry one.
    - `source` · `"applied" | "build" | "deploy" | "health"` · read-only — Which axis produced this entry: `applied` = the spec could not be applied to the platform; `build` = the image build failed; `deploy` = the deploy pipeline failed (e.g. deadline); `health` = the running workload is failing (crash, image pull, not ready).
    - `code` · `"dns_propagating" | "image_pull_failed"` · read-only — Stable machine-readable tag, present only on entries whose meaning a client may safely branch on (append-only — tolerate unknown values). Absent entries carry `message` alone.
    - `resource` · `string` · read-only — For `applied` failures: the platform resource that failed (e.g. `workload/web`).
    - `message` · `string` · read-only — The real failure detail, verbatim — never fabricated.
    - `at` · `string <date-time>` · read-only — When this failure was first observed (stable while it persists).
  - `url` · `string <uri>` · read-only — The service’s public address (exposed services only). Sticky for display: set once the service has first gone live, kept across later unready states, cleared only when the service is unexposed. Whether it is currently UP is the `health` axis, not this field.
  - `lastDeployment` · `object` · read-only — Pointer to the most recent deployment. Fetch the deployment itself for its pipeline status and per-phase timestamps — no status is duplicated here.
    - `id` · `string` · read-only — Identifier of the most recent deployment.
    - `version` · `integer` · read-only — Monotonic version number of the deployment.
  - `appliedAt` · `string <date-time>` · read-only — When the desired spec last successfully applied to the platform. Never cleared.
  - `statusObservedAt` · `string <date-time>` · read-only — When the runtime status was last observed ("status as of").
- `internalHost` · `string` · read-only — Read-only: the internal DNS host other services reach this one at, for service-to-service wiring.
- `connection` · `Record<string, string>` · read-only — Read-only: non-secret connection details for a managed addon (postgres/redis).

**Example `ServiceDto`**

```json
{
  "id": "svc_01example0000000000000000x",
  "name": "my-app",
  "type": "web",
  "cpu": 1,
  "memory": 1,
  "exposed": true,
  "source": {
    "type": "git",
    "git": {
      "provider": "github",
      "repoUrl": "https://example.com",
      "branch": "example",
      "autoDeploy": true
    },
    "image": {
      "ref": "example"
    }
  },
  "imagePullCredentialsSet": true,
  "runtime": {
    "port": 8080,
    "protocol": "http",
    "healthCheckPath": "example",
    "entrypoint": {
      "command": "example",
      "args": [
        "example"
      ]
    }
  },
  "serverless": {
    "enabled": true
  },
  "cron": {
    "enabled": true,
    "schedule": "example"
  },
  "volume": {
    "id": "svc_01example0000000000000000x",
    "mountPath": "example",
    "sizeGb": 0,
    "name": "my-app"
  },
  "locations": [
    {
      "name": "my-app",
      "replicas": 1
    }
  ],
  "domains": [
    {
      "hostname": "example",
      "mode": "cname",
      "status": "pending",
      "statusReason": "example",
      "dnsRecords": [
        {
          "type": "TXT",
          "name": "my-app",
          "value": "example"
        }
      ]
    }
  ],
  "status": {
    "applied": "pending",
    "build": "pending",
    "health": "online",
    "errors": [
      {
        "source": "applied",
        "code": "dns_propagating",
        "resource": "example",
        "message": "example",
        "at": "2026-01-01T00:00:00.000Z"
      }
    ],
    "warnings": [
      {
        "source": "applied",
        "code": "dns_propagating",
        "resource": "example",
        "message": "example",
        "at": "2026-01-01T00:00:00.000Z"
      }
    ],
    "url": "https://example.com",
    "lastDeployment": {
      "id": "svc_01example0000000000000000x",
      "version": 3
    },
    "appliedAt": "2026-01-01T00:00:00.000Z",
    "statusObservedAt": "2026-01-01T00:00:00.000Z"
  },
  "internalHost": "example",
  "connection": {
    "key": "example"
  }
}
```
