> ## Documentation Index
> Fetch the complete documentation index at: https://datum-4926dda5-docs-api-reference-demo.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API conventions

> The declarative resource model shared by every Datum Cloud resource: apiVersion, kind, metadata, spec, and status.

Every Datum Cloud resource — a `DNSZone`, an `HTTPRoute`, a `Project`, a billing account — follows the same shape and the same workflow. Learn it once and it applies to everything in the [API resource reference](/api/overview).

<Note>
  This page is the entry point for the API concepts. Once you understand the common shape here, follow the details: [Object metadata](/api/concepts/metadata), [Status & conditions](/api/concepts/status-and-conditions), and [Scopes](/api/concepts/scopes) cover the three top-level sections, while [Field formats & types](/api/concepts/field-formats), [Resource references](/api/concepts/references), [Versioning & stability](/api/concepts/versioning), and [Validation & safe changes](/api/concepts/validation) explain how fields are described, linked, versioned, and checked.
</Note>

<Warning>
  The Datum Cloud API is currently **alpha** (`v1alpha1`). Resources, fields, and defaults may change in backward-incompatible ways between releases. The Gateway API networking resources (for example [`HTTPRoute`](/api/networking/gateway/httproute)) are served at the stable `v1` version.
</Warning>

## The declarative model

Datum Cloud is **declarative**. You don't issue step-by-step commands to build something. Instead, you write down the state you *want* a resource to be in, hand it to the platform, and the platform does the work of making reality match — and keeps it that way. This is the core idea behind every resource:

* You declare **desired state** (the `spec`).
* The platform **reconciles** continuously, taking whatever actions are needed to reach that state.
* The platform reports **observed state** (the `status`) so you can see what actually happened.

You describe the destination; the platform figures out the route and tells you where things stand.

## The top-level shape

Every resource is an object with the same four top-level fields:

| Field        | Purpose                                                                          | Who writes it |
| ------------ | -------------------------------------------------------------------------------- | ------------- |
| `apiVersion` | The API group and version the resource belongs to (`<group>/<version>`).         | You           |
| `kind`       | The type of resource, for example `DNSZone`.                                     | You           |
| `metadata`   | Identity and bookkeeping — the resource's `name`, labels, annotations, and more. | You (mostly)  |
| `spec`       | The **desired state** — the fields you set to declare what you want.             | You           |
| `status`     | The **observed state** — what the platform reports back. Read-only.              | The platform  |

<Info>
  A useful way to read any resource: **`spec` is the request, `status` is the receipt.** You own everything in `spec`; the platform owns everything in `status`. Never edit `status` — it's overwritten by the platform on every reconcile.
</Info>

### apiVersion and kind: the resource's identity

A resource type is identified by three things — its **group**, **version**, and **kind** (often abbreviated GVK):

* **Group** namespaces related resources together, for example `dns.networking.miloapis.com`.
* **Version** tracks the maturity and shape of the API, for example `v1alpha1`.
* **Kind** is the specific type, for example `DNSZone`.

The `apiVersion` field combines group and version as `<group>/<version>`, and `kind` names the type. Together they tell the platform exactly which resource you mean:

```yaml theme={null}
apiVersion: dns.networking.miloapis.com/v1alpha1
kind: DNSZone
```

Every page in the [API resource reference](/api/overview) opens with an **Identity** table listing the group, version, kind, and scope for that resource. For example, [`DNSZone`](/api/dns/dnszone) is served at group `dns.networking.miloapis.com`, version `v1alpha1`, kind `DNSZone`, scope Project.

### metadata: naming and organizing

`metadata` carries the resource's identity and bookkeeping fields — its `name`, any `labels` and `annotations`, and platform-managed values you'll see on resources you read back. See [Object metadata](/api/concepts/metadata) for the full breakdown.

### spec: what you want

`spec` is where you declare desired state. The available fields differ by resource type — a `DNSZone` spec names the zone's domain, an `HTTPRoute` spec describes routing rules — but the meaning is always the same: *this is what I want to exist.* Each resource page documents its spec fields, their types, and which are required.

### status: what actually happened

`status` is populated by the platform to report observed state. It commonly includes a set of **conditions** — standardized readiness signals such as `Accepted` and `Programmed` — plus resource-specific observed values. Because reconciliation is continuous, `status` is your window into whether the platform has caught up to your `spec` and whether anything went wrong. See [Status & conditions](/api/concepts/status-and-conditions).

## A generic manifest skeleton

Strip away the resource-specific fields and every manifest looks like this:

```yaml theme={null}
apiVersion: <group>/<version>   # e.g. dns.networking.miloapis.com/v1alpha1
kind: <Kind>                    # e.g. DNSZone
metadata:
  name: <name>                  # unique within its scope
  labels:                       # optional: your own key/value tags
    example.com/team: platform
spec:
  # desired state — the fields you set (resource-specific)
# status is written by the platform; you don't include it when applying
```

You write everything above `status`. When you read a resource back, the platform will have added a `status` block (and filled in some managed `metadata`).

## The desired-state workflow

Working with any resource is the same loop, regardless of type:

<Steps>
  <Step title="Declare desired state">
    Write a manifest with `apiVersion`, `kind`, `metadata`, and the `spec` you want. You only ever author these.
  </Step>

  <Step title="Apply it">
    Submit the manifest. The platform stores your desired state and begins reconciling toward it. See [Changing resources](/datumctl/resources/changing) and [Safe changes & declarative config](/datumctl/resources/safe-changes).
  </Step>

  <Step title="The platform reconciles">
    Controllers take whatever actions are needed to make reality match your `spec`, and keep doing so as conditions change. You don't drive these steps.
  </Step>

  <Step title="Read the reported status">
    Inspect `status` (especially its conditions) to confirm the resource is ready, or to see why it isn't. See [Reading resources](/datumctl/resources/reading).
  </Step>
</Steps>

<Tip>
  Because state is declarative, re-applying the same manifest is safe: the platform compares your desired state against what exists and only changes what's different. Keep your manifests in version control and treat them as the source of truth.
</Tip>

## Working with resources from the CLI

The [API resource reference](/api/overview) tells you *what* fields a resource has. The `datumctl` guides tell you *how* to apply and read them — the mechanics are identical for every resource type:

* [Reading resources](/datumctl/resources/reading) — get and inspect resources and their status.
* [Changing resources](/datumctl/resources/changing) — apply, create, and edit desired state.
* [Safe changes & declarative config](/datumctl/resources/safe-changes) — preview changes and manage manifests declaratively.
* [Output formats & scripting](/datumctl/output-and-scripting) — machine-readable output for automation.
* [Contexts & scoping](/datumctl/contexts-and-scoping) — target the right Project or the Platform.
* [Discovering resources & schemas](/datumctl/discovering-resources) — list available resource types and explore their fields live.

Because scope (Project vs. Platform) determines where a resource lives and how you address it, read [Scopes](/api/concepts/scopes) alongside [Contexts & scoping](/datumctl/contexts-and-scoping).
