The map
These overlap less than their names suggest. Pick by the question you are trying to answer.
| You want… | Use | Configured by |
|---|---|---|
| TestVibe to be able to send email at all | You, in the admin console | |
| a failing run to become a Jira ticket | Connectors | A workspace owner/admin, in Settings |
| to seed or reset your test environment before a run, and tear it down after | Hooks | Per project, in Settings |
| to be told when something finishes or breaks | Notifications | Each user, for themselves |
| tests to run on a schedule, or in reaction to another run | Automations | Per project, in the app |
| to drive TestVibe from CI or a script | API / CLI / MCP | Each user, via an API key |
What can reach your network
The most valuable thing this page can tell a self-hosted administrator: two of these deliberately cannot call an address inside your own network, and no setting changes that. Plan around it rather than debugging it.
| Feature | Calls out from | Can it reach a private address? |
|---|---|---|
| Hooks | The application | No — loopback and private ranges are blocked outright, with no opt-out. |
| Notification webhooks | The application | No — restricted to a fixed list of public chat hosts. |
| The application | Yes — your own SMTP relay, wherever it is. | |
| Connectors | The application | Yes — a self-managed GitLab, Jira Data Center or Azure DevOps Server URL is accepted. |
| The site under test | The test runner | Yes — that is the whole point of self-hosting. |
http://10.1.2.3/reset or
http://internal.corp/seed is rejected when it is saved. Expose the
endpoint on a routable address, or use the correlation approach in
section 05 to have the tests themselves do the work.
Optional, but you will want it. TestVibe runs fine with no mail at all, and nobody is blocked from signing in. But several useful things quietly do nothing until you set it up. This is the only page in the guide that explains how.
What works without it, and what does not
| Works with no mail | Needs mail |
|---|---|
| Creating the first user — done in the console's First user panel, already verified. | Password resets. Without mail a locked-out user has no way back in on their own. |
| Adding everyone else — Settings → Members → Invite produces a copyable link you can send however you like. | Run, generation and load-test notifications. Email is every user's default channel, so with no relay nobody is told anything. |
| Signing in, generating, running tests — all of it. | Emailed invitations (the copy-link path still works) and the output of an assistant automation, which is delivered by email. |
Setting it up
Everything is in the admin console under Mail. There are two ways to send, and you pick one.
- Choose a transport.
- Your own SMTP relay — preferred, and the only option that works without outbound internet.
- Mandrill — one HTTPS call per message to
mandrillapp.com, with no relay to run, but this install then needs outbound internet. SetTESTVIBE_MANDRILL_API_KEY(Mandrill API key). Your from address must be on a domain verified in your Mandrill account or every message is rejected.
- Fill in the fields for the transport you chose (table below).
- Set a from address on a domain your relay will accept. Most relays reject a sender on a domain they do not own.
- Press Send test message. You should receive the test mail. Do not move on until you do — every other mail problem in this product traces back to this step.
| Console field | Key | Notes |
|---|---|---|
| SMTP relay host | TV_SMTP_HOST | The relay TestVibe hands messages to. Leave every mail field blank to disable email entirely. |
| Port | TV_SMTP_PORT | Default 587 (submission, STARTTLS) or 25 (internal relay). Implicit-TLS port 465 is not supported — use 587, which every mainstream relay also offers. |
| Use STARTTLS | TV_SMTP_USE_TLS | On by default. Leave it on unless this is an internal relay on a trusted network that does not offer TLS. |
| Username | TV_SMTP_USERNAME | Leave blank if the relay authorises this host by IP instead of credentials. |
| Password or app token | TV_SMTP_PASSWORD | Stored encrypted. Office 365 and Google Workspace need an app password or a dedicated service account here, not a user's own password. |
| From address | TESTVIBE_EMAIL_SENDER_ADDRESS | Required. |
| From name | TESTVIBE_EMAIL_SENDER_NAME | Default TestVibe. |
.env.example and the Helm
values.yaml carry no TV_SMTP_* keys at all,
and the compose web service does not forward them — so a value you add to
.env is simply ignored, with no error. Use
Console → Mail. To manage it as code anyway, add the variables
to the web service's own environment (web.extraEnv on Kubernetes); the
console then shows them locked.
One more optional field lives here: TESTVIBE_SIGNUP_NOTIFY_EMAIL
(Notify on new sign-ups) tells an address of yours when someone registers.
Blank means nobody is notified — this install never reports sign-ups outside your
network.
Connectors
For: turning a failure into a ticket in the system your team already uses — by hand from the run, or automatically every night.
How it is put together
- A connection is the credential, and it belongs to the workspace. Created once, in Settings → Connectors, by an owner or admin. It is encrypted at rest and never returned to a browser.
- A binding says what this project uses that connection for, and which target — which Jira project, which repository. It holds a pointer, never a credential.
| Provider | Files issues? | What the user supplies |
|---|---|---|
| Jira | Yes | Site URL, account email, API token. Works against a self-managed site — put its URL in the Site URL field. |
| GitLab | Yes | GitLab URL (defaults to gitlab.com — change it for self-managed) and a
personal access token with the api scope. |
| Azure DevOps | Yes | Organization and a PAT with Work Items (Read & Write). |
| GitHub | Yes, with setup | A GitHub App installation — see the note below. No token is stored; a scoped installation token is minted per call. |
| Slack, Mattermost | Not yet | An incoming webhook URL. They are connectable and the credential is stored, but no feature consumes a chat connection yet. For chat alerts today, use Notifications. |
GitHub__AppId (or
GITHUB_APP_ID) and GitHub__PrivateKeyPem (or
GITHUB_APP_PRIVATE_KEY_PEM). Neither appears in the Compose
.env template, the Helm values or the appliance environment file, so you
must register your own GitHub App and add them yourself. Until you do, the GitHub
connector cannot mint a token. Jira, GitLab and Azure DevOps need none of
this — a token in the connect form is enough, so start there.
What it does once connected
- A File issue button appears on run, load-run and generation detail screens, one per connection that can file issues. Automations can file issues too, and an automated ticket is identical to a hand-filed one.
- The issue body carries the permanent TestVibe deep link and names the artifacts. It deliberately does not embed artifact links — those expire, and a dead link in a two-year-old ticket helps nobody.
- Repeat failures with the same signature comment on the existing ticket rather than opening a new one each night. A person clicking the button always gets a new ticket, because they meant it.
Connector credentials are separate from the jira test plugin's
credentials, deliberately. The plugin runs inside the test sandbox; connectors run in
the application. Same service, different privilege boundary — do not reuse one token
for both.
Setup & cleanup hooks
For: "call my API to seed a tenant before the suite, and tear it down after." A REST call TestVibe makes on your behalf around a run, a load test or a generation.
How a hook works
- Six events: before and after each of run, load test and generation. Suite-level only — there are no per-scenario hooks, because scenarios run in parallel and concurrent "reset the database" calls would stomp each other.
- Five fields: name, event, URL, failure policy, enabled. That is the whole configuration surface, on purpose.
- TestVibe sends a fixed JSON body and reads only the status code. No custom body, no custom headers, no response parsing — the same contract GitHub and Stripe webhooks use.
- A before hook can refuse. With the failure policy set to fail, a non-2xx response stops the run before any capacity is taken. An after hook can never block.
- Signed with a
TestVibe-Signatureheader —t=<unix>,v1=<hex HMAC-SHA256>over"{t}.{body}", Stripe's construction, so most integrators already have verification code. The secret is shown exactly once when the hook is created. - Fixed 30-second timeout and two retries.
Correlating a hook with the tests it set up
Both sides see the same value. The hook payload carries a per-run unique
token, and the tests get the same value as the TESTVIBE_RUN_UNIQUE
environment variable. So your endpoint creates tenant-<unique> and
the tests find it, with nothing parsed out of the hook's response.
That is also the answer when the private-address restriction bites: if your seeding endpoint cannot be exposed, have the tests do the seeding, keyed on the same value. Tests run in the runner, which can reach your network.
Hook operator notes
- Hooks run in the application, not in the test sandbox. That is why they get secrets and retries — and why section 02 applies to them.
- A run blocked by a failing before-hook ends as error with a banner naming the hook. It is not a test failure, and no capacity was consumed.
- Three consecutive failures of a blocking hook force a notification even for scheduled runs, which are otherwise quiet — so a broken hook cannot kill a nightly schedule in silence.
- The execution log stores failure responses but never a successful one — a setup endpoint's 200 is the response most likely to contain a freshly-minted credential.
- Where: Settings → Project → Hooks. Use the Send test request button, because it is the only place a successful response body is ever shown.
Notifications
For: telling a person that a run, generation or load test finished — outside the app. Per user, on by default. Operators provide nothing here except the mail relay; each user picks their own channels in Settings → Notifications.
Channels
| Channel | Target | On a self-hosted install |
|---|---|---|
| The user's verified address, or another they add. | Works anywhere — through your relay. | |
| Slack | An incoming webhook on hooks.slack.com. |
Needs internet |
| Google Chat | A space webhook on chat.googleapis.com. |
Needs internet |
| Microsoft Teams | A Workflows webhook on webhook.office.com or
logic.azure.com. |
Needs internet |
Per channel and per event type — run, generation, load — a user chooses all, failures only, or off. Cancellations never notify.
notify: true on the REST body or --notify on the CLI. Runs
dispatched from the interface always notify normally.
Automations
For: "run the suite every night at 2am", "file a ticket whenever a run fails", "have the assistant investigate and tell me the root cause". A trigger → condition → action engine, configured per project in the app.
Triggers
- On a schedule — chosen from presets, with a timezone. There is no raw cron field.
- On an event — a run finishing, optionally filtered to failures.
Actions
- Run features — the whole suite as one run, or a subset.
- Run a load test.
- Run an assistant job — one headless assistant turn against a prompt, emailed to you.
- Create an issue in a connected tracker.
There is also a per-automation AI triage on failure toggle: when a run this automation triggered fails, the assistant investigates and the outcome carries a root cause instead of just "failed" — shown on the run, in the failure notification, and in the automation's history.
Automation operator notes
- Scheduling is safe across restarts and replicas. A due automation is claimed atomically, so a restart mid-tick cannot double-fire and a second instance cannot either.
- An automation-produced run cannot re-trigger an automation. There is a loop guard; you will not wake up to a runaway chain.
- Time zone matters. A blank or unrecognised timezone is treated as UTC. On a "why did it run at the wrong time" question, check that field first.
- Automations consume capacity like any other dispatch. Several nightly schedules landing on the same minute will queue against your concurrency caps — see Capacity.
- Assistant automations run inline on the scheduler tick with a 5-minute ceiling, so many of them due at once will serialise. Their output arrives by email.
- Automation-dispatched runs are silent by default — see section 06. Enabling AI triage makes its failures deliver anyway, because you opted in.
API, CLI and MCP
For: CI pipelines, scripts, and AI coding tools. One core behind three surfaces — an HTTP API, a command-line tool, and an MCP server that plugs TestVibe into an AI assistant.
What a user needs
- An API key. Created in the application under
Settings → CLI & API keys. Keys begin
tvb_and are shown once. They are sent asAuthorization: Bearer tvb_…. - Your install's address. Everything is under
{your base URL}/api/v1/ops. There is no TestVibe-hosted endpoint involved. - The CLI, if they want one. You should see your projects listed
back.
shell
npm install -g testvibe export TESTVIBE_SERVER=https://testvibe.example.com export TESTVIBE_API_KEY=tvb_… testvibe projects
The same package runs as an MCP stdio server, so an AI assistant can drive the same operations.
TESTVIBE_PROJECTpins a default project.
API operator notes
- Plan gating does not apply. On the cloud, programmatic access is a paid capability; on a self-hosted install that check is skipped entirely. Every workspace has full API, CLI and MCP access.
- You can still put a ceiling on it.
TESTVIBE_OPS_RATE_LIMIT_PER_HOURcaps requests per workspace per hour when set — unset means no per-workspace limit on self-hosted. A separate per-IP limiter,TESTVIBE_OPS_RATE_LIMIT_IP_PER_HOUR, defaults to 10,000 per hour. Both are environment-only; neither is in the console. Clients get the standardRateLimit-*response headers whenever limiting is on. - The API is a full control plane — it can create features,
dispatch runs and generations, and edit project files. Treat a
tvb_key as equivalent to the user's access, and make sure your reverse proxy is not caching authenticated responses.
Where to go next
- Capacity — what happens when automations and CI dispatch at the same time.
- Licensing · Sign-in · AI providers · Storage.
- The setup checklist — the rest of the first-hour configuration.
- Product documentation — the per-feature reference your users will want.