Repository layout and manifests
apiVersion, kind, metadata.name as the natural key, one file or many, and what happens on rename.
Repository layout and manifests
Discovery
upzero scans a connected repository's up0/ directory recursively for every *.yaml/*.yml file: up0/**/*.yaml. What matters is the kind: field inside a document, never its filename or which directory it sits in. Organizing manifests by team, by environment, or any other convention is entirely your own choice; nothing in upzero enforces or reads meaning into the directory structure.
up0 import (see Import existing config) writes one file per resource under up0/<kind-plural>/<metadata.name>.yaml as a sensible starting point, but a file can hold one document or several, separated by ---, exactly like kubectl apply -f. Splitting every resource into its own file or grouping many into one is equally valid.
Manifest shape
Every resource is a standalone document with four top-level keys:
apiVersion: up0.io/v1
kind: Monitor
metadata:
name: production-api
labels:
env: production
criticality: critical
annotations:
up0.io/recreate: "true"
spec:
# fields specific to this Kind (see the Kind reference)
...apiVersion is declared per document, always up0.io/v1 today. A missing or unrecognized value is a hard parse-time error; it is never assumed to be v1.
kind is PascalCase singular (Monitor, StatusPage), matching the seven registered Kinds in the Kind reference.
metadata.name is the natural key: unique per organization, per Kind. There is no separate id field to track; renaming a resource in the manifest is indistinguishable from deleting the old name and creating a new one; the old name shows up in the next plan as to_destroy and the new name as to_create, not as an update. Give a resource a stable name from the start if you intend to keep editing its other fields over time.
metadata.labels is free-form key/value taxonomy, usable the same way on every Kind. This is separate from Monitor.spec.tags, which references real Tag resources by name (see the Tag and Monitor pages).
metadata.annotations carries one-off instructions to the sync process itself, never state that is compared field by field the way spec is. up0.io/recreate: "true" is the one annotation in use today, re-minting a revoked IngestionToken's secret (see Not yet as code for IngestionToken's current status). Any label or annotation key under the up0.io/ prefix is reserved for upzero itself; a manifest that sets one is rejected at validation time.
spec is the desired state, one schema shared by the manifest and by upzero's own API request validation, so a Kind's fields never drift between the two. There is no status field on any manifest: live, observed state (a monitor's current up or down status, a status page component's computed color) is never written into a manifest and never read back from one. A manifest's spec says what you want; the console, API and CLI are where you see what is actually true right now.
Validation
Every document is validated independently. One malformed or invalid document reports its own error against its own file and is excluded from that sync's plan; it never fails the rest of the file or the rest of the repository.
| Problem | Example |
|---|---|
Missing apiVersion | up0/monitors/production-api.yaml: missing required field "apiVersion" |
Unrecognized apiVersion | up0/monitors/production-api.yaml: unrecognized apiVersion "up0.io/v3" for kind Monitor |
Unknown kind | up0/widgets/foo.yaml: unknown kind "Widget" (not a registered upzero resource type) |
Missing metadata.name | up0/monitors/production-api.yaml: missing required field "metadata.name" |
| A reserved-prefix label or annotation | metadata.annotations key "up0.io/foo" uses the reserved "up0.io/" prefix |
A spec field fails validation | The same field-path and message shape any other API validation error uses |
Duplicate metadata.name for one Kind, two documents | duplicate name "production-api" for kind Monitor |
Looking up a Kind's fields before writing a manifest
up0 schema explain Monitor --version v1
up0 schema explain Monitor --version v1 --output jsonGenerated directly from the same schema the API and the sync process both validate against, so it never drifts from what a manifest actually needs. --output json is meant for editor tooling or an agent authoring a manifest; the Kind reference pages are this same output, already generated and annotated with a one-line meaning per field.