Public beta — not for production use. Data may be wiped at any time. Questions? Contact us.
Documentation menu

axiom.yaml manifest reference

The complete schema of the axiom.yaml package manifest: every field, its type, default, validation rule, and which CLI commands read or write it.

View as Markdown

axiom.yaml is the package manifest. It sits at the root of every Axiom package and declares the package's identity, its nodes, the message types it imports from other packages, and optional build overrides. The Axiom CLI locates the package root by walking up from the current directory until it finds axiom.yaml.

Three fields are required: name, version, and language. Everything else is optional. axiom validate checks the manifest before publishing (see Validation rules).

Complete example

Every field the parser accepts, in one manifest:

# axiom.yaml — at the package root
name: christian/text-tools
version: 1.2.0
language: python
description: Text processing nodes
author: Christian Lucas
license: MIT
tags:
  - text
  - nlp
nodes:
  - name: SummarizeText
    description: Summarize input text
    input: TextRequest
    output: SummaryResult
    required_secrets:
      - OPENAI_API_KEY
  - name: StreamTokens
    input: TextRequest
    output: TokenFrame
    type: pipeline
imports:
  - package: axiom-official/axiom-conv-ai
    version: 1.0.0
    messages:
      - ChatTurn
env:
  - name: LOG_LEVEL
    description: Verbosity of node logging
    required: false
    secret: false
    default: info
build:
  dockerfile: custom/Dockerfile
  system_deps:
    - ffmpeg

A minimal valid manifest is just the three identity fields — axiom init writes exactly that (plus your --description if given, and a commented example nodes: block you can delete).

Top-level fields

FieldTypeRequiredDefaultPurpose
namestringyesScoped package name, handle/package-name
versionstringyesSemantic version of the package
languagestringyesOne of go, python, rust, java, typescript, csharp
typestringno""proto-only to skip build and deployment; otherwise omit
descriptionstringno""Shown in the registry on publish
authorstringno""Stored with the package record on publish
licensestringno""Stored with the package record on publish
tagslist of stringno[]Discovery tags, stored in the registry's tag index on publish
nodeslist of nodeno[]The package's nodes (see nodes)
importslist of importno[]Message types from other packages (see imports)
envlist of env varno[]Runtime environment variables (see env)
buildobjectnounsetBuild overrides (see build)

description, author, and license are written to the registry when you publish with axiom push. tags are written to the registry's tag index on publish. Marketplace search currently matches on package name, description, and author — not on these tags.

Identity fields: name, version, language

name must be scoped: your-handle/package-name. Both parts may contain only lowercase letters, digits, and hyphens, and each part must start with a letter or digit (pattern: ^[a-z0-9][a-z0-9-]*/[a-z0-9][a-z0-9-]*$). An unscoped or missing name fails validation. axiom init christian/text-tools creates a local directory named after the part after the last / (text-tools/).

