pindo-cli
The official command-line interface for Pindo, the SMS platform. Log in once, then send test messages, check your balance, manage your organization and pull reports from your terminal or from scripts.
- Installation
- Quick start
- Commands
- Authentication and configuration
- Reports
- Using the CLI in scripts
- Using the API directly
- Development
Installation
Requires Python 3.10 or newer.
The recommended way is pipx (or
uv), which installs the pindo command in its
own isolated environment:
pipx install pindo-cli
uv tool install pindo-cli
Plain pip works too:
python -m pip install --upgrade pindo-cli
Check it worked:
pindo --version
Quick start
pindo register # create an account (skip if you have one)
pindo login # saves your API token to ~/.pindo/config.toml
pindo balance # USD 71421.953
pindo sms --to +250781234567 --text "Hello from Pindo" --sender Pindo
Every command prompts for anything you leave out, and pindo <command> --help
(or -h) lists its options.
Commands
| Command | What it does |
|---|---|
pindo login |
Log in and save your API token for later commands |
pindo logout |
Delete the saved token |
pindo token |
Print a new API token without saving it |
pindo refresh-token |
Request a fresh token and update the saved one |
pindo register |
Create a new Pindo account |
pindo forgot-password |
Email yourself a password-recovery token |
pindo recover-password |
Set a new password with that recovery token |
pindo sms |
Send a test SMS |
pindo balance |
Show your account balance |
pindo org |
Update your organization's name, delivery-report webhook and retry count |
pindo config show |
Show the active base URL, user and (masked) token, and where the token came from |
pindo config path |
Print the config file location |
pindo report ... |
Reporting commands (see Reports) |
Global options go before the command:
| Option | Meaning |
|---|---|
--debug |
Log every API request and response to stderr. Passwords and tokens are redacted. |
--base-url URL |
Talk to another API environment, e.g. staging |
-v, --version |
Show the version |
-h, --help |
Show help |
pindo --debug balance
Phone numbers must be in international format with the country code
(+250781234567). Spaces, dashes and brackets are stripped, and a missing
leading + is added.
Authentication and configuration
pindo login stores your token in ~/.pindo/config.toml. The file and its
folder can only be read by your user account. Every command that needs a token
looks for one in this order:
--token/-ton the command line- the
PINDO_TOKENenvironment variable (handy for CI and cron jobs) - the config file written by
pindo login
| Environment variable | Purpose |
|---|---|
PINDO_TOKEN |
API token to use instead of the saved one |
PINDO_BASE_URL |
API base URL (default https://api.pindo.io) |
PINDO_CONFIG |
Use a different config file |
Run pindo config show to see which token is in use and where it came from.
Reports
Reporting commands live under pindo report and all share these options:
| Option | Meaning |
|---|---|
--from DATE / --to DATE |
Date range. Accepts 2026-10-01, today, yesterday or 30d. Default: last 7 days. |
--page N / --per-page N |
Pagination (default page 1, 50 rows) |
--all |
Fetch every page |
-o, --output table|csv|json |
Output format (default table) |
-f, --file PATH |
Write to a file instead of the terminal |
--tz ZONE |
Timezone for dates, e.g. Africa/Kigali or UTC (default: your local zone) |
Run pindo report --help to see the available reports.
Using the CLI in scripts
Errors are printed to stderr as a single Error: ... line, and the exit code
tells you what happened:
| Exit code | Meaning |
|---|---|
0 |
Success |
1 |
The API or the network returned an error (bad token, unknown email, server down, ...) |
2 |
Invalid usage, e.g. a missing option or a malformed phone number |
$ pindo balance --token wrong
Error: Unauthorized. Your token is invalid or expired; run `pindo login`. (HTTP 401)
$ echo $?
1
Read-only requests are retried automatically, with backoff, when the server is temporarily unavailable (HTTP 429/502/503/504). Requests that send messages or change data are never retried, so an SMS is never sent twice.
Using the API directly
The CLI is a thin client for the Pindo REST API. Examples for sending SMS (single and bulk), inbound messages, delivery-report webhooks and PindoVerify in cURL, Python, Node.js, PHP, Ruby, Go, Java and C# are in docs/api.md.
Development
You need Poetry 2.x.
git clone https://github.com/pindoio/pindo-cli.git
cd pindo-cli
poetry install
poetry run pre-commit install # optional: lint and format on every commit
| Task | Command |
|---|---|
| Run the tests (all HTTP is mocked) | poetry run pytest --cov |
| Also run tests against the live API | poetry run pytest --run-live |
| Lint | poetry run ruff check . |
| Format | poetry run ruff format . |
| Type-check | poetry run mypy |
| Run the CLI from source | poetry run pindo --help |
See CONTRIBUTING.md for how the code is laid out and how releases work. To report a security issue, see SECURITY.md.
License
Metadata
Release files for pindo-cli 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pindo_cli-1.2.0.tar.gz | 21.7 kB | With provenance | Details for pindo_cli-1.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pindo_cli-1.2.0-py3-none-any.whl | Python 3 | none | any | Details for pindo_cli-1.2.0-py3-none-any.whl |
Total release size: 44.4 kB
Release files / pindo_cli-1.2.0.tar.gz
| Download URL | pindo_cli-1.2.0.tar.gz |
|---|---|
| Size | 21.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ebe49aabfb517dc473b129c35872ef7a873ef4f34426f4d3c33056f8a0142ead
|
|
BLAKE2b-256 checksum How to use checksums |
48f6bd37a9493b5d1fa4a069c6726d494bb738d4eda57656159ba0e94d1355d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / pindo_cli-1.2.0-py3-none-any.whl
| Download URL | pindo_cli-1.2.0-py3-none-any.whl |
|---|---|
| Size | 22.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
19dc3cdd28fd66d56b92e1565c4477c618c71298fee9b09180ce0fdf66b093fd
|
|
BLAKE2b-256 checksum How to use checksums |
f5e8230500cb2bca683415922f540916ead92b32e46979be0a19d3551aff6f4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logSecurity for pindo-cli 1.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for pindo_cli-1.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.