Environments
Your voice agent probably runs in several places: a development build, a staging copy and production. CallQA models them as environments, so the same scenarios can run against each one, on their own schedule, and you can compare them before you promote a version.
The basics
- Every organization has one default environment (
productionfor existing accounts). Runs and versions that name no environment go there: older CI jobs, older scenario documents. Add development and staging on the Versions and environments board creates the usual two in one click. - A scenario is activated in the environments where it should run, each with its own schedule, time zone and call window (see below).
- A run belongs to one environment. Pick it with the selector next to Run now,
or with
environmentwhen you trigger from the API or CI. - A version (
v2.4.0, a short sha) belongs to one environment. The same code gets one version per environment it reaches: Promote a version (POST /versions/{id}/promote) when it moves from staging to production. - A phone number can be reached at another number in an environment (for example the
staging line of the same agent). Set it on the environment page, or with
PUT /environments/{env}/numbers. Both numbers must be registered and verified.
Environments are named by slug (staging), name or id everywhere in the API.
Which scenario runs where
The Versions and environments board (Dashboard) shows one column per environment, headed by the version deployed there, with the scenarios activated in it, their schedule and their last verdict. Drag a scenario to a column, or tick scenarios in Add scenarios to an environment, to activate them there.
| Task | Request | Scope |
|---|---|---|
| Environments of a scenario | GET /scenarios/{id}/environments |
read |
| Activate, schedule or pause a scenario in an environment | PUT /scenarios/{id}/environments/{env} |
write |
| Remove a scenario from an environment | DELETE /scenarios/{id}/environments/{env} |
write |
| Scenarios of an environment | GET /environments/{env}/scenarios |
read |
| Activate, pause or remove many scenarios at once | POST /environments/{env}/scenarios |
write |
| The whole board (scenario x environment, versions) | GET /matrix |
read |
curl -sS -X PUT "https://app.callqa.dev/api/v1/scenarios/$SCENARIO/environments/staging" \
-H "Authorization: Bearer $CALLQA_API_KEY" -H "Content-Type: application/json" \
-d '{"enabled": true, "schedule": "every hour", "timezone": "Europe/Paris", "call_window": "08:00-20:00"}'
schedule_enabled: false pauses the schedule without losing it, "schedule": "" removes it.
The same plans can live in the scenario document, so a YAML export round-trips: the top-level
schedule, timezone and call_window are the plan of the default environment, and
environments holds the other ones, keyed by slug. An environment the document does not name
is left as it is.
Environments are never created by an import (a typo would create one): a slug your
organization does not have is refused with 422 invalid_scenario, on the entry at fault, with
the list of your environments and how to add one:
{"detail": "invalid scenario", "code": "invalid_scenario", "errors": [{"loc": "environments.staging", "msg": "Unknown environment 'staging'. This organization's environments: production. Use one of them, remove this entry, or create the environment first (Dashboard > Versions and environments > + Environment, or POST /api/v1/environments), then import again."}]}
The example below needs staging and development: Add development and staging on the
board creates both.
name: "Book appointment - staging and production"
target:
phone: "+14155550100"
persona:
description: "Calm customer"
goal: "Book a haircut for tomorrow 2pm"
schedule: "every day at 09:00"
timezone: "America/New_York"
environments:
staging:
schedule: "every hour"
call_window: "08:00-20:00 America/New_York"
development:
enabled: false
From CI
curl -sS -X POST "https://app.callqa.dev/api/v1/scenarios/$SCENARIO/runs?wait=true&threshold=80" \
-H "Authorization: Bearer $CALLQA_API_KEY" -H "Content-Type: application/json" \
-d '{"environment": "staging", "version": "v2.4.0", "git_sha": "'"$GITHUB_SHA"'"}'
The version v2.4.0 is created in staging if it does not exist there yet. release is the
former name of version and is still read until 2027-03-31.
Compare and follow stability
- Compare environments (
GET /environments/compare?a=staging&b=production, the Compare button of the board): KPIs, per scenario scores and the test cases whose last verdict differs. Adda_version/b_version(version ids) to compare two versions, andscenario_idto focus on one scenario. Growth plan and above. - Stability per environment (
GET /environments/stability?days=30, and a table on the dashboard): tests, pass rate, average score, p95 latency, flaky test cases (both passed and failed in the period) and last run. Growth plan and above. - Filter lists by environment:
GET /runs?environment=staging,/calls?environment=...,/versions?environment=..., and?env=stagingon the dashboard, runs, calls and versions pages. - Webhook endpoints can be restricted to some environments: see Webhooks.
Rules
- Deleting an environment that has runs or versions is refused (
409 environment_in_use): their history stays readable. The default environment cannot be deleted (409 default_required); make another one the default first. - Roles: everyone reads environments; admins and members create and edit them, and activate
scenarios in them; only admins delete them. API scopes:
read,write,admin.