# CLI Reference

Every Senso CLI command and flag, grouped by what you use it for.

This is the full list of `senso` commands. To install the CLI and sign in, start with [Senso CLI](https://docs.senso.ai/docs/senso-cli). Every command also prints its own help with `senso <command> --help`.

## Global flags

These work on every command.

| Flag | What it does |
|------|--------------|
| `--api-key <key>` | Use this key for one command, instead of the stored one |
| `--base-url <url>` | Send requests to a different API address |
| `--output <format>` | `plain` (default), `json` or `table` |
| `--quiet` | Hide the banner and other non-essential output |
| `--no-update-check` | Skip the daily check for a newer version |
| `-v`, `--version` | Print the CLI version |
| `-h`, `--help` | Print help for any command |

Use `--output json` in scripts and agents. It prints the API's response as JSON and nothing else.

## Environment variables

| Variable | What it does |
|----------|--------------|
| `SENSO_API_KEY` | The key to use, instead of the stored one |
| `SENSO_BASE_URL` | A different API address, like `--base-url` |
| `SENSO_CONFIG_DIR` | Where the CLI stores its config, instead of the default folder |
| `SENSO_DEBUG=1` | Print every request and its status, with the key hidden |
| `SENSO_GAP_SIGNALS=off` | Keep searches out of the gap report, like `--no-gap-signals` |
| `SENSO_NO_UPDATE_CHECK=1` | Skip the daily version check, like `--no-update-check` |

The CLI uses the key from `--api-key` first, then `SENSO_API_KEY`, then the stored config. `senso whoami` shows which one it used.

## Exit codes

| Code | Meaning |
|------|---------|
| `0` | The command did what you asked |
| `1` | Senso refused the request. The message says why |
| `2` | The command was wrong: an unknown command, a missing argument or a bad flag |
| `3` | No key, or the key was refused |
| `4` | What you asked for does not exist |
| `5` | The CLI could not reach Senso |

## Authentication

Sign in, sign out, and check which organization you are using.

| Command | What it does |
|---------|--------------|
| `senso login` | Sign this device in. Opens an approval page in your browser; an admin approves, and the CLI stores the key it gets. Does nothing if your stored key still works. |
| `senso logout` | Forget the stored key. A key that `senso login` created is revoked first; a key you supplied is only forgotten. |
| `senso whoami` | Show the organization you are signed in to, the key prefix, and where the key came from. |

| Command | Flag | What it does |
|---------|------|--------------|
| `login` | `--complete` | Finish a login started earlier: wait for the browser approval and store the key. |
| `login` | `--interactive` | Paste an existing API key at a prompt instead. Needs a terminal. |
| `login` | `--device-name <name>` | How this device is labeled on the approval page. |
| `login` | `--no-browser` | Do not try to open the approval page automatically. |

## Organization

Your organization's profile, credits and industry.

### senso org

| Command | What it does |
|---------|--------------|
| `senso org get` | Show the organization profile: name, slug, tier, websites, locations, models and schedule. |
| `senso org update` | Update organization details. Only the fields you pass change, but `websites` and `locations` replace their whole list. |
| `senso org set-industry <industryId>` | Set the industry your organization belongs to, from `senso industries list`. Replaces any previous choice. |
| `senso org set-runs` | Turn every scheduled prompt run and content-generation run on or off. |

| Command | Flag | What it does |
|---------|------|--------------|
| `org update` | `--data <json>` | JSON with any of `name`, `slug`, `logo_url`, `websites` (list of `{"url"}`), `locations` (list of `{"country_code", "region_name"}`). |
| `org set-runs` | `--enabled <bool>` | Set to true or false |

### senso credits

| Command | What it does |
|---------|--------------|
| `senso credits balance` | Show the credits available and any spend limit. |
| `senso credits history` | Show credit spend per day over a trailing window, oldest first, ending today. |

| Command | Flag | What it does |
|---------|------|--------------|
| `credits history` | `--days <n>` | Length of the trailing window in days, 1-365 (default 30) |

### senso industries

| Command | What it does |
|---------|--------------|
| `senso industries list` | List the public industry catalog, with each industry's prompt, model and location counts. |
| `senso industries answers <industry>` | Read the newest answer for each of your industry's prompts, per model and location, and whether it named your brand. |
| `senso industries prompts <industry>` | List the prompts an industry runs. Their IDs are what `import-prompts` and `generate industry-draft` take. |
| `senso industries brands <industry>` | Rank the brands named in an industry's answers over a window, by mentions. |
| `senso industries brand <industry> <brandName>` | Everything about one brand in an industry, matched by name. |
| `senso industries brand-by-id <industry> <brandId>` | The same as `brand`, looked up by the `brand_id` it returns. |
| `senso industries domain <industry> <domain>` | How often a domain, or a full URL with `--url`, was cited in an industry's answers. |
| `senso industries import-prompts <industry>` | Copy prompts from your own industry into your organization, with their run history. Prompts you already have are skipped. This activates the organization and starts its scheduled runs. |

| Command | Flag | What it does |
|---------|------|--------------|
| `industries list` | `--search <q>` | Case-insensitive substring match against name or slug |
| `industries list` | `--limit <n>` | Page size, 1-100 (default 50) |
| `industries list` | `--offset <n>` | Number of industries to skip (default 0) |
| `industries list` | `--sort <order>` | Sort order: name_asc, name_desc, created_asc, created_desc (default name_asc) |
| `industries list` | `--live` | Only industries actively running — at least one model enabled and one active prompt |
| `industries answers` | `--mentioned <bool>` | Only answers that did (true) or did not (false) name your brand |
| `industries answers` | `--models <list>` | Comma-separated model filter: gpt-4.1, chatgpt, perplexity, aioverview, gemini, linkup, claude-sonnet-4-6, grok |
| `industries answers` | `--location <code>` | One location, e.g. US or US/California (default every location) |
| `industries answers` | `--prompt-ids <list>` | Comma-separated prompt ids to restrict to |
| `industries answers` | `--since <date>` | Only answers collected on or after this day, YYYY-MM-DD |
| `industries answers` | `--include-empty` | Include answers where the model returned nothing |
| `industries answers` | `--limit <n>` | Page size, 1-100 (default 25) |
| `industries answers` | `--offset <n>` | Number of answers to skip (default 0) |
| `industries prompts` | `--imported <bool>` | Keep only the prompts you already have (true) or do not have yet (false). Omit for all. |
| `industries prompts` | `--limit <n>` | Page size, 1-100 (default 50) |
| `industries prompts` | `--offset <n>` | Number of prompts to skip (default 0) |
| `industries brands` | `--from <date>` | Start of the window, YYYY-MM-DD (default 30 days ago) |
| `industries brands` | `--to <date>` | End of the window, YYYY-MM-DD (default today) |
| `industries brands` | `--models <list>` | Comma-separated model filter |
| `industries brands` | `--location <code>` | One location, as the industry's runs record it: a country code such as US, or a country/region pair such as US/California |
| `industries brands` | `--limit <n>` | Page size, 1-100 (default 100) |
| `industries brands` | `--offset <n>` | Number of brands to skip (default 0) |
| `industries brands` | `--no-canonicalize` | Do not merge spelling variants — raw per-spelling rows |
| `industries brands` | `--rollup <mode>` | Set to `parent` to fold sub-brands into their parent company |
| `industries brands` | `--entity-type <list>` | Comma-separated types to keep: brand, regulator, publisher, government, generic_term, product_model, forum_social |
| `industries brand` | `--from <date>` | Start of the window, YYYY-MM-DD (default 30 days ago) |
| `industries brand` | `--to <date>` | End of the window, YYYY-MM-DD (default today) |
| `industries brand` | `--models <list>` | Comma-separated model filter |
| `industries brand` | `--location <code>` | One location, as the industry's runs record it: a country code such as US, or a country/region pair such as US/California |
| `industries brand-by-id` | `--from <date>` | Start of the window, YYYY-MM-DD (default 30 days ago) |
| `industries brand-by-id` | `--to <date>` | End of the window, YYYY-MM-DD (default today) |
| `industries brand-by-id` | `--models <list>` | Comma-separated model filter |
| `industries brand-by-id` | `--location <code>` | One location, as the industry's runs record it: a country code such as US, or a country/region pair such as US/California |
| `industries domain` | `--from <date>` | Start of the window, YYYY-MM-DD (default 30 days ago) |
| `industries domain` | `--to <date>` | End of the window, YYYY-MM-DD (default today) |
| `industries domain` | `--models <list>` | Comma-separated model filter |
| `industries domain` | `--location <code>` | One location, as the industry's runs record it: a country code such as US, or a country/region pair such as US/California |
| `industries domain` | `--url <url>` | Look up this full URL instead of the bare domain |
| `industries import-prompts` | `--prompt-ids <ids>` | Comma-separated industry prompt ids, 1-100, no duplicates (from `senso industries prompts`) |

### senso history-imports

| Command | What it does |
|---------|--------------|
| `senso history-imports list` | List the 50 most recent history-import jobs, newest first. |
| `senso history-imports get <importId>` | Show one history-import job, by the ID `industries import-prompts` returns. |

### senso run-config

| Command | What it does |
|---------|--------------|
| `senso run-config models` | Show the AI models prompts are run against. |
| `senso run-config set-models` | Replace the AI models prompts are run against. |
| `senso run-config model-options` | List the model names `set-models` accepts. |
| `senso run-config scheduler-models` | Show the provider and model pairs the scheduler runs. |
| `senso run-config set-scheduler-models` | Replace the scheduler's provider and model pairs. |
| `senso run-config schedule` | Show the days of the week prompts run (0 is Sunday). |
| `senso run-config set-schedule` | Set the days of the week prompts run. |

| Command | Flag | What it does |
|---------|------|--------------|
| `run-config set-models` | `--data <json>` | JSON `{"models": [...]}`, at least one name from `run-config model-options`. |
| `run-config set-scheduler-models` | `--data <json>` | JSON `{"models": [...]}` of `provider/model` pairs. |
| `run-config set-schedule` | `--data <json>` | JSON `{"schedule": [...]}`, days 0 (Sunday) to 6 (Saturday). |

## Members and access

People, roles and API keys.

### senso members

| Command | What it does |
|---------|--------------|
| `senso members list` | List organization members, with their names, emails and roles. |

| Command | Flag | What it does |
|---------|------|--------------|
| `members list` | `--limit <n>` | Maximum members to return (max: 1000) |
| `members list` | `--offset <n>` | Number of members to skip (for pagination) |
| `members list` | `--search <query>` | Filter by name or email |
| `members list` | `--sort <order>` | Sort order: name_asc, name_desc, email_asc, email_desc, created_asc, created_desc |

### senso users

| Command | What it does |
|---------|--------------|
| `senso users list` | List the users in the organization, with their user IDs and roles. |
| `senso users add` | Add an existing Senso user to the organization by user ID and role ID. |
| `senso users get <userId>` | Show one user's role and membership. |
| `senso users update <userId>` | Change a user's role in the organization. |
| `senso users remove <userId>` | Remove a user from the organization. Their Senso account is not deleted. |
| `senso users set-current <userId>` | Make this organization the user's active organization. |
| `senso users invite` | Invite someone new by email. Creates their account and adds them with the role you choose. |
| `senso users invite-existing` | Add an existing Senso user to the organization by email. |

| Command | Flag | What it does |
|---------|------|--------------|
| `users list` | `--limit <n>` | Maximum number of users to return |
| `users list` | `--offset <n>` | Number of users to skip (for pagination) |
| `users add` | `--data <json>` | JSON with `user_id`, `role_id` and optional `is_current`. |
| `users update` | `--data <json>` | JSON with `role_id` (required) and optional `is_current`. |
| `users invite` | `--email <email>` | User's email address |
| `users invite` | `--given-name <name>` | First name |
| `users invite` | `--family-name <name>` | Last name |
| `users invite` | `--role-id <uuid>` | Role to assign — resolve with `senso roles list` |
| `users invite` | `--is-current` | Make this org the new user's current org |
| `users invite-existing` | `--email <email>` | Email of an existing Senso user |
| `users invite-existing` | `--role-id <uuid>` | Role to assign — resolve with `senso roles list` |
| `users invite-existing` | `--is-current` | Make this org the user's current org |

### senso roles

| Command | What it does |
|---------|--------------|
| `senso roles list` | List every role in the organization: the built-in admin, collaborator and viewer roles, and any custom ones. |

### senso permissions

| Command | What it does |
|---------|--------------|
| `senso permissions list` | List every permission key, with its name, description and category. |

### senso api-keys

| Command | What it does |
|---------|--------------|
| `senso api-keys list` | List the organization's API keys, with name, expiry and whether each is restricted. |
| `senso api-keys get <keyId>` | Show one API key's details. The key itself is never shown again after it is created. |
| `senso api-keys kb-permissions-get <keyId>` | Show the knowledge base restrictions on a key. An empty list means full access. |

| Command | Flag | What it does |
|---------|------|--------------|
| `api-keys list` | `--limit <n>` | Maximum number of keys to return |
| `api-keys list` | `--offset <n>` | Number of keys to skip (for pagination) |

## Knowledge base

Add, organize and search the documents Senso answers from.

### senso kb

| Command | What it does |
|---------|--------------|
| `senso kb root` | Show the knowledge base's root folder. |
| `senso kb stats` | Count the documents and folders in the knowledge base. |
| `senso kb my-files` | List the files and folders at the top of the knowledge base. |
| `senso kb find` | Find files and folders by name. |
| `senso kb sync-status` | Show whether recent moves and deletes are still being applied. Not an ingestion signal: use `kb get` for that. |
| `senso kb get <id>` | Show a file or folder. For a document, `content.processing_status` says whether it is ready to search. |
| `senso kb children <id>` | List what is inside a folder. |
| `senso kb ancestors <id>` | List the folders above a file or folder, from the root down. |
| `senso kb get-content <id>` | Show a document's text and metadata, or an earlier version with `--rev`. |
| `senso kb download-url <id>` | Get a temporary download link for an uploaded file, or an earlier version with `--rev`. |
| `senso kb create-folder` | Create a folder, at the top level or inside another folder. |
| `senso kb rename <id>` | Rename a file or folder. |
| `senso kb move <id>` | Move a file or folder into another folder. |
| `senso kb delete <id>` | Delete a file or folder. |
| `senso kb bulk-delete <nodeIds...>` | Delete up to 100 files and folders at once. Folders take everything inside them. If any one cannot be deleted, none are. |
| `senso kb create-raw` | Add a document from text or markdown. Senso tags it automatically once it is processed. |
| `senso kb update-raw <id>` | Replace a text document's title and text, as a new version. |
| `senso kb patch-raw <id>` | Update a text document's text, and optionally its title and summary, as a new version. |
| `senso kb upload <files...>` | Upload up to 10 files. Each is processed in the background; check with `kb get` before searching it. |
| `senso kb update-file <id> <file>` | Replace an uploaded file with a new version. |
| `senso kb tags list <id>` | List the tags on a file or folder. |
| `senso kb tags set <id>` | Replace all the tags on a file or folder. Names that do not exist yet are created. |
| `senso kb tags add <id>` | Add one tag to a file or folder. A new name is created. |
| `senso kb tags remove <id>` | Remove one tag from a file or folder. |
| `senso kb permissions list <id>` | List who has access to a file or folder, with each grant's ID. |
| `senso kb permissions add <id>` | Give a user or group viewer or editor access to a file or folder. |
| `senso kb permissions update <id> <permissionId>` | Change a grant's role to viewer or editor. |
| `senso kb permissions remove <id> <permissionId>` | Remove a grant. |

| Command | Flag | What it does |
|---------|------|--------------|
| `kb my-files` | `--limit <n>` | Items per page, 1-50 (the API caps higher values at 50) (default 50) |
| `kb my-files` | `--offset <n>` | Pagination offset (default 0) |
| `kb my-files` | `--type <type>` | Only nodes of this type: folder, content |
| `kb my-files` | `--status <status>` | Only documents in this ingestion state: pending, processing, complete, failed. Ignored with --type folder |
| `kb my-files` | `--role <role>` | Only nodes where the caller holds this role: editor, viewer. Ignored for org-admin keys, which already reach everything |
| `kb my-files` | `--sort-by <field>` | Sort by: name, updated_at, created_at, type, status, role |
| `kb my-files` | `--sort-order <dir>` | Sort direction: asc, desc |
| `kb my-files` | `--tag-ids <ids>` | Comma-separated tag IDs; only nodes carrying at least one of them |
| `kb find` | `--query <q>` | Name search query |
| `kb find` | `--limit <n>` | Items per page, 1-50 (the API caps higher values at 50) (default 20) |
| `kb find` | `--offset <n>` | Pagination offset (default 0) |
| `kb find` | `--type <type>` | Only nodes of this type: folder, content |
| `kb find` | `--status <status>` | Only documents in this ingestion state: pending, processing, complete, failed. Ignored with --type folder |
| `kb find` | `--role <role>` | Only nodes where the caller holds this role: editor, viewer. Ignored for org-admin keys, which already reach everything |
| `kb find` | `--sort-by <field>` | Sort by: name, updated_at, created_at, type, status, role |
| `kb find` | `--sort-order <dir>` | Sort direction: asc, desc |
| `kb find` | `--tag-ids <ids>` | Comma-separated tag IDs; only nodes carrying at least one of them |
| `kb children` | `--limit <n>` | Items per page, 1-50 (the API caps higher values at 50) (default 50) |
| `kb children` | `--offset <n>` | Pagination offset (default 0) |
| `kb children` | `--type <type>` | Only nodes of this type: folder, content |
| `kb children` | `--status <status>` | Only documents in this ingestion state: pending, processing, complete, failed. Ignored with --type folder |
| `kb children` | `--role <role>` | Only nodes where the caller holds this role: editor, viewer. Ignored for org-admin keys, which already reach everything |
| `kb children` | `--sort-by <field>` | Sort by: name, updated_at, created_at, type, status, role |
| `kb children` | `--sort-order <dir>` | Sort direction: asc, desc |
| `kb children` | `--tag-ids <ids>` | Comma-separated tag IDs; only nodes carrying at least one of them |
| `kb get-content` | `--rev <n>` | Retrieve a specific stored version of this content, by version number |
| `kb download-url` | `--rev <n>` | Download a specific stored version of this file, by version number |
| `kb create-folder` | `--name <name>` | Folder name |
| `kb create-folder` | `--parent-id <id>` | Parent folder node ID (omit to create at root) |
| `kb rename` | `--name <name>` | New name |
| `kb move` | `--parent-id <parentId>` | Target parent folder node ID |
| `kb create-raw` | `--data <json>` | JSON with `text` (required), `title`, `summary`, `kb_folder_node_id`. |
| `kb update-raw` | `--data <json>` | JSON with `title` and `text` (both required), `summary`, `tag_ids`. `tag_ids` replaces all tags. |
| `kb patch-raw` | `--data <json>` | JSON with `text`, `title`, `summary`, `tag_ids`. `tag_ids` replaces all tags. |
| `kb upload` | `--folder-id <id>` | Parent folder node ID to place files in (omit for root) |
| `kb tags set` | `--names <list>` | Comma-separated tag names (created if missing) |
| `kb tags set` | `--ids <list>` | Comma-separated existing tag UUIDs |
| `kb tags add` | `--name <name>` | Tag name (created if missing) |
| `kb tags add` | `--id <tagId>` | Existing tag UUID |
| `kb tags remove` | `--name <name>` | Tag name to detach |
| `kb tags remove` | `--id <tagId>` | Existing tag UUID to detach |
| `kb permissions add` | `--grantee-type <type>` | Who the grant is for: user, group |
| `kb permissions add` | `--grantee-id <id>` | The user ID or group ID to grant access to |
| `kb permissions add` | `--role <role>` | Access level to grant: viewer, editor |
| `kb permissions update` | `--role <role>` | The new role: viewer, editor |

### senso ingest

| Command | What it does |
|---------|--------------|
| `senso ingest upload <files...>` | Upload up to 10 files. The same as `kb upload`. |
| `senso ingest reprocess <nodeId> <file>` | Replace a document's file with a new one and process it again. |

| Command | Flag | What it does |
|---------|------|--------------|
| `ingest upload` | `--folder-id <id>` | Destination folder ID (skip interactive prompt) |

### senso website-import

| Command | What it does |
|---------|--------------|
| `senso website-import start` | Import pages from your organization's website into the knowledge base, and wait until it finishes. The site is the one on file in `senso org get`. |
| `senso website-import status` | Show the import in progress and the last one that finished. |

| Command | Flag | What it does |
|---------|------|--------------|
| `website-import start` | `--no-wait` | Return the accepted run immediately instead of polling until the import finishes. |

### senso search

| Command | What it does |
|---------|--------------|
| `senso search <query>` | Ask a question. Returns an answer written from your knowledge base and the passages it used. |
| `senso search context <query>` | Return the matching passages only, with no answer, to feed into your own model. |
| `senso search content <query>` | Return the matching documents only, one row each, with the IDs to read them or narrow a later search. |
| `senso search full <query>` | The same as `senso search`. |
| `senso search stream <query>` | Stream the answer as it is written, then the passages it used. |

| Command | Flag | What it does |
|---------|------|--------------|
| `search` | `--max-results <n>` | Maximum number of results (max: 20) (default 5) |
| `search` | `--content-ids <ids...>` | Restrict search to specific content item IDs (space-separated UUIDs) |
| `search` | `--require-scoped-ids` | Only return results from the specified --content-ids (omit to allow fallback to all content) |
| `search` | `--no-gap-signals` | Keep this search out of the organization's gap report (sends X-Senso-Signals: off). Use it for probes, tests and monitors — a real question that finds nothing should be left eligible. The search still runs, costs credits and is recorded. Set SENSO_GAP_SIGNALS=off to do this for every search. |
| `search context` | `--max-results <n>` | Maximum results (max: 20) (default 5) |
| `search context` | `--content-ids <ids...>` | Restrict search to specific content item IDs (space-separated UUIDs) |
| `search context` | `--require-scoped-ids` | Only return results from the specified --content-ids |
| `search context` | `--no-gap-signals` | Keep this search out of the organization's gap report (sends X-Senso-Signals: off). Use it for probes, tests and monitors — a real question that finds nothing should be left eligible. The search still runs, costs credits and is recorded. Set SENSO_GAP_SIGNALS=off to do this for every search. |
| `search content` | `--max-results <n>` | Maximum results (max: 20) (default 5) |
| `search content` | `--content-ids <ids...>` | Restrict search to specific content item IDs (space-separated UUIDs) |
| `search content` | `--require-scoped-ids` | Only return results from the specified --content-ids |
| `search content` | `--no-gap-signals` | Keep this search out of the organization's gap report (sends X-Senso-Signals: off). Use it for probes, tests and monitors — a real question that finds nothing should be left eligible. The search still runs, costs credits and is recorded. Set SENSO_GAP_SIGNALS=off to do this for every search. |
| `search full` | `--max-results <n>` | Maximum results (max: 20) (default 5) |
| `search full` | `--content-ids <ids...>` | Restrict search to specific content item IDs (space-separated UUIDs) |
| `search full` | `--require-scoped-ids` | Only return results from the specified --content-ids |
| `search full` | `--no-gap-signals` | Keep this search out of the organization's gap report (sends X-Senso-Signals: off). Use it for probes, tests and monitors — a real question that finds nothing should be left eligible. The search still runs, costs credits and is recorded. Set SENSO_GAP_SIGNALS=off to do this for every search. |
| `search stream` | `--max-results <n>` | Maximum results (max: 20) (default 5) |
| `search stream` | `--content-ids <ids...>` | Restrict search to specific content item IDs (space-separated UUIDs) |
| `search stream` | `--require-scoped-ids` | Only return results from the specified --content-ids |
| `search stream` | `--no-gap-signals` | Keep this search out of the organization's gap report (sends X-Senso-Signals: off). Use it for probes, tests and monitors — a real question that finds nothing should be left eligible. The search still runs, costs credits and is recorded. Set SENSO_GAP_SIGNALS=off to do this for every search. |

### senso tags

| Command | What it does |
|---------|--------------|
| `senso tags list` | List every tag in the organization. |
| `senso tags create` | Create a tag. Names are unique, ignoring case. |
| `senso tags get <id>` | Show a tag and how many prompts and documents use it. |
| `senso tags update <id>` | Rename a tag. Everything already tagged keeps it. |
| `senso tags delete <id>` | Delete a tag and remove it from everything it was on. |

| Command | Flag | What it does |
|---------|------|--------------|
| `tags list` | `--counts` | Include prompt/content usage counts |
| `tags create` | `--name <name>` | Tag name |
| `tags update` | `--name <name>` | New tag name |

## Brand and context

What every piece of generated content inherits.

### senso brand-kit

| Command | What it does |
|---------|--------------|
| `senso brand-kit get` | Show the brand kit: name, domain, description, voice and tone, author persona and writing rules. |
| `senso brand-kit set` | Replace the whole brand kit. Any field you leave out is removed. |
| `senso brand-kit patch` | Change some brand kit fields and keep the rest. `global_writing_rules` is replaced as a whole. |

| Command | Flag | What it does |
|---------|------|--------------|
| `brand-kit set` | `--data <json>` | JSON `{"guidelines": {...}}` with any of `brand_name`, `brand_domain`, `brand_description`, `voice_and_tone`, `author_persona`, `global_writing_rules`. |
| `brand-kit patch` | `--data <json>` | JSON `{"guidelines": {...}}` with at least one of the brand kit fields. |

### senso content-types

| Command | What it does |
|---------|--------------|
| `senso content-types list` | List the organization's content types. |
| `senso content-types create` | Create a content type from a name and a markdown template. |
| `senso content-types get <id>` | Show a content type and its configuration. |
| `senso content-types update <id>` | Replace a content type's name and configuration. |
| `senso content-types patch <id>` | Change some of a content type's fields and keep the rest. |
| `senso content-types delete <id>` | Delete a content type. |

| Command | Flag | What it does |
|---------|------|--------------|
| `content-types list` | `--limit <n>` | Maximum number of content types to return (default 50) |
| `content-types list` | `--offset <n>` | Number of items to skip (for pagination) |
| `content-types create` | `--data <json>` | JSON with `name` and `config`: `template` (markdown), `cta_text`, `cta_destination`, `writing_rules`. |
| `content-types update` | `--data <json>` | JSON with `name` and `config`, both required. |
| `content-types patch` | `--data <json>` | JSON with the fields to change. |

### senso product-lines

| Command | What it does |
|---------|--------------|
| `senso product-lines list` | List the organization's product lines. |
| `senso product-lines create` | Create a product line, with any details you want to attach. |
| `senso product-lines get <id>` | Show a product line. |
| `senso product-lines update <id>` | Replace a product line's name and details. |
| `senso product-lines patch <id>` | Change some of a product line's fields and keep the rest. |
| `senso product-lines delete <id>` | Delete a product line. |

| Command | Flag | What it does |
|---------|------|--------------|
| `product-lines list` | `--limit <n>` | Maximum items to return (default 50) |
| `product-lines list` | `--offset <n>` | Number of items to skip (for pagination) |
| `product-lines create` | `--data <json>` | JSON with `name` and `details` (any object). |
| `product-lines update` | `--data <json>` | JSON with `name` and `details`, both required. |
| `product-lines patch` | `--data <json>` | JSON with the fields to change. |

## Prompts and tracking

The questions Senso asks AI models, and who and what to watch in the answers.

### senso prompts

| Command | What it does |
|---------|--------------|
| `senso prompts list` | List the organization's prompts: the questions Senso asks AI models on your behalf. |
| `senso prompts create` | Create a prompt, with a funnel stage: awareness, consideration, evaluation or decision. |
| `senso prompts get <promptId>` | Show a prompt and its full run history. |
| `senso prompts delete <promptId>` | Delete a prompt and its run history. |
| `senso prompts tags list <promptId>` | List the tags on a prompt. |
| `senso prompts tags set <promptId>` | Replace all the tags on a prompt. Names that do not exist yet are created. |
| `senso prompts tags add <promptId>` | Add one tag to a prompt. A new name is created. |
| `senso prompts tags remove <promptId>` | Remove one tag from a prompt. |

| Command | Flag | What it does |
|---------|------|--------------|
| `prompts list` | `--limit <n>` | Maximum prompts to return (max: 100) |
| `prompts list` | `--offset <n>` | Number of prompts to skip (for pagination) |
| `prompts list` | `--search <query>` | Filter prompts by question text |
| `prompts list` | `--sort <order>` | Sort order: created_desc, created_asc, text_asc, text_desc, type_asc, type_desc |
| `prompts create` | `--data <json>` | JSON with `question_text` and `type`. |
| `prompts tags set` | `--names <list>` | Comma-separated tag names (created if missing) |
| `prompts tags set` | `--ids <list>` | Comma-separated existing tag UUIDs |
| `prompts tags add` | `--name <name>` | Tag name (created if missing) |
| `prompts tags add` | `--id <tagId>` | Existing tag UUID |
| `prompts tags remove` | `--name <name>` | Tag name to detach |
| `prompts tags remove` | `--id <tagId>` | Existing tag UUID to detach |

### senso questions

| Command | What it does |
|---------|--------------|
| `senso questions list` | List the organization's questions. |
| `senso questions create` | Create a question, with a funnel stage and optional tags. |
| `senso questions patch <questionId>` | Change a question's funnel stage or tags. |
| `senso questions delete <questionId>` | Delete a question. |

| Command | Flag | What it does |
|---------|------|--------------|
| `questions list` | `--type <type>` | Filter by question type: organization, network (default organization) |
| `questions create` | `--data <json>` | JSON with `question_text`, `type` and `tag_ids`. |
| `questions patch` | `--data <json>` | JSON with `type`, `tag_ids`, or both. |

### senso competitors

| Command | What it does |
|---------|--------------|
| `senso competitors list` | List the competitors you track. |
| `senso competitors add` | Track one competitor. |
| `senso competitors batch-add` | Track up to 50 competitors at once, for example the ones `competitors suggest` returns. |
| `senso competitors suggest` | Suggest competitors, from your website and recent prompt runs. |
| `senso competitors update <competitorId>` | Change a tracked competitor. |
| `senso competitors delete <competitorId>` | Stop tracking a competitor. |

| Command | Flag | What it does |
|---------|------|--------------|
| `competitors add` | `--name <name>` | Competitor brand name |
| `competitors add` | `--url <url>` | Competitor website URL |
| `competitors batch-add` | `--data <json>` | JSON `{"items": [...]}`, each with `name`, `url`, `source`, and optionally `rationale` and `confidence`. |
| `competitors update` | `--name <name>` | Competitor brand name |
| `competitors update` | `--url <url>` | Competitor website URL |

### senso tracked-sources

| Command | What it does |
|---------|--------------|
| `senso tracked-sources list` | List the rules that classify cited URLs as Owned, Tracked or External. |
| `senso tracked-sources add` | Add a rule. New rules start active. A `domain` rule matches the whole registrable domain, so `blog.example.com` is stored as `example.com`. |
| `senso tracked-sources update <sourceId>` | Replace a rule. Pattern, match type and tier are required. |
| `senso tracked-sources delete <sourceId>` | Remove a rule. |

| Command | Flag | What it does |
|---------|------|--------------|
| `tracked-sources add` | `--pattern <pattern>` | Value to match cited URLs against, interpreted per --match-type |
| `tracked-sources add` | `--match-type <type>` | Match strategy: domain, host, path_prefix, exact_url |
| `tracked-sources add` | `--tier <tier>` | Classification tier: primary (Owned), tracked, secondary (External) |
| `tracked-sources add` | `--category <category>` | Optional sub-category (only meaningful for the 'tracked' tier): affiliated_domain, published_content, social, press |
| `tracked-sources add` | `--label <label>` | Optional human-readable label |
| `tracked-sources add` | `--priority <n>` | Optional ordering priority (integer) |
| `tracked-sources update` | `--pattern <pattern>` | Value to match cited URLs against, interpreted per --match-type |
| `tracked-sources update` | `--match-type <type>` | Match strategy: domain, host, path_prefix, exact_url |
| `tracked-sources update` | `--tier <tier>` | Classification tier: primary (Owned), tracked, secondary (External) |
| `tracked-sources update` | `--category <category>` | Optional sub-category (only meaningful for the 'tracked' tier): affiliated_domain, published_content, social, press |
| `tracked-sources update` | `--label <label>` | Optional human-readable label |
| `tracked-sources update` | `--priority <n>` | Optional ordering priority (integer) |
| `tracked-sources update` | `--active` | Mark the rule active |
| `tracked-sources update` | `--no-active` | Mark the rule inactive |

## Evaluate

Check text against your sources, find gaps, and read how AI answers about you.

### senso evals

| Command | What it does |
|---------|--------------|
| `senso evals evaluators` | List the evaluators you can run, with their current versions. |
| `senso evals text` | Check text you supply, against your knowledge base (`kb_accuracy`) or your brand kit (`brand_alignment`). |
| `senso evals runs` | List eval runs, newest first, with each score and its claim counts. |
| `senso evals get <runId>` | Show one eval run in full: every claim, its verdict and the evidence. |
| `senso evals claims` | List the individual claims evaluators have judged, across runs or for one. |
| `senso evals content <contentId>` | Check a saved text document or generated article. Uploaded files cannot be checked. |

| Command | Flag | What it does |
|---------|------|--------------|
| `evals text` | `--evaluator <key>` | Which check to run: kb_accuracy, brand_alignment (default kb_accuracy) |
| `evals text` | `--evaluator-version <v>` | Pin an evaluator version (see `senso evals evaluators`) |
| `evals text` | `--judge-model <model>` | Override the model that judges the text |
| `evals text` | `--label <text>` | Free-form tag stored on the run, for finding it later |
| `evals text` | `--idempotency-key <key>` | Makes the trigger safe to retry — the same key returns the original run |
| `evals text` | `--wait` | Poll until the run finishes instead of returning a handle straight away |
| `evals text` | `--text <text>` | The text to judge |
| `evals text` | `--text-file <path>` | Read the text to judge from a file |
| `evals text` | `--title <title>` | Optional title, stored with the run's subject (max 255 chars) |
| `evals runs` | `--from <instant>` | Only items created at or after this RFC 3339 instant, e.g. 2026-09-01T00:00:00Z |
| `evals runs` | `--to <instant>` | Only items created before this RFC 3339 instant (exclusive) |
| `evals runs` | `--evaluator <key>` | Filter by evaluator key (see `senso evals evaluators`) |
| `evals runs` | `--subject-type <type>` | Filter by subject type, e.g. inline or content |
| `evals runs` | `--limit <n>` | Page size, 1-100 (default 25) |
| `evals runs` | `--offset <n>` | Number of items to skip (default 0) |
| `evals claims` | `--from <instant>` | Only items created at or after this RFC 3339 instant, e.g. 2026-09-01T00:00:00Z |
| `evals claims` | `--to <instant>` | Only items created before this RFC 3339 instant (exclusive) |
| `evals claims` | `--evaluator <key>` | Filter by evaluator key (see `senso evals evaluators`) |
| `evals claims` | `--subject-type <type>` | Filter by subject type, e.g. inline or content |
| `evals claims` | `--limit <n>` | Page size, 1-100 (default 25) |
| `evals claims` | `--offset <n>` | Number of items to skip (default 0) |
| `evals claims` | `--run-id <id>` | Only claims from this eval run |
| `evals content` | `--evaluator <key>` | Which check to run: kb_accuracy, brand_alignment (default kb_accuracy) |
| `evals content` | `--evaluator-version <v>` | Pin an evaluator version (see `senso evals evaluators`) |
| `evals content` | `--judge-model <model>` | Override the model that judges the text |
| `evals content` | `--label <text>` | Free-form tag stored on the run, for finding it later |
| `evals content` | `--idempotency-key <key>` | Makes the trigger safe to retry — the same key returns the original run |
| `evals content` | `--wait` | Poll until the run finishes instead of returning a handle straight away |

### senso gaps

| Command | What it does |
|---------|--------------|
| `senso gaps list` | List gaps, most severe first. By default only open, reopened and addressed gaps. |
| `senso gaps get <gapId>` | Show a gap in full: every sighting, every decision recorded against it, and the evidence. |
| `senso gaps resolve <gapId>` | Record what was done about a gap. The type you record decides its new status. |
| `senso gaps answer <gapId>` | Record that you wrote content to fix a gap. The gap becomes addressed. |
| `senso gaps dismiss <gapId>` | Close a gap that does not need fixing. |
| `senso gaps undo <gapId> <resolutionId>` | Take back one recorded decision. The gap's status is worked out again from the rest. |

| Command | Flag | What it does |
|---------|------|--------------|
| `gaps list` | `--status <status>` | Filter by status, repeatable: weak, open, reopened, addressed, resolved, dismissed, dormant, or all (default open, reopened, addressed) |
| `gaps list` | `--problem <problem>` | Filter by problem, repeatable: conflict, not_found, no_source, flagged |
| `gaps list` | `--origin <origin>` | Filter by origin, repeatable: claim, unanswered_question, documents_didnt_answer, flagged_answer, api_unanswered_question. api_unanswered_question is a search through the API or CLI that found nothing |
| `gaps list` | `--surface <surface>` | Filter by where it was seen, repeatable: search_turn, content, question_run, api_search |
| `gaps list` | `--kind <kind>` | Filter by kind, repeatable: missing, conflict, kb_conflict, flagged |
| `gaps list` | `--tag <tagId>` | Filter by topic tag id, repeatable (see `senso tags list`) |
| `gaps list` | `--search <text>` | Only gaps whose text contains this |
| `gaps list` | `--sort <order>` | severity, recent, demand (default severity) |
| `gaps list` | `--limit <n>` | Page size, 1-100 (default 50) |
| `gaps list` | `--offset <n>` | Number of gaps to skip (default 0) |
| `gaps resolve` | `--type <type>` | One of: answered, content_added, content_updated, ruled_kb_correct, ruled_claim_correct, ruled_document, dismissed, not_relevant, we_dont_do_this, source_irrelevant |
| `gaps resolve` | `--produced-content-id <id>` | The content that was written — required for answered, content_added and content_updated |
| `gaps resolve` | `--authority-content-id <id>` | The document the decision is about — required for ruled_claim_correct, ruled_document and source_irrelevant |
| `gaps resolve` | `--ruling-side <side>` | Which side a ruling found correct: kb, claim, document |
| `gaps resolve` | `--notes <text>` | Why, in a sentence — shown on the gap's timeline |
| `gaps answer` | `--content-id <id>` | The content that answers it: the `id` from `senso kb create-raw`, or a `content_id` from `senso kb get` |
| `gaps answer` | `--updated` | An existing document was improved, rather than a new one written |
| `gaps answer` | `--notes <text>` | What was written, in a sentence |
| `gaps dismiss` | `--notes <text>` | Why it does not matter, in a sentence |

### senso analytics

| Command | What it does |
|---------|--------------|
| `senso analytics summary` | Every headline metric for a window, with the previous window and the change between them. |
| `senso analytics mentions` | Mentions, share of voice (your mentions ÷ mentions of every brand), rank and sentiment over time. |
| `senso analytics citations` | Citation Rate for each tier (÷ D, answers with at least one citation) and Citation Share for each tier (÷ S, citation instances), over time. |
| `senso analytics domains` | Every cited domain, ranked, with its Citation Coverage (÷ D) and Citation Share (÷ S). |
| `senso analytics pages` | Every cited URL, with its Citation Coverage (÷ D), Citation Share (÷ S) and the prompts behind it. |
| `senso analytics prompts` | Performance per prompt. Sort by `mention_rate` ascending to find where you are not mentioned. |
| `senso analytics prompt <promptId>` | One prompt's metric history, plus the latest full answer from every model and location. |
| `senso analytics answers` | The newest answer for each prompt, model and location, with its citations and competitor mentions. |
| `senso analytics glossary` | The definition, denominator and pitfall of every metric these commands return. |
| `senso analytics filters` | The models, locations, prompt types, tags and competitors that have data, so you can filter without guessing. |

| Command | Flag | What it does |
|---------|------|--------------|
| `analytics summary` | `--from <date>` | Window start, YYYY-MM-DD (default 30 days ending at the most recent day with data) |
| `analytics summary` | `--to <date>` | Window end, YYYY-MM-DD (max window: 365 days) |
| `analytics summary` | `--models <list>` | Comma-separated model filter — see 'senso analytics filters' |
| `analytics summary` | `--location <list>` | Comma-separated location filter, case-sensitive (e.g. US, US/California) |
| `analytics summary` | `--prompt-type <type>` | Funnel stage: awareness, consideration, evaluation, decision |
| `analytics summary` | `--tag <tag>` | Restrict to prompts carrying this tag |
| `analytics mentions` | `--from <date>` | Window start, YYYY-MM-DD (default 30 days ending at the most recent day with data) |
| `analytics mentions` | `--to <date>` | Window end, YYYY-MM-DD (max window: 365 days) |
| `analytics mentions` | `--models <list>` | Comma-separated model filter — see 'senso analytics filters' |
| `analytics mentions` | `--location <list>` | Comma-separated location filter, case-sensitive (e.g. US, US/California) |
| `analytics mentions` | `--prompt-type <type>` | Funnel stage: awareness, consideration, evaluation, decision |
| `analytics mentions` | `--tag <tag>` | Restrict to prompts carrying this tag |
| `analytics mentions` | `--group-by <bucket>` | Time bucket: day, week (default day) |
| `analytics citations` | `--from <date>` | Window start, YYYY-MM-DD (default 30 days ending at the most recent day with data) |
| `analytics citations` | `--to <date>` | Window end, YYYY-MM-DD (max window: 365 days) |
| `analytics citations` | `--models <list>` | Comma-separated model filter — see 'senso analytics filters' |
| `analytics citations` | `--location <list>` | Comma-separated location filter, case-sensitive (e.g. US, US/California) |
| `analytics citations` | `--prompt-type <type>` | Funnel stage: awareness, consideration, evaluation, decision |
| `analytics citations` | `--tag <tag>` | Restrict to prompts carrying this tag |
| `analytics citations` | `--group-by <bucket>` | Time bucket: day, week (default day) |
| `analytics domains` | `--from <date>` | Window start, YYYY-MM-DD (default 30 days ending at the most recent day with data) |
| `analytics domains` | `--to <date>` | Window end, YYYY-MM-DD (max window: 365 days) |
| `analytics domains` | `--models <list>` | Comma-separated model filter — see 'senso analytics filters' |
| `analytics domains` | `--location <list>` | Comma-separated location filter, case-sensitive (e.g. US, US/California) |
| `analytics domains` | `--prompt-type <type>` | Funnel stage: awareness, consideration, evaluation, decision |
| `analytics domains` | `--tier <tier>` | Filter by tier: primary, tracked, secondary |
| `analytics domains` | `--domain-contains <text>` | Substring filter on the domain |
| `analytics domains` | `--sort <field>` | Sort by: citations, coverage (default citations) |
| `analytics domains` | `--limit <n>` | Maximum rows to return (default 50, max: 100) |
| `analytics domains` | `--offset <n>` | Rows to skip (for pagination) |
| `analytics pages` | `--from <date>` | Window start, YYYY-MM-DD (default 30 days ending at the most recent day with data) |
| `analytics pages` | `--to <date>` | Window end, YYYY-MM-DD (max window: 365 days) |
| `analytics pages` | `--models <list>` | Comma-separated model filter — see 'senso analytics filters' |
| `analytics pages` | `--location <list>` | Comma-separated location filter, case-sensitive (e.g. US, US/California) |
| `analytics pages` | `--prompt-type <type>` | Funnel stage: awareness, consideration, evaluation, decision |
| `analytics pages` | `--tier <tier>` | Filter by tier: primary, tracked, secondary |
| `analytics pages` | `--domain <domain>` | Restrict to one exact domain |
| `analytics pages` | `--domain-contains <text>` | Substring filter on the domain |
| `analytics pages` | `--url-contains <text>` | Substring filter on the URL |
| `analytics pages` | `--sort <field>` | Sort by: citations, coverage (default citations) |
| `analytics pages` | `--limit <n>` | Maximum rows to return (default 50, max: 100) |
| `analytics pages` | `--offset <n>` | Rows to skip (for pagination) |
| `analytics prompts` | `--from <date>` | Window start, YYYY-MM-DD (default 30 days ending at the most recent day with data) |
| `analytics prompts` | `--to <date>` | Window end, YYYY-MM-DD (max window: 365 days) |
| `analytics prompts` | `--models <list>` | Comma-separated model filter — see 'senso analytics filters' |
| `analytics prompts` | `--location <list>` | Comma-separated location filter, case-sensitive (e.g. US, US/California) |
| `analytics prompts` | `--prompt-type <type>` | Funnel stage: awareness, consideration, evaluation, decision |
| `analytics prompts` | `--tag <tag>` | Restrict to prompts carrying this tag |
| `analytics prompts` | `--search <query>` | Filter prompts by question text |
| `analytics prompts` | `--sort <field>` | Sort by: mention_rate, share_of_voice, citations, answered, text (default mention_rate) |
| `analytics prompts` | `--order <dir>` | Sort direction: asc, desc (default desc) |
| `analytics prompts` | `--limit <n>` | Maximum rows to return (default 50, max: 100) |
| `analytics prompts` | `--offset <n>` | Rows to skip (for pagination) |
| `analytics prompt` | `--from <date>` | Window start, YYYY-MM-DD |
| `analytics prompt` | `--to <date>` | Window end, YYYY-MM-DD |
| `analytics prompt` | `--models <list>` | Comma-separated model filter |
| `analytics prompt` | `--location <list>` | Comma-separated location filter, case-sensitive |
| `analytics prompt` | `--no-include-answers` | Omit the latest answer bodies (included by default) |
| `analytics answers` | `--from <date>` | Answers collected on or after this date, YYYY-MM-DD (hides rows, never reveals older answers) |
| `analytics answers` | `--to <date>` | Answers collected on or before this date, YYYY-MM-DD (hides rows, never reveals older answers) |
| `analytics answers` | `--models <list>` | Comma-separated model filter |
| `analytics answers` | `--location <list>` | Comma-separated location filter, case-sensitive |
| `analytics answers` | `--prompt-type <type>` | Funnel stage: awareness, consideration, evaluation, decision |
| `analytics answers` | `--tag <tag>` | Restrict to prompts carrying this tag |
| `analytics answers` | `--mentioned <bool>` | Only answers that did (true) or did not (false) name your brand |
| `analytics answers` | `--cited <bool>` | Only answers that did (true) or did not (false) cite anything |
| `analytics answers` | `--citation-tier <tier>` | Only answers citing this tier: primary, tracked, secondary |
| `analytics answers` | `--limit <n>` | Maximum rows to return (default 25, max: 100) |
| `analytics answers` | `--offset <n>` | Rows to skip (for pagination) |

## Generate

Write content from your knowledge base and manage it through review.

### senso generate

| Command | What it does |
|---------|--------------|
| `senso generate settings` | Show whether content generation and auto-publish are on, the schedule and the destinations. |
| `senso generate update-settings` | Change the generation settings: on or off, auto-publish, schedule and default content type. |
| `senso generate sample` | Write one draft for a prompt in a content type, and wait for it. Without `--destination` it is saved as a draft only. |
| `senso generate run` | Generate content for all prompts, or the ones you name. Runs in the background; follow it with `runs-get`. |
| `senso generate job-context` | Show every prompt with its queue status (create or update) and a summary of the queue. |
| `senso generate runs-list` | List generation runs. |
| `senso generate runs-get <runId>` | Show one generation run. |
| `senso generate runs-items <runId>` | List the prompts in a run and each one's status and resulting content. |
| `senso generate runs-logs <runId>` | List a run's log entries. |
| `senso generate industry-draft` | Write a document for one of your industry's prompts and return it as markdown. It is not saved as content. |

| Command | Flag | What it does |
|---------|------|--------------|
| `generate update-settings` | `--data <json>` | JSON with any of `enable_content_generation`, `content_auto_publish`, `content_schedule` (days 0 to 6), `selected_content_type_id`. |
| `generate sample` | `--prompt-id <id>` | Prompt (geo question) ID to generate content for |
| `generate sample` | `--content-type-id <id>` | Content type ID that defines the output format (use 'content-types list' to find) |
| `generate sample` | `--destination <dest>` | Publisher slug to publish to immediately after generation. Omit to save as draft only. |
| `generate sample` | `--no-wait` | Return the accepted sample job immediately instead of polling for the generated content. |
| `generate run` | `--prompt-ids <ids...>` | Optional list of prompt IDs to process (omit to run all) |
| `generate run` | `--content-type-id <id>` | Override the org's default content type for this run |
| `generate run` | `--publisher-ids <ids...>` | Restrict publishing to specific publisher IDs |
| `generate runs-list` | `--limit <n>` | Items per page (default 20) |
| `generate runs-list` | `--offset <n>` | Pagination offset (default 0) |
| `generate runs-list` | `--status <status>` | Filter by run status |
| `generate runs-list` | `--active-only` | Only return active (in-progress) runs |
| `generate runs-list` | `--start-date <date>` | Filter runs on or after this date (YYYY-MM-DD) |
| `generate runs-list` | `--end-date <date>` | Filter runs on or before this date (YYYY-MM-DD) |
| `generate runs-items` | `--limit <n>` | Items per page (default 100) |
| `generate runs-items` | `--offset <n>` | Pagination offset (default 0) |
| `generate runs-items` | `--status <status>` | Filter by item status: pending, running, succeeded, failed, skipped, stopped |
| `generate runs-logs` | `--limit <n>` | Items per page (default 100) |
| `generate runs-logs` | `--offset <n>` | Pagination offset (default 0) |
| `generate industry-draft` | `--industry-prompt-id <id>` | An industry prompt id from `senso industries prompts` — NOT one of your own prompt ids |
| `generate industry-draft` | `--content-type-id <id>` | A content type id from `senso content-types list`, giving the document its format |
| `generate industry-draft` | `--product-line-ids <ids>` | Comma-separated product line ids (default all, up to 100) |
| `generate industry-draft` | `--audience <text>` | Who the document is for (max 500 chars) |
| `generate industry-draft` | `--style-tone <text>` | Voice and tone guidance (max 500 chars) |
| `generate industry-draft` | `--extra-instructions <text>` | Further instructions for the writer (max 4000 chars) |

### senso generated-content

| Command | What it does |
|---------|--------------|
| `senso generated-content list` | List generated content, published or drafts. |
| `senso generated-content get <id>` | Show one generated item, with its question and body. |

| Command | Flag | What it does |
|---------|------|--------------|
| `generated-content list` | `--status <status>` | Which items to list: published, drafts (default published) |
| `generated-content list` | `--limit <n>` | Items per page (max 100) (default 10) |
| `generated-content list` | `--offset <n>` | Pagination offset (default 0) |
| `generated-content list` | `--search <query>` | Filter by title |

### senso content

| Command | What it does |
|---------|--------------|
| `senso content list` | List the files and folders at the top of the knowledge base. `kb my-files` returns the same, in more detail. |
| `senso content get <id>` | Show a generated content item: its versions, metadata and publish status. Knowledge base documents are read with `kb get-content`. |
| `senso content delete <id>` | Delete a content item, and remove it from any destination it is published to. |
| `senso content unpublish <id>` | Take a content item down from every destination, or only some, and return it to draft. |
| `senso content verification` | List content in the review workflow, by editorial status. |
| `senso content verification-counts` | Count content by editorial status, with per-destination summaries. |
| `senso content verification-velocity` | How many published pages have been cited, and how long the first citation took. |
| `senso content provenance` | Trace one published URL back through generation to its sources and publish records. |
| `senso content citation-details <id>` | Citation detail for one published content item: a summary, each destination and a daily trend. |
| `senso content citation-prompts <id>` | The prompts and models whose answers cite a published item, and the lift against answers that do not. |
| `senso content record-edits <id>` | Record edit events for a content item. Events already recorded are skipped. |
| `senso content versions <id>` | List a content item's versions, newest first. |
| `senso content reject <versionId>` | Reject a content version in review, with an optional reason. |
| `senso content restore <versionId>` | Return a rejected version to draft. |
| `senso content owners <id>` | List a content item's owners. |
| `senso content set-owners <id>` | Replace a content item's owners. |
| `senso content remove-owner <id> <userId>` | Remove one owner from a content item. |
| `senso content tags list <id>` | List the tags on a content item. |
| `senso content tags set <id>` | Replace all the tags on a content item. Names that do not exist yet are created. |
| `senso content tags add <id>` | Add one tag to a content item. A new name is created. |
| `senso content tags remove <id>` | Remove one tag from a content item. |

| Command | Flag | What it does |
|---------|------|--------------|
| `content list` | `--limit <n>` | Items per page (default 10) |
| `content list` | `--offset <n>` | Pagination offset (default 0) |
| `content unpublish` | `--publish-record-ids <ids...>` | Restrict unpublish to specific publish_record UUIDs. Use 'content get <id>' to find publish record IDs for a content item. |
| `content verification` | `--limit <n>` | Maximum items to return |
| `content verification` | `--offset <n>` | Number of items to skip (for pagination) |
| `content verification` | `--search <query>` | Filter by title |
| `content verification` | `--status <status>` | Filter by status: all, draft, review, rejected, published |
| `content verification` | `--substatus <substatus>` | Narrow further (only valid with --status published): pending_draft |
| `content provenance` | `--url <url>` | The live published URL to audit, matched exactly |
| `content citation-details` | `--start-date <YYYY-MM-DD>` | Inclusive start of the window |
| `content citation-details` | `--end-date <YYYY-MM-DD>` | Inclusive end of the window; not before --start-date |
| `content citation-details` | `--models <list>` | Comma-separated models to filter by (e.g. chatgpt,perplexity). Omit for all. |
| `content citation-details` | `--locations <list>` | Comma-separated locations to filter by. Omit for all. |
| `content citation-prompts` | `--start-date <YYYY-MM-DD>` | Inclusive start of the window |
| `content citation-prompts` | `--end-date <YYYY-MM-DD>` | Inclusive end of the window; not before --start-date |
| `content citation-prompts` | `--models <list>` | Comma-separated models to filter by (e.g. chatgpt,perplexity). Omit for all. |
| `content citation-prompts` | `--locations <list>` | Comma-separated locations to filter by. Omit for all. |
| `content citation-prompts` | `--destinations <list>` | Comma-separated publisher slugs to restrict to. Unknown slugs are ignored. |
| `content record-edits` | `--data <json>` | JSON `{"events": [...]}`, each with `event_type`, `edit_source` and `client_event_id`. |
| `content reject` | `--reason <text>` | Reason for rejection |
| `content set-owners` | `--user-ids <ids...>` | User IDs to set as owners |
| `content tags set` | `--names <list>` | Comma-separated tag names (created if missing) |
| `content tags set` | `--ids <list>` | Comma-separated existing tag UUIDs |
| `content tags add` | `--name <name>` | Tag name (created if missing) |
| `content tags add` | `--id <tagId>` | Existing tag UUID |
| `content tags remove` | `--name <name>` | Tag name to detach |
| `content tags remove` | `--id <tagId>` | Existing tag UUID to detach |

### senso ctas

| Command | What it does |
|---------|--------------|
| `senso ctas list` | List the call-to-action templates, the default first. |
| `senso ctas create` | Create a call-to-action template. |
| `senso ctas update <ctaId>` | Replace a template. Any optional field you leave out is cleared. |
| `senso ctas delete <ctaId>` | Delete a template. The default cannot be deleted until you clear or change it. |
| `senso ctas set-default <ctaId>` | Make a template the organization default. |
| `senso ctas clear-default` | Clear the organization default. |
| `senso ctas for-content <contentId>` | Show which call to action a content item carries: the default, a pinned template, or none. |
| `senso ctas set-for-content <contentId>` | Set which call to action a content item carries. |
| `senso ctas upload-url` | Get a temporary link to upload an image for a template, and the `image_url` to use. |

| Command | Flag | What it does |
|---------|------|--------------|
| `ctas create` | `--data <json>` | JSON with `title`, `button_label` and `target_url` (required), and optionally `description`, `eyebrow`, `image_url`, `agent_text`, `is_default`. |
| `ctas update` | `--data <json>` | JSON with the full template. `title`, `button_label` and `target_url` are required. |
| `ctas set-for-content` | `--selection <type>` | What to carry: default, template, none |
| `ctas set-for-content` | `--cta-id <ctaId>` | The template to pin. Required with --selection template only. |
| `ctas upload-url` | `--filename <name>` | The file's name. Its extension, when it has one, must match --content-type. |
| `ctas upload-url` | `--content-type <type>` | The image media type: image/png, image/jpeg, image/webp, image/gif |
| `ctas upload-url` | `--size <bytes>` | The file size in bytes, at most 10485760 (10 MiB) |

## Publish

Send content to your destinations.

### senso engine

| Command | What it does |
|---------|--------------|
| `senso engine publish` | Publish markdown to your destinations. Pass `content_id` to publish a new version of an existing item. |
| `senso engine draft` | Save markdown as a draft for review. Pass `content_id` to add a version to an existing item. |

| Command | Flag | What it does |
|---------|------|--------------|
| `engine publish` | `--data <json>` | JSON with `raw_markdown` and `seo_title` (required), and optionally `content_id`, `geo_question_id`, `summary`, `publisher_ids`, `mark_as_published`. |
| `engine publish` | `--publisher-ids <ids...>` | Restrict publishing to specific publisher IDs. Overrides any publisher_ids present in --data. Omit to publish to all configured destinations (citeables by default). |
| `engine draft` | `--data <json>` | JSON with `raw_markdown` and `seo_title` (required), and optionally `content_id`, `geo_question_id`, `summary`. |

### senso destinations

| Command | What it does |
|---------|--------------|
| `senso destinations list` | List the destinations you can publish to, with live article counts. |
| `senso destinations add` | Register a custom domain as a destination. |
| `senso destinations remove <publisherId>` | Remove a destination, and choose what happens to content live on it. |

| Command | Flag | What it does |
|---------|------|--------------|
| `destinations add` | `--domain <domain>` | Custom domain to register (e.g. "content.example.com") |
| `destinations add` | `--name <name>` | Display name for the destination (e.g. "Example Citeables") |
| `destinations add` | `--type <type>` | Destination type. One of: citeables, codeables, cucopilot. Defaults to citeables. (default citeables) |
| `destinations remove` | `--action <action>` | One of: leave, unpublish, delete. See command description. |
| `destinations remove` | `--also-remove-destination` | Also delete the publisher row (not just the org link). Only valid for custom destinations you own. (default false) |
| `destinations remove` | `--keep-domain` | Keep the custom domain registered on citeables after removing (custom destinations only). (default false) |

### senso publish-records

| Command | What it does |
|---------|--------------|
| `senso publish-records retry <publishRecordId>` | Retry a publish that failed. |

## Agent skills and the CLI

Install skills for your coding agent, and manage the CLI itself.

### senso skills

| Command | What it does |
|---------|--------------|
| `senso skills install [names...]` | Install Senso agent skills. With no names, or `--all`, it installs the nine official skills as one set. |
| `senso skills list` | List the installed Senso skills. |
| `senso skills list-available` | List every official Senso skill you can install. |
| `senso skills remove <name>` | Remove an installed skill. |

| Command | Flag | What it does |
|---------|------|--------------|
| `skills install` | `--all` | Install every official Senso skill |
| `skills install` | `--agent <name>` | Target a specific agent: claude, cursor, codex, copilot, gemini, cline |
| `skills install` | `--global` | Install globally instead of project-level |
| `skills list` | `--global` | List globally installed skills |
| `skills remove` | `--global` | Remove from global install |

| Command | What it does |
|---------|--------------|
| `senso setup` | Install the nine official skills globally, for every supported agent, and remove retired ones. Installs only what is missing or out of date. |
| `senso update` | Update the CLI to the latest version. |
| `senso uninstall` | Remove the CLI, its skills and the stored key. Asks first unless you pass `--yes`. |

| Command | Flag | What it does |
|---------|------|--------------|
| `setup` | `--agent <name>` | Target a specific agent: claude, cursor, codex, copilot, gemini, cline |
| `setup` | `--global` | Install globally (the default; accepted so the flag is never an error) |
| `setup` | `--local` | Install into the current project instead of globally |
| `uninstall` | `-y, --yes` | Skip the confirmation prompt (required when there is no terminal) |
| `uninstall` | `--dry-run` | Report what would be removed without removing anything |
| `uninstall` | `--keep-skills` | Leave the installed agent skills alone |
| `uninstall` | `--keep-config` | Leave the stored API key and organization info alone |
## Next steps

- [Senso CLI](https://docs.senso.ai/docs/senso-cli) — Install the CLI and sign in
- [Send your first API request](https://docs.senso.ai/docs/quickstart) — The same round trip, over the API
- [API Keys](https://docs.senso.ai/docs/api-keys) — How keys work, and how to create, restrict and revoke one
- [Errors](https://docs.senso.ai/docs/errors) — Every status the API returns
