Roasting
Roast commands
Record roasts, import and download Artisan .alog files, and watch a folder for new roasts.
Record roasts, import Artisan .alog files with their curves and milestones, download the file a roast was imported from, and watch a folder so new roasts are captured automatically.
Access: Member. Requires member access on your account.
purvey roast list
List your roast profiles, sorted by date.
Usage: purvey roast list [options]
Access: Member. Requires member access on your account.
- --coffee-id expects inventory_id, not catalog_id.
- --catalog-id filters by catalog ID.
- --date-start and --date-end accept YYYY-MM-DD format.
- --search takes up to 100 characters and is matched as written: % and _ are ordinary characters, and * stands for any one character. A number finds the roast with exactly that ID, and any roast with the number in its coffee or batch name. Search text that is refused exits 2; the message calls the search text q.
- Every filter narrows the list together: --search with --coffee-name, --batch-name, or --roast-id returns only roasts that match all of them.
- --wholesale false includes roasts of coffees with no catalog listing, so true and false together cover every roast.
- --include-totals adds meta.totals { roasts, batches, average_loss_percent } for every roast the filters match, the same on every page. average_loss_percent is null when no matching roast has a recorded weight loss. An empty result prints data: [] with totals of zero. It does not support --csv.
- Paging: raise --offset by --limit. With --include-totals, a page is the last one when --offset plus the number of roasts returned reaches meta.totals.roasts.
- Without --include-totals the output is a list of roasts, and an empty result prints nothing on stdout.
- Every roast includes batch_id, the ID of the batch it belongs to.
- artisan_file_available is true when roast artisan-file can return the Artisan file the roast was imported from.
| Argument or flag | Details |
|---|---|
--coffee-id <id> | Only roasts of this inventory item (an inventory ID, not a catalog ID). |
--roast-id <id> | Only the roast with this roast ID. |
--batch-id <uuid> | Only the roasts in this batch (a batch ID from roast-batch list). |
--batch-name <text> | Only roasts whose batch name contains this text (case-insensitive); names can repeat, so this can span several batches. |
--coffee-name <text> | Only roasts of coffees whose name contains this text (case-insensitive). |
--search <text> | Only roasts whose coffee name or batch name contains this text (case-insensitive), or whose roast ID is this number, with or without a leading #. |
--date-start <YYYY-MM-DD> | Only roasts on or after this date. |
--date-end <YYYY-MM-DD> | Only roasts on or before this date. |
--stocked | Only roasts of coffees still marked as in stock in your inventory. |
--catalog-id <id> | Only roasts of coffees bought from this catalog coffee (a catalog ID). |
--wholesale <true|false> | true for roasts of wholesale coffees only, false for every other roast; without it, both. |
--include-totals | Print { data, meta } instead of a list: data is the page of roasts, and meta.totals counts every roast the filters match. |
--limit <n> | Maximum number of roasts to return. Default: 20. |
--offset <n> | Number of roasts to skip when paging. Default: 0. |
purvey roast list --search "guji" --include-totals
purvey roast list --wholesale false --limit 20 --offset 20
purvey roast list --date-start 2026-03-01 --date-end 2026-03-31
purvey roast list --batch-id 7c1d4e2a-9b3f-4a6c-8d5e-2f1a0b9c8d7epurvey roast get
Get a single roast profile.
Usage: purvey roast get <id> [options]
Access: Member. Requires member access on your account.
- artisan_file_available is true when roast artisan-file can return the Artisan file the roast was imported from.
| Argument or flag | Details |
|---|---|
<id> | Required: Roast ID. |
--include-temps | Add the full temperature curve; output can be large. |
--include-events | Add roast event markers such as first crack and drop. |
purvey roast chart
Get sampled chart data for one roast: temperature series, events, and chart revision.
Usage: purvey roast chart <id> [options]
Access: Member. Requires member access on your account.
- Returns the roast chart data unchanged: sampled series, events, and metadata.
- data.metadata.revision identifies the immutable chart revision used by reference-profile compare.
| Argument or flag | Details |
|---|---|
<id> | Required: Roast ID. |
--target-points <n> | Approximate number of samples per temperature series. Default: 400. Range: 50 to 1000. |
purvey roast chart 123 --pretty
purvey roast chart 123 --target-points 120 | jq '.data.metadata.revision'purvey roast artisan-file
Download the Artisan file a roast was imported from, exactly as you uploaded it.
Usage: purvey roast artisan-file <id> [options]
Access: Member. Requires member access on your account.
- Writes the file byte for byte, checks it against its SHA-256, and prints a JSON receipt: data.path, data.bytes, data.sha256. A file that fails the check is removed.
- Requires Studio access on your account; API keys need the roast:read scope.
- A roast has a file when artisan_file_available is true in roast get or roast list. Roasts entered by hand, logged live, or imported before files were kept have none; the error message says which.
| Argument or flag | Details |
|---|---|
<id> | Required: Roast ID. |
--output <path> | File to write, or an existing folder to save the file in under its original name. Defaults to the current folder. |
--force | Overwrite the output file if it already exists. |
purvey roast artisan-file 123
purvey roast artisan-file 123 --output ~/artisan/purvey roast create
Create a new roast profile.
Usage: purvey roast create [options]
Access: Member. Requires member access on your account.
- Pass --batch-id or --batch-name, not both. The created roast includes batch_id.
| Argument or flag | Details |
|---|---|
--coffee-id <id> | Inventory ID of the coffee you roasted (not a catalog ID). Required unless you use --form. |
--batch-id <uuid> | Add the roast to this existing batch, whatever the roast date; the roast takes the batch's name. Use instead of --batch-name. |
--batch-name <name> | Add the roast to your batch with this name on the roast date, or start one; defaults to the coffee name plus today's date. |
--oz-in <oz> | Green coffee weight going in, in ounces. |
--oz-out <oz> | Roasted coffee weight coming out, in ounces. |
--roast-date <YYYY-MM-DD> | Date of the roast; defaults to today. |
--notes <text> | Free-text notes about the roast. |
--targets <text> | What you were aiming for, such as "FC at 390F, 18% development". |
--roaster-type <text> | Roaster model or type, such as Aillio Bullet. |
--form | Prompt for an inventory coffee, batch name, weight in, notes, and targets; the roast date is set to today and targets are saved in the notes. |
purvey roast update
Update a roast profile.
Usage: purvey roast update <id> [options]
Access: Member. Requires member access on your account.
- --batch-id and --batch-name move this roast between batches. To rename a batch, use roast-batch update --name.
| Argument or flag | Details |
|---|---|
<id> | Required: Roast ID. |
--notes <text> | Replace the roast notes. |
--oz-out <oz> | New roasted weight, in ounces; weight loss is recalculated when the green weight is known. |
--batch-id <uuid> | Move the roast into this batch; use instead of --batch-name. |
--batch-name <name> | Move the roast into your batch with this name on the roast date, or start one. |
--targets <text> | Replace the roast targets. |
purvey roast delete
Delete a roast profile.
Usage: purvey roast delete <id> [options]
Access: Member. Requires member access on your account.
- Deleting the last roast in a batch leaves the batch in place, empty. Remove it with roast-batch delete.
| Argument or flag | Details |
|---|---|
<id> | Required: Roast ID. |
--yes | Delete without asking for confirmation; needed in scripts and agents. |
purvey roast import
Import an Artisan .alog roast file.
Usage: purvey roast import [file] [options]
Access: Member. Requires member access on your account.
- Pass --batch-id or --batch-name, not both.
- The result includes batch_id; pass it as --batch-id to import the next file into the same batch.
| Argument or flag | Details |
|---|---|
[file] | Optional: Path to Artisan .alog file. |
--coffee-id <id> | Inventory ID of the coffee you roasted (not a catalog ID). Required unless you use --form. |
--batch-id <uuid> | Add the roast to this existing batch, whatever the roast date; the roast takes the batch's name. Use instead of --batch-name. |
--batch-name <name> | Add the roast to your batch with this name on the roast date, or start one; defaults to the coffee name plus the roast date. |
--oz-in <oz> | Green coffee weight going in, in ounces; overrides the weight read from the .alog file. |
--roast-notes <text> | Notes to save with the imported roast. |
--roast-targets <text> | What you were aiming for, saved with the imported roast. |
--form | Pick the file and inventory item interactively. |
purvey roast from-reference
Create a roast from the Artisan file saved with a reference profile.
Usage: purvey roast from-reference <profile-id> <revision-id> [options]
Access: Member. Requires member access on your account.
- Creates the roast from the Artisan file uploaded with reference-profile import, so the .alog file does not need to be on this machine.
- Only an uploaded Artisan reference can become a roast. A generated plan is never recorded as a roast, and a reference saved from a past roast is refused because that roast is already in your history.
- Output is the created roast with its curve, an import summary, and the reference it came from.
- Pass --batch-id or --batch-name, not both.
- Requires a member credential and Studio access on your account.
| Argument or flag | Details |
|---|---|
<profile-id> | Required: UUID of an uploaded Artisan reference profile. |
<revision-id> | Required: UUID of that profile's current revision. |
--coffee-id <id> | Required. Inventory ID of the coffee you roasted (not a catalog ID). |
--batch-id <uuid> | Add the roast to this existing batch, whatever the roast date; the roast takes the batch's name. Use instead of --batch-name. |
--batch-name <name> | Add the roast to your batch with this name on the roast date, or start one; defaults to the coffee name plus the roast date. |
--roast-date <YYYY-MM-DD> | Date of the roast; defaults to the date in the saved Artisan file. |
--oz-in <oz> | Green coffee weight going in, in ounces; overrides the weight in the saved Artisan file. |
--oz-out <oz> | Roasted weight coming out, in ounces; overrides the weight in the saved Artisan file. |
--roast-notes <notes> | Notes to save with the new roast. |
--roast-targets <targets> | What you were aiming for, saved with the new roast. |
--idempotency-key <key> | Key that makes retries safe: repeating the command with the same key does not create a second roast. A new key is generated when omitted. |
purvey roast from-reference 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --coffee-id 7 --prettypurvey roast watch
Watch a directory for new Artisan .alog files.
Usage: purvey roast watch [directory] [options]
Access: Member. Requires member access on your account.
- --auto-match is mutually exclusive with --coffee-id.
- --auto-match matches each new roast to a stocked inventory item from its metadata.
- --commit-mode defaults to batch so new roasts are queued until the session ends.
- In batch commit mode the session opens one new batch, named by --batch-prefix, and saves every roast into it by batch ID. It stays one batch when the name was used before and when the session runs past midnight. The closing summary prints the batch ID.
- --resume keeps adding to the same batch. A session saved by an earlier CLI version, which stored only the batch name, continues in the batch that holds its first saved roast.
- The batch is opened when the first roast is saved. If no roast is saved into it, for example when every import fails, it is removed when the session ends.
- In individual commit mode each roast is its own batch, named "<name> #1", "<name> #2", and so on.
| Argument or flag | Details |
|---|---|
[directory] | Optional: Directory to watch. |
--coffee-id <inventory_id> | Inventory ID to attach every new roast to; required unless you use --auto-match, --resume, or --form. |
--batch-prefix <name> | Batch name for the watch session; defaults to the coffee name. Batch commit mode saves every roast into one new batch with this name, and individual commit mode numbers them like "<name> #1". |
--prompt-each | Ask which inventory item each new file belongs to instead of attaching every file to --coffee-id. |
--auto-match | Match each new roast to a stocked inventory item automatically from details in its .alog file; cannot be combined with --coffee-id. |
--commit-mode <batch|individual> | batch queues new roasts and saves them into one new batch when you stop watching, so the session is a single batch; individual saves each roast as soon as its file appears, as its own numbered batch. Default: batch. |
--oz-in <oz> | Green coffee weight, in ounces, to record for every watched import. |
--roast-notes <text> | Notes to save with every watched import. |
--roast-targets <text> | Roast targets to save with every watched import. |
--resume | Continue the last watch session with its saved directory, settings, import progress, and batch. |
--form | Set up the directory, coffee, and commit mode interactively. |