Grants
Command line (CLI)
A native command-line client for Grants. One install line.
The Grants CLI is auto-generated from the same models the HTTP API exposes - every endpoint you can hit with curl is also a subcommand here. The script is one self-contained Python file (no pip install), checks for updates once a day, and authenticates with the same Bearer tokens the rest of the API accepts.
Install
One line, one file. The script lands under your home directory - no pip install, no system-wide changes. Pick your OS in the tabs below.
curl -fsSL https://granttool.de/xapi2/cli/install.sh | bash
1.2.8·Command: grantscli·checksum: 6d49ad4588…Sign in
Every command except login / version / update requires a valid token. Two ways in: a personal access token (PAT) from the Integrations menu (recommended for scripts + CI), or interactive email + password (saved as a session token under ~/.grantscli/credentials.json, mode 0600).
grantscli login --token pat_…
Commands
Each data model is a subgroup. Click a model name to jump to its detail page; the available ops mirror the HTTP API one-to-one.
| Model | Commands |
|---|---|
| derived_doc | grantscli derived_doc listgrantscli derived_doc getgrantscli derived_doc creategrantscli derived_doc updategrantscli derived_doc deletegrantscli derived_doc upsert |
| feedback_item | grantscli feedback_item listgrantscli feedback_item getgrantscli feedback_item creategrantscli feedback_item updategrantscli feedback_item deletegrantscli feedback_item upsert |
| feedback_point | grantscli feedback_point listgrantscli feedback_point getgrantscli feedback_point creategrantscli feedback_point updategrantscli feedback_point deletegrantscli feedback_point upsert |
| file | grantscli file listgrantscli file getgrantscli file creategrantscli file updategrantscli file deletegrantscli file upsert |
| folder | grantscli folder listgrantscli folder getgrantscli folder creategrantscli folder updategrantscli folder deletegrantscli folder upsert |
| grant | grantscli grant listgrantscli grant getgrantscli grant creategrantscli grant updategrantscli grant deletegrantscli grant upsert |
| lead | grantscli lead listgrantscli lead getgrantscli lead creategrantscli lead updategrantscli lead deletegrantscli lead upsert |
| loi | grantscli loi listgrantscli loi getgrantscli loi creategrantscli loi updategrantscli loi deletegrantscli loi upsert |
| review_note | grantscli review_note listgrantscli review_note getgrantscli review_note creategrantscli review_note updategrantscli review_note deletegrantscli review_note upsert |
| version_snapshot | grantscli version_snapshot listgrantscli version_snapshot getgrantscli version_snapshot creategrantscli version_snapshot updategrantscli version_snapshot deletegrantscli version_snapshot upsert |
--filter name=Foo (repeatable), --all (auto-paginate), --fields id,name (project response), --cache N (local cache, N s), --file p.json / --csv p.csv / --stdin (bulk input; arrays + CSV rows), --continue-on-error (don't stop on bulk failure; exit 1 if any failed), --dry-run (preview the request), --idempotency-key K / --auto-idempotency (safe retries), --retry N + --backoff exp (auto-retry 429/5xx), --format json|ndjson|table (output shape), --stderr-json (machine-readable errors), --profile NAME (switch credentials).Use with an AI assistant
Models like Claude, ChatGPT, or Gemini will write scripts that drive this CLI for you - they only need the context below. Copy the block into your chat, then describe what you want to do.
Help me write scripts using `grantscli`, the CLI for the Grants app.Install:macOS/Linux: curl -fsSL https://granttool.de/xapi2/cli/install.sh | bashWindows PS: irm https://granttool.de/xapi2/cli/install.ps1 | iexSign in (required before any data command):grantscli login --token pat_… # personal access tokengrantscli login # interactive (token or email + password)Commands per model:grantscli derived_doc { list | get | create | update | delete | upsert }fields: --grant-id --kind --based-on-version --status --formats --latest-blob-id --latest-formatgrantscli feedback_item { list | get | create | update | delete | upsert }fields: --grant-id --source-type --who --subject --body --urgent --unread --status --due-dategrantscli feedback_point { list | get | create | update | delete | upsert }fields: --grant-id --feedback-item-id --chapter-key --kind --excerpt --suggestion --applied --applied-atgrantscli file { list | get | create | update | delete | upsert }fields: --name --kind --content --doc --grant-id --folder-id --is-root --blob-id --mime-type --size-bytes --sort-order --chapter-type --chapter-answers --ai-messages --import-status --import-gaps --import-atgrantscli folder { list | get | create | update | delete | upsert }fields: --name --grant-id --parent-folder-id --sort-ordergrantscli grant { list | get | create | update | delete | upsert }fields: --grant-type-key --title --description --funder --program --deadline --requested-amount --currency --status --compiler --root-file-id --tags --notes --color --intake-blob-id --intake-url --intake-extracted --import-status --import-started-at --import-finished-at --intake-extracted-by-source --intake-sources --awarded-amount --awarded-at --profile --team-size --baseline-scoregrantscli lead { list | get | create | update | delete | upsert }fields: --first-name --last-name --gender --company --position --fair-location --phone --email --linkedin --website --city --country --lead-status --note --tags --inferred-gender --inferred-country --inferred-domain --account-id --lead-source-id --last-contacted-atgrantscli loi { list | get | create | update | delete | upsert }fields: --grant-id --lead-id --partner-id --status --scope-months --exclusive --body --blob-idgrantscli review_note { list | get | create | update | delete | upsert }fields: --grant-id --chapter-key --who --role --body --resolved --resolved-atgrantscli version_snapshot { list | get | create | update | delete | upsert }fields: --grant-id --label --score --summary --snapshot --feedback-trigger --derived-keysOutput + flags:- stdout is JSON (one object, or {data:[...], meta:{...}} on list).- errors go to stderr; non-zero exit (3=auth, 5=not found, 6=validation, 7=conflict, 8=rate-limited).- --filter name=Foo (friendly key, repeatable) on `list`.- --all auto-paginates; --fields id,name projects; --cache N caches list/get for N s.- writes accept --json '{...}', --file path.json (arrays = bulk), --stdin, or --csv path [--map k=COL,…].- upsert needs --unique <field>; --dry-run previews any write.- --retry N --backoff exp survives 429/5xx; --stderr-json gives machine-readable errors.Field schemas + constraints per model: https://granttool.de/docs/types/<model>Full CLI reference: https://granttool.de/docs/cliTask: <describe what you want to do>
Examples
grantscli login --token pat_…grantscli whoami
Recipes
End-to-end snippets for the workflows people actually run. Pick a tab.
# items.csv has columns: grant_id,Full Name,status# --map renames CSV headers to API field names; missing cells skipped.grantscli derived_doc create \--csv items.csv \--map name=Full Name \--continue-on-error \--retry 3 --backoff exp
Environment variables
| Variable | Purpose |
|---|---|
| XCLI_NO_AUTOUPDATE | Skip the once-per-day version check + self-replace. |
| XCLI_NO_TELEMETRY | Skip the anonymous CLI usage analytics. |
| XCLI_BASE_URL | Override the baked-in server URL (testing only). |
| XCLI_TOKEN | Use this PAT for the current invocation without saving it. |
Telemetry + auto-update
The CLI sends one anonymous analytics event per command (command name, version, OS - no request bodies, no field values) so the team running this app can see how it's used in the same dashboard as the web UI. The data is processed securely; an audit log of every event tied to you can be requested at any time from the company operating the app. We strongly encourage leaving telemetry on - it's how reliability issues surface and how the team prioritises improvements that affect you. It can be turned off with XCLI_NO_TELEMETRY=1. Separately, the CLI checks for a newer version at most once every 24 hours and updates itself in place; XCLI_NO_AUTOUPDATE=1 disables that.