Config as code (GitOps)

Manage assistants, squads, tools and tests as files in git, and promote them from development to production

Config as code keeps your Vapi configuration in files under version control instead of only in the dashboard. Every change to a prompt, tool or squad goes through a pull request. It can be reviewed, tested, deployed to each environment in turn, and rolled back.

Vapi GitOps is an open-source repository that does this for Vapi. Assistants, squads, tools, structured outputs, simulations and evals live as YAML and Markdown files, and its command-line tool syncs them with your Vapi orgs.

Why manage Vapi as code

ConsiderationDashboard onlyConfig as code
HistoryLimited view of who changed whatFull git history for every prompt and setting
ReviewChanges go live when savedChanges are reviewed in a pull request before they deploy
TestingTest after the change is liveSimulations run against each pull request, before merge
EnvironmentsCopy settings between orgs by handThe same files promote from development to production
RollbackRecreate the previous configurationRevert the commit and deploy again
Coding agentsAgents click through a UI or call the API directlyAgents edit files and open pull requests that people review

What the repository gives you

  • Safe sync. npm run apply pulls the latest platform state before it pushes, so edits made in the dashboard aren’t silently overwritten. Every deploy saves a snapshot you can roll back to.
  • Readable references. Files refer to each other by name (toolIds: [lookup-patient]). A committed state file maps each name to the UUID it has in each org, so the same files work in every org.
  • Any number of orgs. Each org is a folder. Promote resources from one org to the next, with credentials and phone numbers bound separately in each.
  • Tests on every pull request. Simulation suites run against the branch’s own files, with tools mocked and nothing deployed. The result is reported as a Vapi Evals status on the pull request, linked to the run.
  • Ready for coding agents. AGENTS.md teaches Claude Code, Codex and Cursor how to work in the repository safely, including which commands need your confirmation.

Get started

1

Create a private copy

Your copy holds your agents’ prompts and configuration, so keep it private. Avoid a public fork, which would publish your configuration.

git clone https://github.com/VapiAI/gitops.git my-vapi-gitops
cd my-vapi-gitops
git remote rename origin upstream
git remote add origin <your-private-repo-url>
git push -u origin main

Keeping the original repository as upstream lets you merge in future updates.

2

Install

You need Node.js 22.13+ or 20.12+, and a private API key for each Vapi org you connect.

nvm use
npm ci
3

Connect an org

npm run setup

The wizard asks for your API key, a name for the org’s folder (for example my-org), and which existing resources to download. It creates .env.my-org, which holds your key and is never committed, and resources/my-org/.

4

Change something and deploy

Edit a file under resources/my-org/, then:

npm run validate -- my-org # check the files offline
npm run apply -- my-org # pull the latest, merge, then push

Commit the changed files and .vapi-state.my-org.json, so your team shares the same name-to-UUID mappings.

The README covers every command and option.

Already running Vapi in production?

You don’t need to rebuild anything. Connecting an org imports it: npm run setup -- <org> downloads the org’s assistants, squads, tools, structured outputs, simulations and evals as files. Commit them, and the repository describes what’s live. Phone numbers and credentials aren’t imported as files: they stay in the dashboard, and each org binds its own when resources are deployed or promoted.

Before your first change:

  • Review what the import found. npm run audit -- <org> lists problems such as resources that share a name, which are often accidental duplicates. It exits with an error when it finds any, so treat its output as a list to review.
  • Preview your first deploy. npm run push -- <org> --dry-run sends nothing and lists what a deploy would do. It should create and delete nothing. Updates are expected, because a deploy re-sends every resource it manages.
  • Leave out what you don’t want managed. Add patterns to resources/<org>/.vapi-ignore. Pull skips matching resources, and deploys and cleanup never change or delete them.

If you already run separate development, staging and production orgs and want to promote between them, follow the one-time setup in the promotion guide, and review the read-only plan before the first promotion applies anything.

Set it up with a coding agent

Coding agents can do the whole setup for you. Paste this prompt into Claude Code, Codex or Cursor, with your private API key already exported as VAPI_PRIVATE_API_KEY:

Set up Vapi GitOps
Set up [https://github.com/VapiAI/gitops](https://github.com/VapiAI/gitops) locally for my Vapi org, in a private repository. Read AGENTS.md first and follow it. Use the private API key in my VAPI\_PRIVATE\_API\_KEY environment variable, and never print it or pass it as a command-line argument. Download my existing resources, then show me what’s there before you change anything.

Agents follow the repository’s AGENTS.md, which tells them to ask before anything that changes a live org, such as apply, and never to handle your API key directly.

Development, staging and production

For separate environments, use one Vapi org per environment, for example acme-dev, acme-staging and acme-prod. Each is a folder in the same repository.

  • Promote, don’t copy. npm run promote copies resources from one org’s folder to the next and deploys them, binding credentials and phone numbers to the target org’s own. A promotion.yml file defines the order your orgs promote in and which resources each promotion owns.
  • Gate production on tests. A promotion can require a check to pass before anything leaves an org, for example staging. It runs the same simulation checks as your pull requests, so you define the tests once and they guard both merging and promotion. If the check fails, or can’t finish, nothing is promoted out of that org. See Check before promoting.
  • Keep production writes in CI. Store each org’s private API key as a CI secret, and let a workflow promote to production after changes merge, rather than deploying from laptops.
  • Keep secrets out of git. Keys live in .env.<org> files or CI secrets. Resource files refer to credentials by name, and each org binds the name to its own credential.

See the promotion guide to set it up.

Test every pull request

Every pull request runs a Validate resources check, which validates each org’s files offline, without secrets. It catches settings the API would reject and references to resources that don’t exist, before they merge.

Simulation suites in the repository can also run on every pull request, against the branch’s own files. Nothing is deployed, and tool calls get mocked results. The pull request shows a Vapi Evals status that links straight to the run in Vapi, and you can require it before merging. Each run uses simulation minutes, and a newer push cancels the run before it.

See the PR checks guide to turn them on, and Simulations for writing the tests themselves.

Working with the dashboard

You can keep using the dashboard alongside the repository. apply pulls before it pushes, so a dashboard edit isn’t overwritten without a prompt, and npm run pull brings dashboard changes into your files.

Vapi’s built-in versioning also works alongside it. Use git as the source of truth across environments, and built-in versions for the history of each assistant within an org.

Learn more