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

Fields of metadata.yml version 1
FieldContract
apiVersion, kindRequired: whatbreaks/v1 and RepositoryMetadata.
servicesRequired, 1–100 items.
service idRequired, 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, ownerRequired, at most 200 characters. owner is a team label, not an identity.
service descriptionOptional, at most 2,000 characters.
service environmentsRequired map. Keys are dev, staging or production; each has a required dependencies list.
dependency idRequired, unique within its service and environment: lowercase letters, digits, '.', '_' or '-'.
dependency relationcalls, depends_on, reads_from, writes_to, publishes_to or consumes_from.
dependency targetkind (service, database or queue), id and environment, all required. There is no default environment.
resourcesOptional, at most 200. Each has id, kind (database or queue), name, owner and a non-empty environments list.
Which relations may point at which kinds of target
RelationTarget kind
callsservice
reads_from, writes_todatabase
publishes_to, consumes_fromqueue
depends_onany

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/v1

The 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.