Integrations
Describe a repository with metadata.yml.
Whatbreaks reads one file from the root of a repository to learn which services and resources it owns and what they depend on in each environment. It never reads source code, pipeline files or environment files: the file is the whole contract.
A complete example
The production Order API calls a dev service on purpose: that environment mismatch is what Whatbreaks exists to catch.
apiVersion: whatbreaks/v1
kind: RepositoryMetadata
services:
- id: commerce/order-api
name: Order API
owner: commerce-team
description: Handles order placement
environments:
dev:
dependencies:
- id: payments
relation: calls
target: { kind: service, id: commerce/payment-api, environment: dev }
production:
dependencies:
- id: payments
relation: calls
target: { kind: service, id: commerce/payment-api, environment: dev }
- id: order-storage
relation: writes_to
target: { kind: database, id: commerce/orders-db, environment: production }
- id: order-events
relation: publishes_to
target: { kind: queue, id: commerce/orders-events, environment: production }
- id: commerce/order-worker
name: Order worker
owner: commerce-team
environments:
production:
dependencies:
- id: order-events
relation: consumes_from
target: { kind: queue, id: commerce/orders-events, environment: production }
- id: order-storage
relation: reads_from
target: { kind: database, id: commerce/orders-db, environment: production }
resources:
- id: commerce/orders-db
kind: database
name: Orders database
owner: commerce-team
environments: [dev, production]
- id: commerce/orders-events
kind: queue
name: Order events
owner: commerce-team
environments: [dev, production]
Fields
| Field | Contract |
|---|---|
apiVersion, kind | Required: whatbreaks/v1 and RepositoryMetadata. |
services | Required, 1–100 items. |
service id | Required, owner/name: each part lowercase letters, digits, '.', '_' or '-', starting with a letter or digit; at most 128 characters in all. Unique within the organisation. |
service name, owner | Required, at most 200 characters. owner is a team label, not an identity. |
service description | Optional, at most 2,000 characters. |
service environments | Required map. Keys are dev, staging or production; each has a required dependencies list. |
dependency id | Required, unique within its service and environment: lowercase letters, digits, '.', '_' or '-'. |
dependency relation | calls, depends_on, reads_from, writes_to, publishes_to or consumes_from. |
dependency target | kind (service, database or queue), id and environment, all required. There is no default environment. |
resources | Optional, at most 200. Each has id, kind (database or queue), name, owner and a non-empty environments list. |
| Relation | Target kind |
|---|---|
calls | service |
reads_from, writes_to | database |
publishes_to, consumes_from | queue |
depends_on | any |
A target that no configured repository declares is not an error: it is reported as an unresolved dependency when the file is analysed.
An omitted environment is not an empty one
dependencies: [] says the service has none in that environment. Leaving the environment out says nothing, and the analysis reports the gap instead of assuming the service is safe there.
Rules for the file
- UTF-8, one YAML document, at most 256 KiB, at the root of the repository.
- No includes, templates, variable expansion, custom tags, anchors, aliases or duplicate keys, and no nesting deeper than 20 levels.
- Unknown fields are rejected, so a misspelt key is an error rather than silently ignored.
- At most 2,000 dependencies in the document. Repeating a relation, target and target environment is rejected even under a different id.
- Credentials, pipeline bindings, approval policy and deployment state cannot be declared here.
Every problem is reported with its YAML path, a 1-based line and column, a stable code and a message, for example services[0].environments.production.dependencies[1].target.kind.
Validate it in your own tooling
The schema is JSON Schema Draft 2020-12 and is served without authentication, so an editor, a linter or another system can fetch it directly:
curl -O https://<your-whatbreaks-host>/api/v1/metadata/schema/v1The schema cannot express the YAML restrictions or the cross-entry rules (duplicates and id collisions). Whatbreaks enforces those when it reads the file, and the metadata validator in the workspace checks a pasted file against all of them.
Ask for an analysis from a pipeline
After a pipeline knows the commit it has checked out and before it deploys, it sends one authenticated request. Whatbreaks fetches metadata.yml at exactly that commit through the repository connection you configured. Create the pipeline binding and its credential in the workspace; which services are analysed and which refs and stages are accepted come from the binding, never from the event.
POST /api/v1/webhooks/pipeline/{binding_id}
Authorization: Bearer <binding credential>
Content-Type: application/json
{
"schema_version": 1,
"event_id": "order-main-812-predeploy-attempt-1",
"event_type": "analysis.requested",
"occurred_at": "2026-09-22T07:00:00Z",
"pipeline": { "external_id": "folder/order-main", "run_id": "812", "attempt": 1, "stage": "predeploy" },
"repository": { "external_id": "42", "commit": "0123456789abcdef0123456789abcdef01234567", "ref": "refs/heads/main" },
"target_environment": "production"
}A 202 answer carries a status_url; poll it with the same credential until the job is succeeded, failed or canceled. A missing or invalid metadata.yml fails the run: it is never reported as low risk.
Ready to connect a repository?
Create an account to set up connections and pipeline bindings.