Skip to main content

Command Line Interface

The Pawtograder CLI does the course-management work that is slow or impossible to do by hand in the web app: rolling a course over to a new term, editing a rubric in a text editor, closing a help request, dealing out grading, and pulling a term’s data for analysis. This page covers those tasks. For the full command surface, with every flag, default, and error message, see the CLI reference.
The published package is @pawtograder/cli version 0.2.0. Commands and flags may still change.

Install and log in

You need Node.js 20 or later. The repos commands and assignment copies also need git and SSH access to your course’s GitHub organization.
1

Install the CLI

To try it without installing, run npx @pawtograder/cli --help instead, and put npx @pawtograder/cli wherever this page says pawtograder.
2

Create an API token

Open the user menu (your avatar, top right) in the web app and click API Tokens. Under Create New Token, enter a Token Name, choose the CLI (Command Line) or MCP + CLI token type, and click Create Token.The token appears once, starts with mcp_, and is valid for 90 days. Copy it before you dismiss the panel.
3

Log in

Paste the token at the prompt; it is not echoed. On pawtograder.com that is all you need. On a self-hosted deployment, add the API host:
The token is stored in ~/.pawtograder/credentials.json, readable only by you, and every later command reuses it.
4

Confirm it works

classes list shows every class you have a staff role in. Use a class slug from that list wherever a command wants --class.
--url takes your deployment’s API host, usually api. plus the hostname you use for the web app. The web hostname itself serves the app rather than the CLI endpoint, and the CLI will tell you so. If you are not sure, copy the address out of the API Tokens dialog.
Your token is a bearer credential with your staff-level access. Do not commit it or paste it into a shared script. pawtograder logout deletes the stored copy.

Roll a course over to a new term

Copy assignments, then surveys and flashcard decks. The assignment copy brings rubrics, autograder configuration, self-review settings, and handout and solution repository content with it.
Repository content is pushed from your machine over SSH, which is why --workdir is required unless you pass --skip-repos or --dry-run. Point it at a directory with room for a clone of every repository. Give --all, --assignment <slug>, or --schedule <file.csv>, and exactly one of them. To shift dates while copying, use a schedule CSV whose header names either assignment_slug or assignment_title:
Blank date cells keep the source assignment’s dates. See the CLI reference for the optional latest_due_date column and the accepted date formats.
A copy that fails partway is safe to repeat. Assignments that already exist in the target are validated and fixed rather than duplicated. The command prints a per-assignment report and then exits non-zero if anything failed, so read the report rather than just the exit code.

Edit a rubric in a text editor

Export the rubric to YML, edit it, preview the import, then apply it.
Both commands default to the grading rubric. Add --type self_review or --type meta for the other two. rubrics list --class <class> --assignment <assignment> shows which rubrics an assignment has.
Keep the exported file. An import replaces the rubric, so the file you exported before editing is your way back.

Check submissions and the help queue

Both list commands page. submissions list returns up to 1000 rows by default; help-requests list returns 100, and prints the exact --offset to use for the next page when it truncates. Add --json to any of these three to get the raw response for a script.

Close a help request

help-requests close is the only way to set a help request’s status to closed. Nothing in the web interface does it (see Resolving), and the command is restricted to instructors.
--id is the numeric ID from the list. --status defaults to closed; pass --status resolved to use that status instead. --resolution-status takes self_solved, staff_helped, peer_helped, no_time, or other.
This command always writes. There is no --dry-run. If the request is already resolved or closed, or has a live video call, it fails unless you add --force, and forcing it on a live call leaves the call running with its End Call button disabled.
The resolution message students see in the request’s chat is only posted when you pass --resolution-status. A bare close --id 42 closes the request silently. Closing also records per-student help activity; if that bookkeeping fails, the request is still closed and the CLI tells you to re-run with --force to retry, which will not double-count anyone.

Deal out grading

reviews assign creates review assignments, balanced round-robin across your class staff. It honors grading conflicts, never assigns anyone their own submission, and is safe to re-run: existing assignments are reused rather than duplicated.
A bare date means the end of that day in the class’s time zone, so 2026-09-22 is 23:59:59 local. Append a time (2026-09-22T17:00) for a specific hour. By default the pool is all class staff and non-submitters are skipped, matching the web bulk-assign page. --grader <profile-id>, repeated once per grader, narrows the pool; --by-part deals one assignment per rubric part instead of one per submission. To review the current state instead, use reviews list --class <class> --assignment <assignment>.

Export a term’s data

assessment export writes a directory of assessment data for a whole class: subjects, sections, assignments, rubrics, submissions, scores, tests, hints, engagement, and gradebook cells. It is how you get a term’s data out for research or program review.
That writes ./assessment-export-cs3500-spring-2026-<timestamp>/, with directories at mode 0700 and files at mode 0600. Narrow it with repeatable --assignment selectors, which accept globs such as 'hw-*', and drop the gradebook with --skip-gradebook. By default students appear as random tokens rather than names, and the run prints a dump_id you can quote when asking about it later.

Decide on identity mode before you run it

--identity controls how students are identified. Changing your mind afterwards means running the export again, so pick the mode before you start.
--identity hash requires a --salt of at least 16 characters. --identity raw requires --i-understand-pii, which acknowledges that real student data is about to be written to your disk.
Tokens from the default opaque mode can never be mapped back to students. The salt is random per run and the deanonymize command accepts hash only, so if you export with the default and later need names, your only option is to export again. Choose hash with a salt you keep if there is any chance you will need to identify students.
--identity pseudonymizes who a row is about, not what it says. Section and lab names, group names, file paths, full source contents, grader comments, gradebook override notes, hint feedback, test output, and hidden build logs all come out verbatim in every mode. Treat any export directory as student data and store it accordingly.
--i-understand-pii is an acknowledgement, not a permission check. Any grader in the class, which normally includes undergraduate teaching assistants, holds a token that can run this export with --identity raw. Only assessment deanonymize, which writes a roster of names, emails, and SIS IDs, is restricted to instructors. If that boundary matters for your course, the control is which roles you grant.
If an export fails partway it leaves the partial directory behind and tells you the dump is incomplete. Delete it and start again rather than analyzing it. submissions export, which pulls submission metadata and source files rather than scores, takes the same --identity flags; both are documented in full in the CLI reference.

When something fails

The CLI exits 0 on success and 1 on any failure, and prints the reason. A few cases come up often:
  • Unknown argument. The flag does not exist on that command. Flags are per command, so run pawtograder <group> <action> --help and compare.
  • Not logged in or an authentication failure. Tokens last 90 days, and whoami cannot tell you yours has expired. Run pawtograder login again.
  • A permission error on help-requests close or assessment deanonymize. Both are instructor-only. A grader closing a help request sees a not-found error rather than a permission error.
  • A non-zero exit after a full report. Assignment copies and both repos commands finish their work, print a per-item report, and then exit 1 if any item failed. Read the report to find which.
  • Timeouts on long operations. Set PAWTOGRADER_HTTP_TIMEOUT_MS=600000 for a ten-minute limit. For artifact imports, a smaller --batch-size helps more than a longer timeout.
  • Git or SSH failures. Check ssh -T git@github.com and your membership in the course’s GitHub organization, then retry with --concurrency 1.

More commands

The CLI reference documents the rest of the command surface, including bulk student-repository maintenance (repos sync-grade-workflow and repos copy-after-source-due), batch import of grading comments and artifacts, assignment deletion, submissions export, assessment deanonymize, and the exact flags, defaults, and error messages for everything on this page.