---
id: w2/m5/t003
title: POST /v1/services/{id}/deploys — trigger a deploy
worker: worker2
status: done
estimate: 25m
depends_on: [w2/m5/t001]
---

## Objective

Render's trigger-deploy verb: `POST /v1/services/{id}/deploys` (201 with the new deploy object) starts a fresh rollout — for image-backed services a re-pull/restart (bump `spec.restartedAt` through the store, honoring single-writer-of-intent); for repo-backed services the build path activates when w1/m5 lands.

## Context

- Render's body carries `clearCache` — accept and ignore (documented), the safe-superset rule.
- The trigger must create the deploy row itself (trigger `api`), then let t001's recording close it from status write-back.

## Steps

1. `TriggerDeploy(appID)` verb: open a `dep-…` row, write the restart intent via the store.
2. REST route → 201 + the created deploy object; 404 unknown; 503 store-less.
3. Update `docs/ADR006-bex-api.md`.

## Files

- `lego/backend/internal/apps/service.go` / `rest.go` (or deploys feature)
- `docs/ADR006-bex-api.md`

## Acceptance criteria

- [ ] Trigger returns 201 with a deploy in a non-terminal status; the same deploy later reads `live` via `get_deploy`/REST once pods gate healthy.
- [ ] Suspended services refuse the trigger (409 or Render's documented behavior — verify against the spec and match).

## Out of scope

- Build-from-git triggering (w1/m5); cancel/rollback verbs (deferred until deploy history is proven).
