You have signed up, you are in the dashboard — now what? This guide walks you through the process of planning your event model, sending your first events, and teaching the AI assistant about your infrastructure. By the end you will have a working setup and an AI that understands your system.
Before diving into individual fields, it helps to have a mental model of how OpsTrails sees your infrastructure. Think of it as a grid with two axes:
subject): the progression of your deployment targets from left to right. Development, staging, production. The same system replicated across different stages.source): the stack of components within any single environment. Frontend, backend, database, cache. The depth of your architecture. DEVELOPMENT STAGING PRODUCTION
┌──────────────┬──────────────┬──────────────┐
FE │ │ │ │
├──────────────┼──────────────┼──────────────┤
BE │ │ ★ deploy │ │
├──────────────┼──────────────┼──────────────┤
DB │ │ │ │
├──────────────┼──────────────┼──────────────┤
CACHE │ │ │ │
├──────────────┼──────────────┼──────────────┤
WORKER │ │ │ │
└──────────────┴──────────────┴──────────────┘Every event you send lands at a specific intersection on this grid. The star above represents “the backend was deployed to staging” — source: "BE", subject: "STAGING". The type field then tells you what happened at that intersection (a deployment, a rollback, a config change), and severity tells you how significant it was.
Every event you send to OpsTrails follows the CloudEvents 1.0 specification. Before you fire off your first curl, it helps to understand what each field does and how OpsTrails uses it.
Here is a complete event payload with every available field:
{
"specversion": "1.0",
"type": "deployment",
"source": "//github.com/acme/api-service",
"time": "NOW",
"id": "deploy-20250115-001",
"subject": "production",
"severity": "MAJOR",
"version": "2.4.0",
"datacontenttype": "application/json",
"dataschema": "https://example.com/schemas/deploy.json",
"data": {
"description": "Quarterly release with new checkout flow",
"timezone": "Europe/London",
"ticket": "JIRA-1234",
"deployer": "jane.doe"
}
}| Field | What it means |
|---|---|
specversion | Always "1.0". This tells OpsTrails you are using CloudEvents v1.0. |
type | The kind of operation — e.g. deployment, rollback, data-load. See Step 4. |
source | The system that produced this event — e.g. BE, FE, DB. See Step 3. |
time | When it happened. Use "NOW" for current server time, or an ISO 8601 timestamp with timezone like 2025-01-15T14:30:00Z. Bare datetimes without a timezone offset are rejected. |
| Field | What it means |
|---|---|
subject | Your environment — e.g. PRODUCTION, STAGING. See Step 2. |
severity | How significant this operation is: LOW, MINOR, MAJOR, or CRITICAL. See Step 5. |
version | A release or build identifier — e.g. 1.2.3, abc1234. |
id | A custom event ID. Auto-generated if you leave it out. |
data | A free-form JSON object. Put anything here that gives context — descriptions, ticket numbers, who triggered it, links. The AI assistant can read all of it. |
datacontenttype | MIME type of the data field. Defaults to application/json. |
dataschema | URI pointing to a schema for your data object. Informational only. |
✅ Tip
specversion, type, source, and time. Everything else enriches the picture for you and the AI.The subject field represents where in your infrastructure something happened. Think of it as your environment identifier — the horizontal axis of the grid. Before sending events, sit down and map out your environments.
Most teams have a straightforward environment ladder:
PRODUCTION
STAGING
DEVELOPMENT
LOCALIf this matches your setup, you are ready — use these values directly in the subject field.
If your organization operates multiple brands, websites, or business units that each have their own environment ladder, encode that into the subject. Use a consistent delimiter (a hyphen works well):
BRAND-A-PRODUCTION
BRAND-A-STAGING
BRAND-A-DEVELOPMENT
BRAND-B-PRODUCTION
BRAND-B-STAGING
BRAND-B-DEVELOPMENTThis pattern also applies to multi-region or multi-tenant setups:
US-PRODUCTION TENANT-ACME-PRODUCTION
US-STAGING TENANT-ACME-STAGING
EU-PRODUCTION TENANT-GLOBEX-PRODUCTION
EU-STAGING TENANT-GLOBEX-STAGING
APAC-PRODUCTIONIn some systems — particularly those with content management workflows — environments have sub-environments that represent content states or approval stages:
BRAND-A-DEVELOPMENT-EDITOR
BRAND-A-DEVELOPMENT-PREVIEW
BRAND-A-DEVELOPMENT-APPROVED
BRAND-A-STAGING-EDITOR
BRAND-A-STAGING-APPROVED
BRAND-B-PRODUCTION-LIVE
BRAND-B-PRODUCTION-PREVIEWThis is less common but fully supported. OpsTrails places no restrictions on how you structure the subject — it is a free-form string (up to 50 characters).
💡 How to decide
The source field represents what system produced the event. If subject is the horizontal axis of your infrastructure (environments), source is the vertical axis (systems within those environments).
Think about all the distinct systems that make up your platform:
| System | Example source value |
|---|---|
| Frontend application | FE |
| Backend / API service | BE |
| Database | DB |
| Edge cache / CDN | CACHE |
| Content management system | CMS |
| Search / indexing service | INDEXING |
| Intermediate layer (BFF, gateway) | INTERMEDIATE |
| Background job processor | WORKER |
| Infrastructure / Terraform | INFRA |
| CI/CD pipeline | CI |
You can also use more descriptive names or URIs. The CloudEvents spec suggests a URI format:
//github.com/acme/api-service
//github.com/acme/frontend
//jenkins/deploy-pipeline
//terraform/production-infraEither approach works. Short identifiers like FE and BE are easier to type in curl commands. URI-style sources are more precise when you have many repositories. You do not need to capture all systems on day one — you can add sources as you go.
The type field describes what kind of operation happened. Common event types include:
| Operation | Example type value |
|---|---|
| Code deployed to an environment | deployment |
| Deployment reverted | rollback |
| New version released | release |
| Incident opened or resolved | incident |
| ETL job or data migration | data-load |
| Configuration changed | config-change |
| Database schema updated | db-migration |
| Cache cleared or rebuilt | cache-purge |
| Content published | content-publish |
| Scheduled maintenance | maintenance |
| Infrastructure scaled | scaling |
| Certificate rotated | cert-rotation |
You can use any string here. Choose names that your team already uses when talking about operations — if you say “we did a deploy”, use deployment. If you say “we pushed a hotfix”, you might use hotfix or just deployment with a description in data.
Severity is optional but useful. It tells OpsTrails (and the AI assistant) how significant an operation is. There are four levels:
| Severity | When to use |
|---|---|
LOW | Routine, low-risk operations. Standard deployments to development, cache clears, config tweaks. |
MINOR | Notable but controlled changes. Deploying a feature to staging, non-production data migrations. |
MAJOR | Significant changes with real impact. Production deployments, major releases, production schema changes. |
CRITICAL | High-risk, high-impact operations. Emergency hotfixes, production incident responses, large-scale infrastructure changes. |
📝 Note
CRITICAL deployment 10 minutes before an incident, it will call that out.A practical approach: start simple. Only set severity on production events. A deploy to staging does not need a severity tag. A major release to production benefits from MAJOR or CRITICAL.
You have planned your environments, sources, types, and severity conventions. Now send a real event. Go to Settings → API Keys in the dashboard and create a key with READ_WRITE scope. Copy the key — it is only shown once.
curl -X POST https://api.opstrails.dev/api/v1/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"specversion": "1.0",
"type": "deployment",
"source": "BE",
"time": "NOW"
}'curl -X POST https://api.opstrails.dev/api/v1/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"specversion": "1.0",
"type": "deployment",
"source": "BE",
"time": "NOW",
"subject": "PRODUCTION",
"severity": "MAJOR",
"version": "2.4.0",
"data": {
"description": "Quarterly release with new checkout flow and payment provider migration",
"ticket": "JIRA-1234"
}
}'Switch to the Events tab in the dashboard. Your event should appear in real time — no refresh needed. The live feed updates automatically as events arrive.
Try sending a few more events with different types and sources to build up some data:
# A frontend deployment
curl -X POST https://api.opstrails.dev/api/v1/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"specversion": "1.0",
"type": "deployment",
"source": "FE",
"time": "NOW",
"subject": "STAGING",
"version": "1.8.0",
"data": {
"description": "Updated landing page with new hero section"
}
}'# A database migration
curl -X POST https://api.opstrails.dev/api/v1/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"specversion": "1.0",
"type": "db-migration",
"source": "DB",
"time": "NOW",
"subject": "PRODUCTION",
"severity": "MAJOR",
"data": {
"description": "Added indexes on orders table for reporting queries"
}
}'# A cache purge
curl -X POST https://api.opstrails.dev/api/v1/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"specversion": "1.0",
"type": "cache-purge",
"source": "CACHE",
"time": "NOW",
"subject": "PRODUCTION",
"severity": "LOW"
}'You have events flowing in. The AI assistant can already see them, but it does not understand what FE, BE, or BRAND-A-PRODUCTION means in your context. You need to give it that understanding.
Go to Settings and find the Business Context section:
Write a few paragraphs covering:
Here is an example for a fictional e-commerce company with two brands:
We are an e-commerce company operating two brands: ShopMax and BuyFast.
ENVIRONMENTS:
Each brand has its own environment ladder. Environment subjects follow the
pattern BRAND-ENVIRONMENT:
- SHOPMAX-PRODUCTION — live customer-facing environment for ShopMax
- SHOPMAX-STAGING — pre-production testing for ShopMax
- SHOPMAX-DEVELOPMENT — development environment for ShopMax
- BUYFAST-PRODUCTION — live customer-facing environment for BuyFast
- BUYFAST-STAGING — pre-production testing for BuyFast
- BUYFAST-DEVELOPMENT — development environment for BuyFast
A deployment to any PRODUCTION environment is considered a release.
SOURCES:
- FE — frontend React application (Next.js), serves the storefront
- BE — backend API service (Node.js), handles orders, payments, inventory
- DB — PostgreSQL database, shared across brands
- CACHE — Cloudflare edge cache, handles product pages and static assets
- CMS — headless CMS (Contentful), manages product descriptions and pages
- WORKER — background job processor, handles email, inventory sync, reports
TYPES:
- deployment — code deployed to an environment
- rollback — a deployment that was reverted
- db-migration — database schema change applied
- cache-purge — CDN/edge cache invalidated
- content-publish — content updated via CMS
- config-change — environment variables or feature flags updated
- incident — an incident was opened or resolved (check data.description)
SEVERITY:
We mark production deployments as MAJOR by default. Hotfixes and incidents
are CRITICAL. Everything else is LOW or MINOR.
NOTES:
- BE and DB deployments are tightly coupled — a backend deployment often
includes a database migration. If you see issues after a BE deployment,
check for a recent DB event as well.
- We deploy to staging before production. A missing staging deployment
before a production deployment is unusual and worth flagging.
- Deployments happen during business hours (9:00–18:00 CET) on weekdays.
Anything outside that window is either a hotfix or an incident response.Without business context, the AI treats your events as raw data. With business context, it can:
Once you have events and business context in place, you can use OpsTrails through any AI assistant that supports MCP (Model Context Protocol) — Claude, Cursor, Claude Code, and others.
OpsTrails provides an MCP endpoint at:
https://api.opstrails.dev/api/mcp/mcpYour AI assistant connects to this endpoint using a READ_ONLY or READ_WRITE API key. Configuration varies by client — check the MCP section for setup instructions specific to your tool.
Once connected, you can ask questions in natural language:
The AI uses the business context you wrote in Step 7 to interpret and explain the results in terms that make sense for your organization.
| Step | What you did |
|---|---|
| 1 | Learned the CloudEvents payload fields |
| 2 | Defined your environments (subject) |
| 3 | Defined your systems (source) |
| 4 | Defined your operation types (type) |
| 5 | Decided how to use severity |
| 6 | Sent your first events via curl |
| 7 | Wrote business context so the AI understands your setup |
| 8 | Connected an AI assistant and started querying |
You are now set up. From here, the next steps are to integrate event tracking into your CI/CD pipeline (see the docs on GitHub Actions, SDK, and CLI) and optionally connect analytics providers for before/after metric comparisons around events.