Preview environments
Open a short-lived Aviato environment for each pull request from CI, so reviewers see the back-office against the pull request's database.
A preview environment is an environment of your project that CI opens for a pull request and Aviato removes when it expires. Reviewers switch to it in the dashboard and see the back-office, your plugin's actions and the schema of the pull request's database, before the change reaches staging or production.
A preview is an ordinary environment with its own connector, credential and audit trail, and the same members and roles as the project. It differs in four ways:
- It expires. Each preview has an expiry, 72 hours by default, between 1 hour and 30 days. Opening it again extends it. Aviato checks every five minutes and removes expired previews, as it does when you close one.
- It has its own limit. Previews do not count against the plan's environments per project. The plan sets how many previews a project can have open at once (see Plans and limits).
- Its audit trail is short. Events of a preview are kept for 7 days at most, or less when your plan's retention is shorter. Audit exports still work. Audit streams (webhooks and S3) leave previews out.
- It accepts no AI agents. The connector of a preview answers MCP requests with
403 mcp_disabled, and Aviato does not register it as an OAuth resource. Connect agents to a standard environment.
Create a preview API key
CI authenticates with a preview API key, which belongs to one project. In the dashboard, open the project's Settings → Environments, then Preview API keys → Create key. Copy the key (it starts with avp_ and is shown once) and store it as a CI secret, for example AVIATO_PREVIEW_KEY.
Only project managers can create and revoke keys: workspace owners, and admins without a custom role on the project. A key acts for the manager who created it. It stops working when that person leaves the workspace or no longer manages the project. Creating and revoking a key is recorded in the project's audit trail; previews opened with the key are recorded with the key as the actor.
Open and close previews
The connector's preview command calls the previews API with AVIATO_PREVIEW_KEY. Set AVIATO_CONTROL_PLANE_URL, the same variable the connector reads, when you run your own control plane (https://api.getaviato.com by default).
aviato-connector preview up --name pr-12 --pull-request-url https://github.com/acme/shop/pull/12
# AVIATO_CONTROL_PLANE_URL=https://api.getaviato.com
# AVIATO_CONNECTOR_TOKEN=avt_pr-1_…
# AVIATO_ENVIRONMENT=pr-12
# AVIATO_DASHBOARD_URL=https://app.getaviato.com/dashboard/…?env=pr-12
aviato-connector preview down --name pr-12up opens the preview, or extends it if it is already open. Either way it returns a new connector token, and the previous token stops working, so run up again on every push and restart the connector with the new token. Names use lowercase letters, digits and -, start with a letter and have at most 31 characters. A preview cannot reuse the name of a standard environment (production, staging…). --ttl-hours sets the lifetime (1–720, default 72) and --format json prints the API's answer instead of variables. Hosted projects pass the preview database with --database-url; self-hosted connectors read it from AVIATO_DATABASE_URL and never send it to Aviato.
Inside GitHub Actions, up also hides the token in the logs and writes step outputs: control_plane_url, connector_token, environment, dashboard_url and expires_at. down succeeds when the preview is already gone.
GitHub Actions
The workflow below opens a preview when a pull request opens or changes, runs its connector against the pull request's database, comments the dashboard link, and closes the preview when the pull request closes. The connector must be reachable from your reviewers' browsers at AVIATO_PUBLIC_URL, so run it where your pull request deployments run. The docker run step stands for that deployment.
name: Aviato preview
on:
pull_request:
types: [opened, synchronize, reopened, closed]
jobs:
preview:
if: github.event.action != 'closed'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Open the preview
id: preview
env:
AVIATO_PREVIEW_KEY: ${{ secrets.AVIATO_PREVIEW_KEY }}
run: |
docker run --rm -e AVIATO_PREVIEW_KEY -e GITHUB_OUTPUT=/github/output -v "$GITHUB_OUTPUT:/github/output" \
getaviato/connector:0.3.0 preview up \
--name pr-${{ github.event.number }} --pull-request-url ${{ github.event.pull_request.html_url }}
# Your preview platform: deploy the connector next to the pull request's database.
- name: Run the connector
run: |
docker run -d --name aviato-pr-${{ github.event.number }} -p 8080:8080 \
-e AVIATO_CONTROL_PLANE_URL=${{ steps.preview.outputs.control_plane_url }} \
-e AVIATO_CONNECTOR_TOKEN=${{ steps.preview.outputs.connector_token }} \
-e AVIATO_DATABASE_URL=${{ secrets.PREVIEW_DATABASE_URL }} \
-e AVIATO_PUBLIC_URL=https://aviato-pr-${{ github.event.number }}.preview.example.com \
getaviato/connector:0.3.0
- name: Comment the dashboard link
uses: marocchino/sticky-pull-request-comment@v2
with:
header: aviato-preview
message: |
Aviato back-office for this pull request: ${{ steps.preview.outputs.dashboard_url }}
(expires ${{ steps.preview.outputs.expires_at }})
close:
if: github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- name: Close the preview
env:
AVIATO_PREVIEW_KEY: ${{ secrets.AVIATO_PREVIEW_KEY }}
run: docker run --rm -e AVIATO_PREVIEW_KEY getaviato/connector:0.3.0 preview down --name pr-${{ github.event.number }}These commands need connector 0.3.0 or later; keep the version pinned. If a pipeline never closes a preview, it is removed when it expires.
Previews API
The command wraps three HTTP endpoints. Send the key as Authorization: Bearer <key> or x-api-key.
| Request | Effect |
|---|---|
PUT /v1/previews/{name} | Opens or extends the preview. Body (JSON, every field optional): ttlHours (1–720, default 72), pullRequestUrl, databaseUrl (hosted projects only). Answers { environment, connectorToken, controlPlaneUrl, dashboardUrl, expiresAt, created }. |
DELETE /v1/previews/{name} | Closes the preview. Answers 204, also when it is already gone. |
GET /v1/previews | Lists the project's open previews: { previews: [{ name, expiresAt, pullRequestUrl, connectorUrl, dashboardUrl, createdAt }] }. |
curl -X PUT https://api.getaviato.com/v1/previews/pr-12 \
-H "Authorization: Bearer $AVIATO_PREVIEW_KEY" -H "content-type: application/json" \
-d '{"ttlHours": 72, "pullRequestUrl": "https://github.com/acme/shop/pull/12"}'Errors use the standard JSON shape (statusCode, message): 400 for an invalid name or body, 401 for a missing or invalid key (or one whose creator no longer manages the project), 403 when the plan's preview limit is reached, 409 when the name belongs to a standard environment, and 429 past 120 requests per minute per key.