CLI Reference
Complete reference for Teachfloor CLI commands and options.
Installation
Code
Command Reference
Quick Reference Table
| Command | Description | Requires Auth | Requires App Folder |
|---|---|---|---|
| Global | |||
teachfloor version | Display CLI version | No | No |
teachfloor login | Authenticate with Teachfloor | No | No |
teachfloor logout | Log out from account | No | No |
teachfloor whoami | Show current user and org | Yes | No |
| App Management | |||
teachfloor apps create <name> | Create new app | Yes | No |
teachfloor apps start | Start dev server | Yes | Yes |
teachfloor apps upload | Build and upload app | Yes | Yes |
| View Management | |||
teachfloor apps add view | Add view to app | Yes | Yes |
teachfloor apps remove view | Remove view from app | Yes | Yes |
teachfloor apps add settings | Add settings view | Yes | Yes |
teachfloor apps add widget | Add widget to app | Yes | Yes |
teachfloor apps remove widget | Remove widget from app | Yes | Yes |
| Permission Management | |||
teachfloor apps grant permission | Add permission | Yes | Yes |
teachfloor apps revoke permission | Remove permission | Yes | Yes |
| Webhook & OAuth | |||
teachfloor apps set webhook | Configure webhook URL and events | Yes | Yes |
teachfloor apps remove webhook | Remove webhook block | Yes | Yes |
teachfloor apps set oauth | Configure OAuth grant type | Yes | Yes |
teachfloor apps remove oauth | Remove OAuth block | Yes | Yes |
| Distribution | |||
teachfloor apps set distribution | Set public/private | Yes | Yes |
| Inspection | |||
teachfloor apps show | Print a spec-sheet summary of the current app | Yes | Yes |
| Diagnostics | |||
teachfloor apps doctor | Diagnose common setup issues | Yes | No |
Non-Interactive Mode
Every prompt in every command has a matching flag. Pass all the flags a command needs and the CLI runs end-to-end without asking questions — required for scripts, CI pipelines, and AI-driven workflows.
Three triggers (any one flips the CLI into non-interactive mode):
--nonInteractiveon the command (alias:--non-interactive,--no-interactive).- Environment variable:
TF_NON_INTERACTIVE=1orCI=1. - Automatic: whenever stdin isn't a TTY (piped input, subprocess spawn, headless agent).
In non-interactive mode:
- A prompt whose flag is set → uses the flag value (validated).
- A prompt whose flag is missing but has a default → uses the default (validated).
- A prompt whose flag is missing and has no default → hard error:
Missing required input in non-interactive mode: pass --<flag> to set "<field>". - Invalid values (bad choice, failed regex, empty required string) → error naming the flag, with the underlying validator's message.
Example — scripted apps create:
Code
No --nonInteractive needed when stdin isn't a TTY — piping / subprocess spawn triggers it automatically. Add the flag explicitly in wrapper scripts if you want fail-fast behavior regardless of shell context.
Flag → prompt mapping (per command):
| Command | Flags |
|---|---|
apps create <name> | --appId, --name, --description, --version |
apps add view | --viewport, --componentName, --withExample, --overwrite |
apps add settings | --componentName, --withExample |
apps add widget | --viewport, --id, --name, --description, --componentName, --withExample, --overwrite |
apps remove view | --viewport, --removeComponent |
apps remove widget | --id, --removeComponent |
apps grant permission | --permissionName, --explanation |
apps revoke permission | --permissionName |
apps set webhook | --url, --events (repeatable, or comma-separated) |
apps set oauth | --oauthType |
apps set distribution | --distributionType |
login remains interactive-only (browser OAuth).
Global Commands
teachfloor version
Display CLI version and check for updates.
Code
Output:
Code
teachfloor login
Authenticate with your Teachfloor account.
Code
Prompts:
- Email address
- Password
- Organization (if you have multiple)
What it does:
- Authenticates with your Teachfloor account
- Stores credentials securely
- Saves selected organization
Example:
Code
teachfloor logout
Log out from your Teachfloor account.
Code
What it does:
- Removes stored credentials
- Clears organization selection
teachfloor whoami
Display current authenticated user and organization.
Code
Output:
Code
App Management
teachfloor apps create <app-name>
Create a new Teachfloor app.
Code
Arguments:
app-name: Name of the folder to create
Prompts (interactive mode) / Flags (non-interactive):
- App ID —
--appId <value>(alias--id; default:<slug>-<timestamp>) - Display Name —
--name <value>(required) - Description —
--description <value>(required) - Version —
--version <value>(semver, default:1.0.0)
What it does:
- Creates app on the platform
- Generates project structure with all necessary files
- Installs dependencies
Generated Structure:
Code
Example:
Code
Save the Client Secret now. It's shown once at create time and never returned by the API again — if you lose it, you can retrieve it from Developers → Apps → your app → OAuth Client Secret in the Teachfloor dashboard. The Client ID is also delivered inside every app.installed webhook payload; the Client Secret is not. See OAuth for how to use these credentials for the refresh flow.
teachfloor apps start
Start development server for your app.
Code
Options:
-m, --manifest <path>: Use custom manifest file
What it does:
- Validates your app manifest
- Uploads manifest to platform
- Opens browser to install the app
- Starts development server with auto-reload
Requirements:
- Must be run inside an app folder
- Must be logged in
- Version must not be approved/published
Example:
Code
With custom manifest:
Code
teachfloor apps upload
Build and upload your app to the platform.
Code
What it does:
- Builds your app for production
- Uploads bundled files to the platform
- Creates a new version
Requirements:
- Must be run inside an app folder
- Must be logged in
- Version must not be already published
Example:
Code
View Management
teachfloor apps add view
Add a new view to your app.
Code
Prompts (interactive mode) / Flags (non-interactive):
- Select viewport —
--viewport <id>(must be one of the app's available viewports) - Component name —
--componentName <PascalCase>(alias--component; defaults to a name derived from the viewport) - Generate example —
--withExample(alias--with-example; default:false) - Overwrite existing file —
--overwrite(only prompted when the target file exists; default:false)
What it does:
- Shows available viewports for your app
- Creates component file in
src/views/ - Updates your app manifest
Example:
Code
Generated Component:
Code
teachfloor apps remove view
Remove a view from your app.
Code
Prompts (interactive mode) / Flags (non-interactive):
- Select viewport —
--viewport <id>(must match an existing view in the manifest) - Delete component file too —
--removeComponent(alias--remove-component; default:false)
What it does:
- Removes view from your app manifest
- Note: Component file remains in
src/views/(delete manually if needed)
Example:
Code
teachfloor apps add settings
Add a settings view to your app.
Code
Prompts (interactive mode) / Flags (non-interactive):
- Component name —
--componentName <PascalCase>(alias--component; default:AppSettings) - Generate example —
--withExample(alias--with-example; default:false)
What it does:
- Creates settings component in
src/views/ - Adds
settingsviewport to your manifest
Example:
Code
teachfloor apps add widget
Add a new widget to your app. See Surfaces for the concepts (widget id, <WidgetView>, admin picker).
Code
Prompts (interactive mode) / Flags (non-interactive):
- Select viewport —
--viewport <pattern>("*"for universal, or a concrete widget-hosting viewport) - Widget id —
--id <slug>(lowercase slug,^[a-z][a-z0-9_]*$, unique per app across all widget declarations) - Widget name —
--name <string>(≤60 chars; shown in the admin's widget picker and the app install-consent surfaces list) - Widget description —
--description <string>(≤200 chars; shown alongside the name in the picker) - Component name —
--componentName <PascalCase>(alias--component; defaults to<PascalId>Widgetderived from the widget id — e.g.streak_daily→StreakDailyWidget) - Generate example —
--withExample(alias--with-example; default:false) - Overwrite existing file —
--overwrite(only prompted when the target file exists; default:false)
What it does:
- Prompts for the widget's scoping viewport
- Validates the widget id locally against ids already in your manifest (fails fast before the server round-trip)
- Creates the component file in
src/views/ - Appends a
surface: "widget"view entry to your manifest with the nestedwidget: { id, name, description }block
Example:
Code
Generated Manifest Entry:
Code
teachfloor apps remove widget
Remove a widget from your app.
Code
Prompts (interactive mode) / Flags (non-interactive):
- Select widget —
--id <slug>(must match a widget id declared in your manifest; picker lists each widget as<id> — <name> (<viewport>)) - Delete component file too —
--removeComponent(alias--remove-component; default:false)
What it does:
- Removes the widget's view entry from your manifest (matched by
widget.id, not viewport — multiple widgets can share the same viewport) - Optionally deletes the component file in
src/views/when--removeComponentis set
Example:
Code
Permission Management
teachfloor apps grant permission
Add a permission to your app.
Code
Prompts (interactive mode) / Flags (non-interactive):
- Select permission —
--permissionName <key>(alias--permission; must be one of the available permissions and not already granted) - Purpose —
--explanation <text>(required — user-facing reason shown on the install screen)
Available Permissions:
Contextual data (SDK):
user:read: Read user profileuser_events:read: Read user activitycourses:read: Read course data (also unlocksGET /v0/courses/*when OAuth is opted in)modules:read: Read module content (also unlocksGET /v0/modules/*when OAuth is opted in)elements:read: Read learning elements (also unlocksGET /v0/elements/*when OAuth is opted in)
Data storage (SDK):
appdata:read/appdata:write: Organization-wide app storageuserdata:read/userdata:write: User-specific storageusercollection:read/usercollection:write: User-specific collection storage
AI (SDK):
ai:text_generate: Consume AI credits to generate textai:context_external_send: Include platform data in external AI requests
Realtime (SDK):
realtime: Publish and subscribe to the app's realtime channels
Public API only (backend/OAuth):
members:read: Read organization members and enrollments viaGET /v0/members/*activities:read: Read activity records viaGET /v0/activities/*
See Permissions for the full description of each permission and OAuth for the scope mapping.
Example:
Code
Updates Manifest:
Code
teachfloor apps revoke permission
Remove a permission from your app.
Code
Prompts (interactive mode) / Flags (non-interactive):
- Select permission —
--permissionName <key>(alias--permission; must match an existing granted permission)
Example:
Code
Webhook & OAuth
teachfloor apps set webhook
Configure the app's webhook URL and the events it subscribes to. Re-run to reconfigure — the whole block is rewritten each time.
Code
Prompts (interactive mode) / Flags (non-interactive):
- URL —
--url <value>(required — must start withhttps://, max 2048 chars) - Events —
--events <name>(multi-select checkbox picker; repeatable flag or comma-separated:--events a --events bOR--events "a,b")
Available Events:
Populated from the server catalog at run time so the CLI always offers exactly the events the platform will accept on upload. Current set includes:
organization.join,course.created,course.updated,course.completed,course.joinmodule.created,module.updatedelement.created,element.updated,element.deleted,element.completedmember.login
The lifecycle events app.installed and app.uninstalled are always delivered — no need to include them in the manifest.
Example:
Code
Updates Manifest:
Code
teachfloor apps remove webhook
Strip the webhook block from the manifest. The app becomes SDK-only for platform events — no signed deliveries, no installer identity disclosure to the app, and no OAuth credentials on install (OAuth requires a webhook to deliver them).
Code
teachfloor apps set oauth
Configure the OAuth block. Presence of this block is the developer's explicit opt-in for install-integrated OAuth — see OAuth.
Code
Prompts (interactive mode) / Flags (non-interactive):
- Type —
--oauthType <value>(alias--type; currently onlyinstall)
Example:
Code
Updates Manifest:
Code
OAuth credentials are delivered inside the app.installed webhook payload. If your app has no webhook block, no tokens will be minted even with oauth set. Run apps set webhook first (or after) to complete the setup.
teachfloor apps remove oauth
Strip the oauth block from the manifest. New installs will no longer receive an access token / refresh token pair on install. In-app SDK permissions still work.
Code
Distribution
teachfloor apps set distribution
Set app distribution type (public or private).
Code
Prompts (interactive mode) / Flags (non-interactive):
- Distribution type —
--distributionType <value>(alias--type; one ofprivateorpublic)
Distribution Types:
- private: Only your organization (default)
- public: Listed in marketplace (requires review)
Example:
Code
Updates Manifest:
Code
Important for Marketplace Submission:
You must set distribution to public before submitting your app for marketplace review. Apps with distribution_type: "private" cannot be submitted to the public marketplace.
Workflow for Public Apps:
Code
Inspection
teachfloor apps show
Print a spec-sheet summary of the current app — manifest metadata, webhook + OAuth config, permissions (with legacy-alias flagging), views, and install state on your own org. The quickest way to see "what does this app look like right now."
Code
Options:
-v, --verbose: Expand widget declarations to showid/name/descriptionper view (default is compactViews (2 widgets, 1 drawer))--json: Emit machine-readable JSON instead of the pretty output (pipe intojq)--no-remote: Skip the permissions-catalog fetch; render local manifest only. Loses legacy-alias flagging and OAuth scope derivation but works fully offline
What it prints:
- Header — app name, version, id, distribution type
- Metadata — description + post-install action (only when set)
- Webhook — URL, subscribed events, note that lifecycle events (
app.installed/app.uninstalled) are always delivered - OAuth — type + "Scopes on install" (the OAuth scopes derived from the manifest's permissions, showing exactly what token an install would mint)
- Permissions — every entry with its purpose; legacy snake_case names show the canonical form with
(legacy alias: course_read)inline - Views — count by surface by default; expanded to per-view detail with
--verbose
Sections only render when the corresponding manifest field is present.
Example:
Code
Scripting with --json:
Code
Diagnostics
teachfloor apps doctor
Run a sequence of checks against your local setup + the current app, printing a pass/warn/fail line for each. Useful when something isn't working and you're not sure whether the problem is auth, the manifest, the app state on the platform, or your webhook/OAuth config.
Code
Options:
-v, --verbose: Print the detail line for every check, not just non-passing ones
What it checks:
Environment
- Authenticated — token present, org selected, and
/whoamistill accepts it (the most common failure mode is a silently-expired token)
Manifest (only when run inside an app folder)
- Inside app folder —
teachfloor-app.jsonexists - Manifest is valid JSON — file parses
- Manifest required fields —
id,name,versionare all set - App exists on the platform — the manifest's
idresolves viaGET /apps/{id}
Metadata (checked when the field is present)
- Description — warns when empty; marketplace listings render blank otherwise
- Distribution type — must be
privateorpublic - post_install_action — shape check:
typeis required; whentype: "external",urlis required and must behttps://
Views (only when ui_extension.views is declared)
- Views — every view has
surface,viewport,component; surface exists in the server catalog; widget-surface views additionally follow server rules (widget id matches^[a-z][a-z0-9_]*$, name ≤ 60 chars, description ≤ 200 chars, ids unique per app)
Permissions (only when declared)
- Permissions — every entry is
{ permission, purpose }; each permission exists in the server catalog; legacy snake_case names (course_read) surface as warnings so you know to migrate to the canonical form (courses:read)
Webhook block (only when declared)
- Webhook URL declared / uses HTTPS / length — server-side rules mirrored locally so
apps uploaddoesn't 422 on preventable issues - Webhook events subscribed — every event in
webhook.eventsis in the server's catalog
OAuth block (only when declared)
- OAuth type is valid — currently only
installis accepted - OAuth prerequisites — the three-prereq gate (
oauthblock +webhookblock + at least one permission) — warns when credentials wouldn't actually be minted on install
Exit code: 0 when there are no errors (warnings still exit 0); 1 when any check failed.
Example:
Code
Command Requirements
Authentication Required
These commands require authentication:
teachfloor apps createteachfloor apps startteachfloor apps upload
Check authentication:
Code
Re-authenticate:
Code
App Folder Required
These commands must be run inside an app folder:
teachfloor apps startteachfloor apps uploadteachfloor apps add viewteachfloor apps remove viewteachfloor apps add settingsteachfloor apps add widgetteachfloor apps remove widgetteachfloor apps grant permissionteachfloor apps revoke permissionteachfloor apps set distribution
Check if in app folder:
Code
Common Workflows
Create and Test App
Code
Update Existing App
Code
Add View to Existing App
Code
Troubleshooting
"Not logged in" error
Solution:
Code
"Not in app folder" error
Check for manifest:
Code
Create new app if needed:
Code
"Version already approved" error
Solution: Increment version in teachfloor-app.json:
Code
Build errors
Clear cache:
Code
Getting Help
Built-in Help
Code
Version Info
Code
Support Channels
- Email: support@teachfloor.com
- Documentation: docs.teachfloor.com
Next Steps
Learn about best practices:
→ Continue to Best Practices