Documentation Index
Fetch the complete documentation index at: https://docs.agentmark.co/llms.txt
Use this file to discover all available pages before exploring further.
A new app starts with one environment, dev, that tracks your branch HEAD live. Create staging and prod to run the same code at pinned, immutable versions — and promote from one environment into another when a version is ready to ship.
Why environments?
Without environments, every push to your connected branch is the only thing your prompts and code can serve. That’s fine while you’re experimenting on dev — but it leaves no place to test a release candidate against real traffic, and no way to keep an older version live while you iterate on the next.
Environments solve both:
dev stays live on HEAD — prompt-only and dataset-only pushes show up instantly, the way iteration should feel.
staging, prod, and any other env you create are pinned — each runs an immutable version snapshot of your content + code that does not move until you explicitly promote into it.
The version that runs in prod is the one you tested in staging. Pushing a typo fix to dev doesn’t change either.
The dev environment
Every app has exactly one default environment, named dev. It is created automatically with the app and has three behaviors no other env shares:
- Tracks branch HEAD live. Every push to your connected branch deploys to
dev through the normal deployment pipeline — the build cache, handler detection, and commit-message overrides all apply here.
- Cannot be promoted into.
dev is the source of promotions, never the target. Promoting into dev would silently move the live pointer off HEAD, breaking the “dev always reflects my branch” invariant.
- Cannot be deleted. The default env is locked for the lifetime of the app.
dev does not get its own dedicated runtime until something needs one — it runs through the app’s primary deployment machinery. Non-default envs each get their own isolated runtime.
Creating an environment
Open the environment dropdown in the breadcrumb at the top of the dashboard and click New environment.
The dropdown shows every env on the app suffixed with its pin state — default for dev, no-pin for a freshly created env, or the version number (v1, v3) for a pinned env. The same menu hosts New environment, and — when the selected env is not dev and you hold environment.promote — Promote to .
Names must match ^[a-z][a-z0-9-]{1,39}$ — lowercase letters, digits, and hyphens, starting with a letter, 2–40 characters. Common choices are staging, prod, preview, eu, tenant-acme.
A newly-created env starts in the no-pin state: the runtime is provisioned but no version has been promoted into it yet. Until the first promote, the env serves nothing.
Creating an env does not auto-mint an API key. The post-create dialog links straight to the API keys page filtered to the new env so you can mint one scoped to it. Keys are scoped per env, so a prod key cannot reach staging traces, templates, or datasets.
The number of environments you can create per app depends on your tier. When you hit the limit, env creation fails with a message naming your current plan — upgrade to add more.
Promoting between environments
A promotion copies one environment’s current content and rebuilds its code into another environment. The target env’s version counter advances by one, its runtime rebuilds, and its pin moves to the new version.
Opening the dialog
Promote is always launched from the target — the env you’re promoting into:
- In the breadcrumb, switch to the env you want to promote into (
staging, prod, etc.).
- Open the env dropdown and click Promote to .
- In the dialog, pick the source env from the dropdown and (optionally) add a note explaining why.
- Click Promote to .
The dialog always shows the direction as a banner: source → target. You can change the source, but the target is fixed by the env you triggered the action from. This is intentional — promotions have a direction, and the UI never lets it go ambiguous.
The source dropdown annotates each option with its current pin state (dev (unpinned), prod (v1)) so you can see at a glance which commit each source would send. The target env is excluded from the source list — an env cannot promote into itself.
What gets promoted
A promote takes the source’s current content and the commit it was built from, and applies both to the target:
- Content — prompt templates (
.prompt.mdx), components (.mdx, .md), datasets (.jsonl), and schemas. A fresh env-keyed snapshot is written for the target, so its content is fully independent of the source going forward.
- Code — the target’s runtime is rebuilt at the source’s commit. The same build cache, env vars, and handler detection rules from the deployment pipeline apply.
The source supplies the commit, not the latest of its branch — so what you tested is what gets promoted:
| Source state | Commit promoted |
|---|
Pinned env (e.g. staging at v3) | The env’s current pinned commit |
dev or any no-pin env | The branch’s current HEAD |
Rules
- Target cannot be
dev. The default env tracks branch HEAD; pinning it would break that invariant. The dialog hides dev from anywhere it would appear as a target.
- Source cannot equal target. Promoting an env into itself is rejected; the dialog drops the target from the source dropdown.
- The app needs a git connection. Promote builds code against a commit, so the app must have a linked repository. Promoting from an app with no git connection returns 400.
- Permission required. Only roles that hold
environment.promote see the action.
Versions
Each non-default env has a monotonic current_version counter. A successful forward promote advances it by one — v1, v2, v3. The version that the env is currently pinned to is shown next to its name in the breadcrumb dropdown (prod · v3).
dev is always at current_version: 0 — it has no pin to count.
Watching a promotion run
When you submit a promotion, the API returns immediately as soon as the content snapshot is written and the env pointer is committed. The code build runs asynchronously after that. The dialog stays open and shows a live progress view with two sub-status rows:
- File sync — writing the env-keyed content snapshot. Completes before the API returns; the dialog shows this as already done.
- Code build — the managed build that produces the target’s new runtime. This is what the progress view is actively polling.
Closing the dialog mid-build does not cancel the promotion — the build keeps going. While a promotion is in flight, the env shows a Deploying… badge next to its name on the Settings → General page, so you can come back to it from anywhere.
The overall status collapses onto one of three values:
| Status | Meaning |
|---|
| In progress | Either the env-level commit or the code build is still working. |
| Deployed | The content commit succeeded and the build settled (either deployed or skipped via cache hit). |
| Failed | Any one of the steps failed; the env stays on its previous version. |
A failed promotion does not change the target’s pin or its current_version — you can fix the underlying cause and click Retry to re-run the same promotion, or close the dialog and trigger a fresh one.
Deployment history
The Deployments tab on each env shows every promotion targeting that env in reverse chronological order. Each card surfaces:
- The short commit SHA the build ran against
- A Promotion type chip and the deployment status pill
- The two pipeline steps — File Sync and Code Deploy — with each step’s outcome
- The actor who triggered the promotion and how long ago it ran
This is the audit log for “what version did prod run between Tuesday and Friday?”. It is per-env: history entries belong to the env they targeted and stay on it for the life of the app.
The GET /v1/environments/{id}/deployments endpoint returns more detail than the cards show — including the pinned env_version, the source env id, and the promotion note. Use it when you need the full audit record programmatically.
Permissions
Environment actions are gated by these per-app permissions:
| Permission | Action |
|---|
environment.read | See the env dropdown and per-env settings |
environment.insert | Create a new environment |
environment.promote | Promote into an environment |
environment.delete | Delete a non-default environment (with typed-name confirmation) |
See Users and access control for how permissions roll up into roles, and API keys for scoping a key to a specific env.
API reference
The same actions are available over the API. Every endpoint is scoped to the app passed in the X-Agentmark-App-Id header. See the API reference — Environments tag — for full request and response schemas.
| Method | Path | Description |
|---|
GET | /v1/environments | List environments for the app (default env first) |
POST | /v1/environments | Create a non-default environment |
GET | /v1/environments/{id} | Get one env, including a cascade-preview for delete |
DELETE | /v1/environments/{id} | Delete a non-default env (requires typed-name confirmation in the body) |
POST | /v1/environments/{id}/promote | Promote a source env into this one; returns the new deployment |
GET | /v1/environments/{id}/deployments | List promotion history for an env |
A POST .../promote returns 202 Accepted with the new deployment_id and env_version. The content snapshot and env-pointer commit are already done by the time the response lands; the build runs asynchronously. Poll GET /v1/deployments/{deploymentId} and watch code_status until it reaches deployed (success) or failed.
# Promote staging into prod
curl -X POST https://api.agentmark.co/v1/environments/$PROD_ENV_ID/promote \
-H "Authorization: Bearer $AGENTMARK_API_KEY" \
-H "X-Agentmark-App-Id: $AGENTMARK_APP_ID" \
-H "Content-Type: application/json" \
-d '{
"source_environment_id": "'"$STAGING_ENV_ID"'",
"note": "Release 2026-05-29 — sign-off in #releases"
}'
Related reading
Have Questions?
We’re here to help! Choose the best way to reach us: