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:
| Key | Values | Description |
|---|---|---|
config/type | chains (default) | The runtime. The chains runtime is the generally available one — see the note on legacy types below. |
config/chains | chain grammar | The pipeline definition — which repo images run, in what order. See chains. |
config/schedule | cron expression | Optional cron trigger, with TZ= and comment support. See schedule. |
config/enabled | true / false (default true) | Kill switch: while false, scheduled triggers are skipped (manual runs still work). |
config/access | claim name | Optional claim for the short-lived NOVEM_TOKEN injected into each run. See run credentials. |
config/env/<name> | any text | Environment 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/spaces | mount mappings | Spaces 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/comments | true / false (default true) | Whether others can comment on the job (its threads). |
config/options/stdin | no / optional / yes | Declare whether callers may or must supply standard input. This is descriptive; it does not change the run API. |
config/options/argv | no / optional / yes | Whether callers may or must pass arguments to the job's first step. See arguments. |
config/options/argv_default | JSON array of strings | Arguments 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/input | no / optional / yes | Declare whether callers may or must upload files. The web run control follows this setting. |
config/options/{stdin,argv,input}_description | text | Instructions shown to callers for the corresponding input. |
Example: pause a job without touching its schedule:
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.optionaladvertises the input without requiring it.yesmarks 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:
- the
argvthe caller passed with the run, when the job runs on thechainsruntime andconfig/options/argvisoptionaloryes(see triggering a run); - otherwise
config/options/argv_default, whateverargvis set to; - otherwise none, and the image runs its
CMDas 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.
["/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:
| Variable | Example | Description |
|---|---|---|
NOVEM_JOB | /u/alice/j/daily_report | The job's path — /u/<user>/j/<job>. |
NOVEM_JOB_RUN | 20260812-101500-3f9a1c | The run id, the <run> in /v1/users/<user>/code/jobs/<job>/runs/<run> — same <user> and <job> as NOVEM_JOB. See runs. |
NOVEM_API_ROOT | https://api.novem.io/v1/ | The API base, /v1/ included — the form the novem Python library and CLI read. |
NOVEM_USERNAME | bob | The 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:
| Variable | Example | Description |
|---|---|---|
NOVEM_SOURCE_REPO | alice/data_fetcher | The repo the step's image came from, <user>/<repo>. |
NOVEM_SOURCE_REF | latest | The ref as the chain named it, so prod for @alice/data_fetcher:prod. Defaults to latest. |
NOVEM_SOURCE_COMMIT | 1a2b3c4d5e6f7890abcdef1234567890abcdef12 | The 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.
Metadata and related endpoints
Alongside config/ and runs, each job
carries:
| Endpoint | Access | Description |
|---|---|---|
name | read/write | Display name. |
description | read/write | Longer free-form description. |
summary | read/write | One-line summary shown in job listings. |
status | read/write | Free-form status text — a place for your pipeline to surface its own state. |
shortname | read | The auto-generated short id (used in URLs). |
url | read | The job's canonical web URL, https://novem.io/j/<shortname>. |
notifications | read/write | Your notification level for this job's run events: ignore, info or important. Per caller — it doesn't affect other users. |
shared | read/write | Who can see the job: PUT/DELETE a group reference (+org~group, @user~group) or public under it. |
tags | read/write | Tags on the job — see tags. |
vars | read/write | Job variables — see vars. |
threads | read/write | Comment threads on the job; disable with config/options/comments. |