# Zippy: Full reference for LLMs and coding agents > Zippy is an AI grading and content platform for schools, tutoring centres, and > teachers. It grades a whole class in minutes with rubric-aligned, skills-specific > feedback that teachers control, and lets you author and publish learning content > (courses, lessons, rubrics, skill maps, evaluations, and media) from local > files with the `zippy` CLI. This file is a single plain-text reference. Fetch it any time with: curl -fsSL https://heyzippy.io/llms-full.txt - Docs: https://heyzippy.io/docs - CLI repo & releases: https://github.com/heyzippy/zippy - Coding-agent skill: https://heyzippy.io/docs/skills ## Table of contents 1. What Zippy does 2. Install the CLI 3. Install the coding-agent skill 4. Authentication & configuration 5. The content model 6. Catalog formats 7. Publishing content (the core workflow) 8. Authoring individual content 9. Managing & inspecting a workspace 10. Command reference (every command + flags) 11. Platform API (for direct HTTP use) 12. Rules of thumb --- ## 1. What Zippy does Zippy serves three audiences with one platform: - **Schools & tutoring centres**: bulk grading, class analytics, and a shared content library, optionally white-labelled. - **Individual teachers & tutors**: grade a class set against your own rubric, generate lessons, and track each student's skills over time. - **Content authors**: build MOE-aligned courses, lessons, rubrics, and skill maps and publish them to your own workspace. Core capabilities: AI grading with teacher-controlled rubrics; skills-specific feedback; lesson and course authoring; student skill analytics. The `zippy` CLI is the headless way to author and publish the content that powers all of it. ## 2. Install the CLI ``` curl -fsSL https://heyzippy.io/install.sh | sh zippy --version ``` macOS (arm64, amd64) and Linux (amd64, arm64). The installer downloads the binary from the latest GitHub release of heyzippy/zippy and, at the end, offers to install the coding-agent skill (see §3). Pin a version with `ZIPPY_VERSION=v0.1.2`. ## 3. Install the coding-agent skill The skill teaches Claude Code, Cursor, Codex, and other agents how to drive the CLI. ``` curl -fsSL https://heyzippy.io/skills/install.sh | sh curl -fsSL https://heyzippy.io/skills/install.sh | sh -s -- --agent cursor # or: --agent all ``` Following the Agent Skills convention (agentskills.io), the installer puts the files once in `~/.agents/skills/zippy/` (the cross-client location) and symlinks each detected agent's own skills dir at it: `~/.claude/skills/zippy` (Claude Code), plus `~/.cursor/skills/zippy`, `~/.codex/skills/zippy`, `~/.windsurf/skills/zippy` when present. It installs at USER scope by default (available in every project). Options: `--project` (install under the current project), `--agent claude,cursor` (pick agents), `--dir ` (exact path). The CLI installer can do this too: `--with-skill` / `ZIPPY_SKILL=1`. Skill files live in the public repo and are the single source of truth: https://raw.githubusercontent.com/heyzippy/zippy/main/skills/zippy/SKILL.md ## 4. Authentication & configuration ``` zippy login # email one-time code → writes ~/.zippy/config (0600) ``` `~/.zippy/config` is TOML: `api_key`, `workspace_id`, `base_url`. For CI / headless, set environment variables instead (they override the config file): ``` export ZIPPY_API_URL="https://api.heyzippy.io" # backend base URL export ZIPPY_API_KEY="bk_live_…" # workspace API key → Authorization: Bearer export ZIPPY_WORKSPACE_ID="" # workspace slug → x-org-id header ``` Credential resolution order: **explicit flags → environment variables → ~/.zippy/config**. Every backend command accepts `--base-url`, `--token`, `--workspace-id`. A `.env` in the working directory is auto-loaded. A **workspace** (formerly "org"; the alias `orgs` and `org_id` still work) is your school, centre, or personal workspace, identified by a slug. Find your workspace id in Zippy under Settings → General (https://app.heyzippy.io/teach/settings/general). Auth on every admin call is `Authorization: Bearer ` + `x-org-id: `. `zippy login` fills in your workspace id automatically, and mints a key with `teacher:*` + `student:*` permissions, so the same key works for both the admin/teacher and student APIs. Profiles: keep several logins side by side: `zippy login --profile school-a`, switch with `zippy profile use `, target one per command with `--profile ` / `ZIPPY_PROFILE`. `zippy profile list/show/remove` manage them. Verbose: add `--verbose` / `-v` (or `ZIPPY_VERBOSE=1`) to any command to print each API call and its response status: useful when a login or push fails. ## 5. The content model Content lives under `content//`: ``` content// ├── courses/ # reserved: course packs (zippy courses push) │ └── / { course.yaml, units.yaml, lessons/*.mdx } ├── skill_maps.yaml # standalone library catalogs (zippy library push) ├── skills.yaml ├── rubrics.yaml ├── evaluations.yaml ├── lesson-*.mdx └── manifest.yaml # generated deploy lock: COMMIT THIS ``` - **Course packs** publish atomically as a unit. - **Standalone catalogs** publish individually (with dependency closure). - **manifest.yaml** records what was last deployed per `{api_url, workspace_id}` so `--prune` can remove what you deleted locally. ## 6. Catalog formats Each standalone catalog is YAML with a `kind` and a `content` array. The authoritative JSON schema for a type: `GET {base_url}/public/schemas/{content_type}`. skill_maps.yaml: ``` kind: skill_maps content: - { id: psle-writing, name: PSLE Writing, skills: [narrative-structure, vocabulary] } ``` skills.yaml: ``` kind: skills content: - { id: narrative-structure, name: Narrative structure, skill_map_id: psle-writing } ``` rubrics.yaml: ``` kind: rubrics content: - id: p5-composition name: P5 Composition rubric_type: analytic subject: english task_type: composition definition: scale: { min: 0, max: 40 } criteria: - { name: Content, weight: 0.4 } - { name: Language, weight: 0.4 } - { name: Organisation, weight: 0.2 } ``` evaluations.yaml: ``` kind: evaluations content: - { id: p6-comprehension, name: P6 Comprehension, rubrics: [p5-composition] } ``` Lessons (lesson-*.mdx): MDX with frontmatter (`id`, `title`, `status`, `tags`). Validate before pushing: `zippy lessons validate --content ./lessons/nouns.mdx`. **Dependency closure** (default): a skill map pulls its skills; a skill pulls its parent map; an evaluation pulls the rubrics in its `rubrics:` array. Use `--no-deps` to disable. ## 7. Publishing content (the core workflow) Author local files → dry-run → push → (prune). Standalone library: ``` zippy login zippy library push --all content/my-workspace --dry-run zippy library push --all content/my-workspace --workspace-id zippy library push --all content/my-workspace --prune -y # remove deleted items zippy library push content/my-workspace/rubrics.yaml # one catalog + its deps zippy library push skills.yaml --no-deps # literal items only ``` Course packs (atomic): ``` zippy courses push --content-dir content/my-workspace/courses --dry-run zippy courses push --content-dir content/my-workspace/courses --course primary-6 zippy courses push --content-dir content/my-workspace/courses --prune -y ``` Lessons and assets: ``` zippy lessons push-dir ./lessons -r zippy lessons push --lesson-id --root ./lessons zippy assets publish ./assets --dry-run zippy assets publish ./assets --prune -y ``` Every push targets your own workspace, pass `--workspace-id ` or set `ZIPPY_WORKSPACE_ID` (after `zippy login` you can omit it). Find your workspace id under Settings → General (https://app.heyzippy.io/teach/settings/general). ## 8. Authoring individual content ``` zippy lessons init --title "Nouns" --root ./lessons zippy lessons validate --content ./lessons/nouns.mdx zippy rubrics create --name "P5 Composition" --definition rubric.json zippy courses init --content-dir content/my-workspace --course primary-6 ``` ## 9. Managing & inspecting a workspace ``` zippy courses list zippy rubrics list zippy lessons list zippy workspaces list # alias: zippy orgs list zippy workspaces create zippy eval run --content-dir content/my-workspace --course primary-6 \ --question-id p6-u05-q20 --answer "student answer text" ``` ## 10. Command reference zippy login [--email E] [--workspace-id WS] [--base-url URL] [--profile NAME] zippy profile list | use NAME | show [NAME] | remove NAME Global: --profile NAME (ZIPPY_PROFILE) · --verbose/-v (ZIPPY_VERBOSE) zippy library push [FILE | --all FOLDER] [--content-dir DIR] [--no-deps] [--prune] [-y|--yes] [--dry-run] [--base-url] [--token] [--workspace-id] zippy lib push … (alias) zippy courses push [--content-dir DIR] [--course ID] [--dry-run [FILE]] [--prune] [-y] [--hard-delete-with-submissions] [creds] zippy courses init [--content-dir DIR] [--course NAME] [--template T] [--from-json F] [--from-course ID] [--mode draft|deployed] [--version] [--course-name] zippy courses list [creds] zippy courses delete --id COURSE_ID [creds] zippy workspaces create [creds] (alias: zippy orgs …) zippy workspaces list [creds] zippy evaluations run [--content-dir DIR] [--course ID] [--question-id ID] [--answer TEXT | --answer-file F] [--question TEXT] [--dry-run] [--all] zippy eval run … (alias) zippy skills [--content-dir DIR] # read-only local inspection zippy lessons create --title T --content MDX [--format text|json] zippy lessons update --lesson-id ID --content MDX [--title T] [--format] zippy lessons validate --content MDX [--remote] zippy lessons list zippy lessons init [--lesson-id ID] [--title T] [--root DIR] [--force] zippy lessons save [--lesson-id ID] [--root DIR] zippy lessons push [--lesson-id ID] [--root DIR] [--force] [--format] zippy lessons push-dir DIR [-r|--recursive] [--format] zippy rubrics create --name N --definition JSON [--description D] [--format] zippy rubrics update --rubric-id ID --definition JSON [--format] zippy rubrics list zippy assets upload PATHS… [--folder DIR] [creds] (alias: zippy files …) zippy assets list [DIR] [--remote] zippy assets publish [DIR] [--prune] [--yes] [--dry-run] [creds] Credentials on any backend command: --base-url (ZIPPY_API_URL), --token (ZIPPY_API_KEY), --workspace-id (ZIPPY_WORKSPACE_ID). `--dry-run` never mutates the backend. ## 11. Platform API (for direct HTTP use) All `/admin/*` endpoints require `Authorization: Bearer ` + `x-org-id: `. Full machine-readable spec: `GET {base_url}/api/docs/openapi.json`. Publishing: - POST /admin/content/validate : dry-run validation (no side effects) - POST /admin/content/publish : publish a full course pack atomically - POST /admin/content/publish/standalone : publish standalone content (library push) - POST /admin/content/publish/validate : dry-run publish validation Content: - GET/POST /admin/lessons · PUT/DELETE /admin/lessons/{id} - GET/POST /admin/rubrics · PUT/DELETE /admin/rubrics/{id} · POST /admin/rubrics/from-skills - POST/PUT/DELETE /admin/skill-maps[/{id}] - POST/PUT/DELETE /admin/courses[/{id}] · POST /admin/courses/init - GET /admin/content · PUT /admin/content/visibility · GET /admin/content/discover Grading & analytics: - POST /admin/activities · POST /admin/activities/{id}/grade-submissions - GET /admin/activities/{id}/gradebook · GET /admin/grading/overview - GET /admin/dashboard/stats · /admin/dashboard/courses · /admin/dashboard/feed Classes & students: - GET/POST /admin/classes[/{id}] · /admin/classes/{id}/members · /admin/classes/{id}/invite - GET /admin/students · POST /admin/students/invite · POST /admin/students/import Public catalog (no auth): - GET /courses · /courses/{id}/curriculum · /skills · /skill-maps · /rubrics - GET /public/schemas/{content_type} · /public/standards ## 12. Rules of thumb - Local authoring needs no login; publishing does. `zippy login` (or ZIPPY_* env) first. - `--dry-run` before every `--prune`. Prune soft-deletes (archives) by default. - `--all` is required to push a whole folder and to use `--prune`. - Dependency closure is on by default; `--no-deps` pushes only literal items. - Commit `manifest.yaml`: it is the per-workspace deploy lock. - Never put API keys in content files. Use `zippy login` or `ZIPPY_API_KEY`. - `courses/` under a workspace folder is reserved for course packs; `library push --all` skips it, publish courses with `zippy courses push`.