This repository is the backend API and persistence layer that powers api.unify.ai/v0. It contains the local project/context/log stack as well as the account, billing, organization, assistant, and Console-facing APIs used by the hosted product.
If Unity is the runtime brain, Orchestra is the durable substrate: projects, contexts, logs, assistants, storage metadata, auth, and the other stateful APIs that make long-lived assistants possible.
Start here: API Endpoints README • Database README • Observability • Contributing • Security
- FastAPI application and API routers
- SQLAlchemy models, DAOs, and Alembic migrations
- background routines for billing, cleanup, notifications, and storage workflows
- observability and deployment configs for managed environments
- API, database, and service tests
- Unify — Python SDK that wraps Orchestra's API
- Console — Web UI that reads and writes Orchestra data
- Unity — AI assistant runtime that persists state through Unify
Running the whole product locally? Don't start here. Use
unity-deploy/selfhost/stack.sh upfrom the private deployment checkout; seeunity-deploy/docs/local-full-stack-inner-loop.md. It starts Orchestra, the Unity gateway, Console, and your Coordinator together, and drives Orchestra'sscripts/local.shfor you. The steps below are for developing/testing Orchestra on its own.
For the smallest local development setup with PostgreSQL + pgvector:
cp .env.example .env
docker run --name orchestra-db -p 5432:5432 \
-e POSTGRES_PASSWORD=orchestra -e POSTGRES_USER=orchestra -e POSTGRES_DB=orchestra \
pgvector/pgvector:pg15
uv sync
alembic upgrade head
uv run python -m orchestraThe API will be available at http://127.0.0.1:8000/v0.
Use .env.advanced.example instead if you need the broader hosted/platform
surface for storage, OAuth, billing, media, scheduler auth, or other managed
integrations.
If you need more detail, start with:
- API Endpoints README
- Database README
- Observability
- CI/CD
- Running the tests
- Running orchestra
- Secrets and Environment Variables
Orchestra is the backend API and database layer in a multi-repository system:
User (Console/Phone/SMS/Email)
│
┌─────────────────┴──────────────────┐
│ Communication │
│ (Webhooks, Voice, SMS, Email) │
└────┬───────────────────────────────┘
│
┌────┴────┐ ┌─────────┐ ┌─────────┐
│ Unity │ │ Unify │ │Orchestra│
│ (Brain) │───▶│ (SDK) │───▶│ (API) │
│ │ │ │ │ (DB) │
└────┬────┘ └────┬────┘ └────┬────┘
│ ▲ ▲
│ │ │
│ ┌─────────┴─┐ ┌────┴───────┐
└───▶│ UniLLM │ │ Console │
│ (LLM API) │ │(Interfaces)│
└───────────┘ └────────────┘
All API endpoints under /v0/ require a Bearer token via the Authorization header, except:
GET /v0/health— unauthenticated health checkPOST /v0/webhooks/stripe— Stripe signature verification (no API key)
Admin endpoints under /v0/admin/ require the ORCHESTRA_ADMIN_KEY. This key comparison uses secrets.compare_digest() for timing-attack resistance. Admin endpoints also support OIDC token verification from the CLOUD_SCHEDULER_SERVICE_ACCOUNT service account.
The /metrics endpoint requires Bearer token authentication via the PROMETHEUS_METRICS_TOKEN environment variable. User email addresses are excluded from metric labels to avoid PII exposure.
An IP-based rate limiter protects admin endpoints, /metrics, and webhook endpoints (60 requests per IP per 60-second window).
All responses include: X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security, Referrer-Policy, X-XSS-Protection, and Permissions-Policy.
| Variable | Purpose |
|---|---|
ORCHESTRA_ADMIN_KEY |
Admin API authentication |
PROMETHEUS_METRICS_TOKEN |
Metrics endpoint authentication |
CLOUD_SCHEDULER_SERVICE_ACCOUNT |
(Optional) Service account email for OIDC-based scheduler auth |
Managed deployments rely on GCP services such as Cloud SQL, Secret Manager, Cloud Storage, Cloud Scheduler, and Cloud Armor. Those operational settings live outside this repo and are intentionally not reproduced here. Provider-event trigger hosted topology prerequisites and ops steps are documented in deploy/provider-trigger-topology.md.
$ tree "orchestra"
orchestra
├── __main__.py # Startup script. Starts uvicorn.
├── conftest.py # Fixtures for all tests.
├── settings.py # Main configuration settings for project.
├── tests # Tests for project.
├── db # module contains db configurations
│ ├── migrations # Files related to alembic migrations.
│ ├── dao # Data Access Objects. Contains different classes to interact with database.
│ └── models # Package contains different models for ORMs.
└── web # Package contains web server. Handlers, startup config.
├── api # Package with all handlers.
│ └── dependencies.py # Contains utilities and helpers for v0/router.
│ └── router.py # Main router.
├── application.py # FastAPI application configuration.
└── lifetime.py # Contains actions to perform on startup and shutdown.This project uses uv to manage dependencies. To install dependencies (including the dev group):
uv syncCommands run inside the environment with uv run <command>, and the
interpreter is always the repo-local .venv/bin/python.
To install pre-commit simply run inside the shell:
pre-commit installUse .env.example as the starting point for the minimal local API/database setup.
Use .env.advanced.example if you need the broader hosted/platform configuration
surface. VSCode will usually load .env automatically, but you may need to
configure your IDE or shell to do the same.
To run the orchestra test suite, you will need the uv environment and a PostgreSQL server running with the pgvector extension installed. The tests and vector functions require pgvector.
Recommended (pgvector-enabled Postgres container):
docker run --name orchestra-db -p 5432:5432 \
-e POSTGRES_PASSWORD=orchestra -e POSTGRES_USER=orchestra -e POSTGRES_DB=orchestra \
pgvector/pgvector:pg15Once the database server is running, install dependencies (including dev) and run the tests using the uv environment. Take into account that some tests will require secrets and environment variables.
uv sync
uv run pytest -vv .If you see an error like extension "vector" is not available, your Postgres instance lacks pgvector. Use the image above or install pgvector in your local Postgres and run CREATE EXTENSION IF NOT EXISTS vector; in the target database.
To run the orchestra service locally, you will need a database with valid data, the corresponding secrets/environment variables, and the uv environment.
If you already have a docker container running Postgres with pgvector you won't need to create a new image. Otherwise:
docker run --name orchestra-db -p 5432:5432 \
-e POSTGRES_PASSWORD=orchestra -e POSTGRES_USER=orchestra -e POSTGRES_DB=orchestra \
pgvector/pgvector:pg15Everytime you create a new container, you should run migrations:
alembic upgrade "head"Now, connect to the PSQL database (password=orchestra):
psql -h localhost -U orchestra -d orchestraYour DB should now be fully functional! Now, you should be able to see all the tables (e.g. \dt).
To run the service, you can do uv run python -m orchestra but you won't be able to debug the service.
To run orchestra in debug mode (in VSCode / Codespaces), your launch.json file should look something like this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
"args": [
"orchestra.web.application:get_app",
"--reload"
],
"jinja": true,
"justMyCode": true
}
]
}Once the service is running, you can send requests to http://127.0.0.1:8000/v0
Orchestra uses a comprehensive observability stack for monitoring, logging, and tracing.
For local development, you can run the observability stack using Docker Compose:
docker-compose -f orchestra/observability/docker-compose.observability.yml up -dThis will start Prometheus, Loki, Tempo, and Grafana containers locally. You can access Grafana at http://localhost:3000.
Managed deployments use Prometheus, Loki, Tempo, and Grafana for metrics, logs, and tracing. For local usage details, refer to the Observability README.
This application can be configured with environment variables.
You can create .env file in the root directory and place all
environment variables here.
All environment variables should start with "ORCHESTRA_" prefix.
For example if you see in your "orchestra/settings.py" a variable named like
random_parameter, you should provide the "ORCHESTRA_RANDOM_PARAMETER"
variable to configure the value. This behaviour can be changed by overriding env_prefix property
in orchestra.settings.Settings.Config.
An example of .env file:
ORCHESTRA_RELOAD="True"
ORCHESTRA_PORT="8000"
ORCHESTRA_ENVIRONMENT="dev"You can read more about BaseSettings class here: https://pydantic-docs.helpmanual.io/usage/settings/
We use pytest-asyncio in STRICT mode. The default fixture loop scope is already set to function in pyproject.toml, so you should not see related deprecation warnings.
If you want to start your project with OpenTelemetry collector
you can add -f ./deploy/docker-compose.otlp.yml to your docker command.
Like this:
docker-compose -f deploy/docker-compose.yml -f deploy/docker-compose.otlp.yml --project-directory . upThis command will start OpenTelemetry collector and jaeger. After sending a requests you can see traces in jaeger's UI at http://localhost:16686/.
This docker configuration is not supposed to be used in production. It's only for demo purpose.
You can read more about OpenTelemetry here: https://opentelemetry.io/
MIT — see LICENSE.