Cutting releases

A deploy tells i3deploy that something shipped. A release tells it what changed — the changelog your team and your users actually read. i3deploy models that at two levels:

  • A ServiceRelease is one service's version: its commit range, and a changelog in two flavors — changelog_markdown (technical notes) and markdown_users (user-facing notes).
  • A ProjectRelease bundles one or more service releases under a single project-facing version — the thing you'd point an end user at ("what's new in 2.4"). It also carries two changelogs, markdown_users and markdown_techies, so the same release can read differently for end users versus engineers.

Both are tagged authored_by: human or authored_by: ai, so it's always visible whether a changelog was written by a person or drafted by Claude.

Releases can be created two ways: directly against the API, or by asking Claude through the MCP connector.

Via the API

1. Create a service release

curl -X POST https://backend.i3deploy.com/v1/service-releases \
  -H "Authorization: Bearer $I3DEPLOY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "service": "web",
    "version": "1.4.2",
    "commit_sha": "abc123",
    "commit_range": "v1.4.1..v1.4.2",
    "changelog_markdown": "- web: fixed checkout redirect loop",
    "markdown_users": "- Fixed a bug where checkout could redirect in a loop",
    "short_summary": "Fix checkout redirect loop"
  }'

service is the service's slug, scoped to your organization. version + service must be unique together — you can't create two releases for the same service/version pair.

2. Bundle it into a project release

curl -X POST https://backend.i3deploy.com/v1/project-releases \
  -H "Authorization: Bearer $I3DEPLOY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "marketing-site",
    "title": "2.4",
    "short": "Checkout fixes and a faster homepage",
    "version_numeric": "2.4.0",
    "markdown_users": "## 2.4\n\n- Fixed a checkout bug that could loop the redirect\n- Faster homepage load",
    "markdown_techies": "## 2.4\n\n- web: fixed checkout redirect loop (abc123)\n- api: added response caching for /homepage",
    "published": true,
    "service_releases": [
      {"service": "web", "version": "1.4.2"}
    ]
  }'

project is the project's slug. version_numeric is the release's version string (semver-ish — i3deploy parses it into major/minor/patch for ordering); title is a separate, freeform headline that doesn't have to be just the version number. service_releases takes {service, version} pairs referencing already-created service releases — create those first, then bundle them. Every referenced service must belong to the same organization as project, or the request is rejected. Set published: true (the default) when the release should show up in the public manifest right away; set it false to stage the changelog before flipping it live.

On read, service_releases comes back expanded (service, version, commit_sha, authored_by) instead of the write-only {service, version} pairs you sent.

Via MCP / Claude

Once the MCP connector is wired up, you don't need to touch curl at all — just ask:

"Cut release 2.4 for marketing-site: bundle web 1.4.2, and write a changelog — fixed the checkout redirect loop, faster homepage."

Claude reads the deploys and commits it has visibility into, drafts both a user-facing and a technical changelog, and calls the same service-releases / project-releases write tools under the hood — so the result is identical to calling the API directly, minus writing curl and JSON by hand. Releases authored this way are marked authored_by: ai.

Next

  • API guide — full endpoint reference and auth details.
  • The public manifest — how a published ProjectRelease shows up in the JSON feed that clients read.