Skip to content

Config

A job is configured through plain files under its config directory, with a handful of metadata endpoints alongside. This page lists them all.

AI-assisted, human-approvednovem uses AI to review and keep our documentation up to date.

Like every novem resource, a job is a folder of small files: each setting is read with GET, set with POST (plain text body), and cleared with DELETE. The job itself is created with PUT, renamed with PATCH and removed with DELETE on its base path, /v1/code/jobs/<job>. GET /v1/code/jobs lists your jobs; GET .../jobs/<job> lists a single job's entries.

Config keys

Everything under config/ controls how and when the job runs:

KeyValuesDescription
config/typechains (default)The runtime. The chains runtime is the generally available one — see the note on legacy types below.
config/chainschain grammarThe pipeline definition — which repo images run, in what order. See chains.
config/schedulecron expressionOptional cron trigger, with TZ= and comment support. See schedule.
config/enabledtrue / false (default true)Kill switch: while false, scheduled triggers are skipped (manual runs still work).
config/accessclaim nameOptional claim for the short-lived NOVEM_TOKEN injected into each run. See run credentials.
config/env/<name>any textEnvironment variables injected into the running container. Encrypted at rest, write-only — GET config/env lists names, never values. Use lower-case names; both name and NAME are visible to your code.
config/spacesmount mappingsSpaces to attach to the job, one name => /u/user/s/space[,ro|,rw] per line. Each becomes a folder under /mnt inside the run. See spaces.
config/options/commentstrue / false (default true)Whether others can comment on the job (its threads).
config/options/stdinno / optional / yesDeclare whether callers may or must supply standard input. This is descriptive; it does not change the run API.
config/options/argvno / optional / yesWhether callers may or must pass arguments to the job's first step. See arguments.
config/options/argv_defaultJSON array of stringsArguments the first step starts with when the caller passes none, e.g. ["/input", "/output"]. Empty (the default) runs the image's own CMD.
config/options/inputno / optional / yesDeclare whether callers may or must upload files. The web run control follows this setting.
config/options/{stdin,argv,input}_descriptiontextInstructions shown to callers for the corresponding input.

Example: pause a job without touching its schedule:

POST/v1/code/jobs/daily_report/config/enabled
false

Note: Some keys are only listed (and writable) when they apply to the job's current config/type: chains requires the chains type, while the legacy extract / render keys require the legacy types.

Legacy runtime keys

The route tree also carries config/extract, config/render, config/filter and config/group, which belong to the older single-image data / pdf runtimes. Writing those types to config/type (and configuring extract / render) requires the f_jobs feature flag and is not generally available. Use the default chains runtime.

Declaring invocation inputs

The config/options leaves declare how a caller should invoke the job. Each of stdin, argv and input accepts one of three modes:

  • no (the default) removes that input from the declared contract.
  • optional advertises the input without requiring it.
  • yes marks the input as required.

The adjacent <input>_description leaf explains what to provide. The job page uses the input declaration to hide file upload controls, offer optional uploads or require at least one file. The normalized contract is also exposed as JSON Schema in config.json_schema from GET /v1/i/<shortname>.

stdin and input describe the interface; they do not change scheduled execution or validate direct requests to the run API. stdin is reserved for callers that understand the schema, and the chains runtime receives files through /input.

Arguments

A job's first step starts with its image's ENTRYPOINT followed by the run's arguments, which take the place of the image's CMD. Later steps of the chain keep their own CMD. The arguments come from, in order:

  1. the argv the caller passed with the run, when the job runs on the chains runtime and config/options/argv is optional or yes (see triggering a run);
  2. otherwise config/options/argv_default, whatever argv is set to;
  3. otherwise none, and the image runs its CMD as usual.

A job referenced in the chain (/j/<job>) starts its own first step with its own argv_default, wherever it sits in the chain. A caller's argv is never passed to it; when the referenced job's step is the chain's first, the run log says so.

A yes job refuses a run triggered without arguments, through POST .../data or the run button, unless it has a default. Scheduled and emailed runs carry no arguments, so they start with the default, or the image's CMD when there is none. Arguments are passed as-is, never through a shell. argv_default takes at most 256 arguments and 64 KiB in total, and so does a caller's argv.

Note: setting argv to optional or yes lets anyone who may run the job choose its first step's arguments. If the image has no ENTRYPOINT, the first argument is the program that runs, with the job's environment and credentials. Give such an image an ENTRYPOINT before you share the job with callers you do not control.

argv_default is part of the job's configuration: callers who may only run the job do not see it, and their run log shows arguments only when they passed them. A run held for review continues with the caller's arguments only if the job still takes argv and the caller may still run it; otherwise it fails. Keep secrets in config/env, not in arguments.