version must be semantic versioning: MAJOR.MINOR.PATCH, with an optional leading v and an optional pre-release suffix of letters, digits, and dots after a hyphen (pattern: ^v?[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$). Examples: 1.0.0, v2.1.3, 0.4.0-beta.1. axiom init writes 0.1.0 unless you pass --version.

language must be exactly one of go, python, rust, java, typescript, csharp. It selects the node templates, the generated service code, and the Dockerfile the build uses. axiom init defaults to go unless you pass --language (-l).

nodes

Each entry in nodes declares one node in the package. axiom create node appends entries here for you; you can also edit the list by hand.

FieldTypeRequiredDefaultPurpose
namestringyesPascalCase node name, unique within the package
descriptionstringno""Shown in the registry
inputstringyesInput message name
outputstringyesOutput message name
typestringnounaryOmit or unary for one-in/one-out; pipeline for a streaming generator
required_secretslist of stringno[]Secret names the node reads at runtime
mutation_capableboolnofalseDeclares the node emits state mutations on its response

nameaxiom create node enforces PascalCase: the first character must be uppercase, and only letters and digits are allowed. Duplicate node names in one manifest are rejected. The node's source file is the snake_case form of the name (SummarizeTextnodes/summarize_text.py).

input / output — each must name a message defined in messages/messages.proto or available from an imported package. axiom validate fails when a referenced message cannot be found.

type — a node is unary unless type: pipeline is set. axiom create node --type accepts only unary or pipeline and writes type: pipeline to the manifest only for pipeline nodes (the key is omitted for unary). See execution model.

required_secrets — names of tenant secrets the node reads at runtime. The declaration is informational: the platform does not enforce it at invocation time. A missing secret does not block a run — secrets.Get("NAME") simply yields a not-found result (found = false) at read time, which the node handles. The marketplace displays the list so users know which secrets to register. axiom validate emits a non-blocking warning when node source calls secrets.Get("NAME") with a name missing from this list. See manage secrets.

mutation_capable — declares that the node emits state mutations on its response. The flow compiler reads this across a flow's nodes to decide whether to enable the mutation path; the default false keeps a node out of that path entirely.

imports

Each entry in imports declares a dependency on another package's message types. Do not write these entries by hand — run axiom import <package>[@version], which downloads the package's .proto files into imports/<flattened-name>/<version>/ (scope / becomes -, e.g. christian/text-opsimports/christian-text-ops/1.0.0/), adds or updates the manifest entry, and runs axiom generate.

FieldTypeRequiredPurpose
packagestringyesScoped name of the imported package
versionstringyesExact version of the imported package
messageslist of stringyesMessage names imported from that package

Validation rules for imports:

  • An import entry with an empty messages list is a hard error and blocks publishing. Fix it by re-running axiom import <package>@<version>, which populates the list.
  • A message name listed here but not found in the downloaded proto files is a warning — it usually means a stale entry after the imported package changed.
  • The downloaded proto files must exist locally under imports/<flattened-name>/<version>/; if they are missing, re-run axiom import <package>@<version>.

See import package types for the full workflow.

env

Each entry in env describes a runtime environment variable for the package. All fields except name are optional.

FieldTypeRequiredDefaultPurpose
namestringyesVariable name
descriptionstringno""What the variable controls
requiredboolnofalseWhether the variable must be set
secretboolnofalseWhether the value is sensitive
defaultstringno""Default value

The env section is declarative metadata about what the package expects; axiom validate does not check it. For credentials read by node code at runtime, use secrets and required_secrets instead — secrets are tenant-scoped and reach node code through AxiomContext.

build

The optional build section overrides how the package's container image is built. Most packages never need it — axiom build and axiom push generate a Dockerfile automatically from the package language.

FieldTypeRequiredPurpose
dockerfilestringnoPath (relative to the package root) to a custom Dockerfile used instead of the generated one
system_depslist of stringnoExtra OS-level packages installed into the generated image

system_deps entries are installed by the generated Dockerfile as OS-level packages. For Python packages, the special value axiom installs the Axiom CLI binary into the image instead of an OS package.

For Python packages, axiom validate scans node source for subprocess calls and emits a non-blocking warning when a node invokes a common tool that is absent from the slim base image and not listed in build.system_deps — without the entry, the tool would be missing from the runtime image. The scan covers a fixed list of tools: git, curl, wget, ssh, rsync, zip, unzip, make, gcc, g++, svn, jq. A tool outside that list (such as ffmpeg) still needs a system_deps entry to be present in the image — it just is not flagged by validation.

Proto-only packages

A proto-only package publishes message types for other packages to import, with no nodes and no running service. A package is treated as proto-only when either:

  • type: proto-only is set explicitly, or
  • the nodes list is empty (proto-only is inferred).

For a proto-only package, the publish pipeline skips the Docker build and the service deployment, and stores only the proto definitions and package metadata. Other packages then pull its messages with axiom import. See the type system.

Which commands read and write axiom.yaml

  • axiom init <name> creates the manifest with name, version (default 0.1.0), language (default go), and your --description. Unless --no-example-comment is passed, it appends a commented example nodes: block showing the required_secrets field.
  • axiom create node <Name> appends a node entry (name, description, input, output, and type: pipeline for pipeline nodes) after scaffolding the source files.
  • axiom import <package>[@version] adds or updates an imports entry, merging newly downloaded message names into the messages list.
  • axiom validate, axiom build, axiom push, axiom dev, and axiom test read the manifest; they must be run inside a package directory (any directory below the one containing axiom.yaml).

When a CLI command rewrites the manifest, it re-serializes the whole file — inline comments you wrote in axiom.yaml are not preserved by these operations. Keep notes elsewhere if you need them to survive.

Validation rules

axiom validate (also run as a gate by axiom push) checks the manifest as its first layer. Failures block publishing unless marked as warnings:

CheckSeverity
name present and scoped (handle/package-name, lowercase/digits/hyphens)error
version present and valid semvererror
language one of the six supported valueserror
Every node's input and output resolves to a known messageerror
Every import entry has a non-empty messages listerror
Imported message names exist in the downloaded proto fileswarning
secrets.Get("NAME") calls covered by required_secretswarning
Python subprocess tools covered by build.system_depswarning

Later validation layers check the proto files, node function signatures, and node tests — see the axiom validate reference.