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
Download script manuallyVersion: 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.

ModelCommands
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
Useful flags: --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 | bash
Windows PS: irm https://granttool.de/xapi2/cli/install.ps1 | iex
Sign in (required before any data command):
grantscli login --token pat_… # personal access token
grantscli 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-format
grantscli feedback_item { list | get | create | update | delete | upsert }
fields: --grant-id --source-type --who --subject --body --urgent --unread --status --due-date
grantscli feedback_point { list | get | create | update | delete | upsert }
fields: --grant-id --feedback-item-id --chapter-key --kind --excerpt --suggestion --applied --applied-at
grantscli 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-at
grantscli folder { list | get | create | update | delete | upsert }
fields: --name --grant-id --parent-folder-id --sort-order
grantscli 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-score
grantscli 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-at
grantscli loi { list | get | create | update | delete | upsert }
fields: --grant-id --lead-id --partner-id --status --scope-months --exclusive --body --blob-id
grantscli review_note { list | get | create | update | delete | upsert }
fields: --grant-id --chapter-key --who --role --body --resolved --resolved-at
grantscli version_snapshot { list | get | create | update | delete | upsert }
fields: --grant-id --label --score --summary --snapshot --feedback-trigger --derived-keys
Output + 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/cli
Task: <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

VariablePurpose
XCLI_NO_AUTOUPDATESkip the once-per-day version check + self-replace.
XCLI_NO_TELEMETRYSkip the anonymous CLI usage analytics.
XCLI_BASE_URLOverride the baked-in server URL (testing only).
XCLI_TOKENUse 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.