POST/v1/code/jobs/daily_report/config/options/argv_default
["/input", "/output"]

The job page's run button offers an Arguments field when argv is optional or yes. Quote an argument that contains spaces; leaving the field blank runs the default.

What a run sees

Alongside your own config/env, every step of a run is told which job it is running as, which run it belongs to, who triggered it, and where to reach novem:

VariableExampleDescription
NOVEM_JOB/u/alice/j/daily_reportThe job's path — /u/<user>/j/<job>.
NOVEM_JOB_RUN20260812-101500-3f9a1cThe run id, the <run> in /v1/users/<user>/code/jobs/<job>/runs/<run> — same <user> and <job> as NOVEM_JOB. See runs.
NOVEM_API_ROOThttps://api.novem.io/v1/The API base, /v1/ included — the form the novem Python library and CLI read.
NOVEM_USERNAMEbobThe username of the user who triggered the run. When bob runs alice's job, this is bob while NOVEM_JOB names alice's job.

Together they name the run in progress and where it lives, so a step carrying a novem token can address itself — read back its own runs/<run>/log, or publish the run's description — instead of guessing which job it was launched as.

A chain that references another job splices that job's steps in place; those steps report the job they came from and its own run, not the calling job's. NOVEM_USERNAME is the same on every step: it names the user who triggered the run, whoever owns the referenced job. If you set a config/env variable of the same name, yours wins.

Run credentials

A job is tokenless by default. Set config/access to a durable claim such as global, repo_ro or repo_rw when its code must call the novem API:

curl -X POST -H "Authorization: Bearer $NOVEM_TOKEN" \
  -H "Content-Type: text/plain" \
  --data 'repo_ro' \
  https://api.novem.io/v1/code/jobs/daily_report/config/access

Each run then receives its own short-lived credential in NOVEM_TOKEN, scoped to that claim. Novem revokes it when the run ends; its expiry bounds it if teardown cannot. Only steps belonging to the top-level job receive the token. A job spliced into a chain does not contribute its own credential.

If the job already stores a manually configured NOVEM_TOKEN under config/env, that legacy value wins over the generated credential. Delete the environment entry before adopting config/access; do not keep long-lived bearer tokens in job configuration.

Only the job owner can set or clear config/access. A credentialed job cannot also have a non-owner write share: anyone who can rewrite its chain or environment would otherwise choose the code that runs with the owner's credential. Clear the write share first, or share the job read-only (r or rx). Conversely, clear config/access before granting someone write access.

GET config/access shows the selected claim and its actions/access; DELETE clears it. An unset job continues to run normally but receives no NOVEM_TOKEN.

Build provenance

Every step is also told which revision of your code its image was built from:

VariableExampleDescription
NOVEM_SOURCE_REPOalice/data_fetcherThe repo the step's image came from, <user>/<repo>.
NOVEM_SOURCE_REFlatestThe ref as the chain named it, so prod for @alice/data_fetcher:prod. Defaults to latest.
NOVEM_SOURCE_COMMIT1a2b3c4d5e6f7890abcdef1234567890abcdef12The full commit sha that image was built from.

These variables identify the code revision used by the step. NOVEM_JOB identifies the job that is running.

The commit comes from the record for the resolved image. It identifies the revision the image was built from, which may differ from the current Git reference. If a new commit is still building, a run uses the previous image and reports that image's commit.

No Dockerfile changes are required. Novem looks up the commit when the run starts, including for images built before this metadata was introduced.

Values are per step, from that step's own repo and ref. A chain that references another job splices in steps built from a different repo at a different commit, and each reports its own. As with the run identity, a config/env variable of the same name wins.

Note: NOVEM_SOURCE_COMMIT is absent, rather than set to a placeholder, for an image with no recorded commit. Check whether the variable is set before using it.

The same commit is written to the run's log beside each step's ref, so a finished run stays traceable once its containers are gone.

Alongside config/ and runs, each job carries:

EndpointAccessDescription
nameread/writeDisplay name.
descriptionread/writeLonger free-form description.
summaryread/writeOne-line summary shown in job listings.
statusread/writeFree-form status text — a place for your pipeline to surface its own state.
shortnamereadThe auto-generated short id (used in URLs).
urlreadThe job's canonical web URL, https://novem.io/j/<shortname>.
notificationsread/writeYour notification level for this job's run events: ignore, info or important. Per caller — it doesn't affect other users.
sharedread/writeWho can see the job: PUT/DELETE a group reference (+org~group, @user~group) or public under it.
tagsread/writeTags on the job — see tags.
varsread/writeJob variables — see vars.
threadsread/writeComment threads on the job; disable with config/options/comments.

Next steps

  • Chains — the pipeline grammar.
  • Schedule — cron syntax and timezones.
  • Runs — triggering, logs, output and retention.