Skip to main content

pesa-cli

Command-line tool for M-Pesa Daraja v3 — STK Push, B2C, balance check, config management.

CI Python Tests License

Test integrations, trigger payments, and check balances from your terminal — without opening the Safaricom portal or writing a script.


Install

pip install pesa-cli

Setup

# Set credentials once — stored in ~/.pesa/config.json (mode 600)
pesa config set --key consumer-key    --value YOUR_CONSUMER_KEY
pesa config set --key consumer-secret --value YOUR_CONSUMER_SECRET
pesa config set --key shortcode       --value 174379
pesa config set --key passkey         --value YOUR_PASSKEY
pesa config set --key environment     --value sandbox   # or production

# Or use environment variables (useful in CI/CD)
export DARAJA_CONSUMER_KEY=...
export DARAJA_CONSUMER_SECRET=...

# Test credentials
pesa auth

Commands

pesa auth

Test credentials and verify connectivity.

✓ Authenticated
Environment: sandbox
Token: mock_token_ab...3456
Expires in: ~60 minutes

pesa stk push PHONE AMOUNT

Initiate an STK Push payment request. The customer receives a PIN prompt on their phone.

pesa stk push 0712345678 500
pesa stk push 0712345678 500 --ref "Invoice001" --desc "Monthly contribution"
✓ STK Push sent
Phone:       +254712345678
Amount:      KES 500
Reference:   Invoice001
Checkout ID: ws_CO_150120241430221234567890

Run: pesa stk query ws_CO_150120241430221234567890

pesa stk query CHECKOUT_ID

Poll the status of an STK Push.

pesa stk query ws_CO_150120241430221234567890
✓ The service request is processed successfully.
Result Code: 0

pesa b2c PHONE AMOUNT

Send money from your shortcode to a phone number.

pesa b2c 0712345678 1000 --remarks "Chama disbursement"

pesa balance

Request account balance (result posted to your ResultURL asynchronously).

pesa balance

pesa config show

Display current configuration with secrets masked.

┌──────────────────────────────────────────────────┐
│ pesa configuration                               │
├──────────────────┬─────────────┬─────────────────┤
│ consumer_key     │ config file │ ************3456 │
│ consumer_secret  │ config file │ ************abcd │
│ shortcode        │ config file │ 174379           │
│ environment      │ config file │ sandbox          │
└──────────────────┴─────────────┴─────────────────┘

Credentials

Credentials are resolved in this order: environment variable → config file.

Credential Config key Environment variable
Consumer Key consumer_key DARAJA_CONSUMER_KEY
Consumer Secret consumer_secret DARAJA_CONSUMER_SECRET
Shortcode shortcode DARAJA_SHORTCODE
Passkey passkey DARAJA_PASSKEY
Initiator Name initiator_name DARAJA_INITIATOR_NAME
Security Credential security_credential DARAJA_SECURITY_CREDENTIAL
Environment environment DARAJA_ENVIRONMENT

Config file is stored at ~/.pesa/config.json with mode 600 (owner read/write only). Override location with PESA_CONFIG=/path/to/config.json.


Use with daraja-mock

# Start daraja-mock
python -m daraja_mock --port 8765

# Point pesa-cli at the mock
export PESA_BASE_URL=http://localhost:8765
pesa auth
pesa stk push 0712345678 100 --ref "Test"

Design decisions

Credentials resolved env → file. CI/CD environments should use env vars. Developer machines use the config file. The CLI never asks for credentials interactively — that would break scripting.

Secrets masked at 600. The config file is created with chmod 600 so other users on shared systems cannot read Daraja credentials.

AccountReference truncated silently. Daraja rejects AccountReference > 12 chars with a cryptic error. The CLI truncates to 12 and shows what was sent.

Rich output, not JSON by default. For human use. Add --output json flag if scripting against pesa-cli output is needed.


Part of the nairobi-stack East Africa engineering ecosystem. Maintained by Gabriel Mahia. Kenya × USA.

Getting sandbox credentials

New to Daraja, or on a new machine? Follow the sandbox setup guide: it creates a free sandbox app and runs OAuth, an STK Push and a status query, with exact portal labels. Set DARAJA_CALLBACK_URL to a public HTTPS address you can watch (for example a webhook.site URL); without it the CLI uses a placeholder and tells you so.

Metadata

Release files for pesa-cli 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pesa-cli 1.0.3
File Size Uploaded Provenance Actions
pesa_cli-1.0.3.tar.gz 15.1 kB With provenance Details for pesa_cli-1.0.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pesa-cli 1.0.3
File Interpreter ABI Platform Actions
pesa_cli-1.0.3-py3-none-any.whl Python 3 none any Details for pesa_cli-1.0.3-py3-none-any.whl

Total release size: 27.5 kB

Release files / pesa_cli-1.0.3.tar.gz

Download URL pesa_cli-1.0.3.tar.gz
Size 15.1 kB
Tags Source
SHA-256 checksum
How to use checksums
63a2149a158ba7599d0d6b83dd8f4655da35d0b11d7c5e392267183cce3ee1ba
BLAKE2b-256 checksum
How to use checksums
43bd8298b050d5a3a7f4df51df98997b2b00a4337bf3a30ccbc2da181540fd50
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 Oct 21, 2026.

Transparency log

Release files / pesa_cli-1.0.3-py3-none-any.whl

Download URL pesa_cli-1.0.3-py3-none-any.whl
Size 12.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
02745f7d66b664cb2f24822280f9f378a88400fb89dc3d0b82babd18433ef75c
BLAKE2b-256 checksum
How to use checksums
d54350ce9f89e8fc3f64b4dc498eddeb1d0c275b197a2d86670607b2800b813b
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 Oct 21, 2026.

Transparency log

Security for pesa-cli 1.0.3

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

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pesa_cli-1.0.3.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 Oct 21, 2026.

Transparency log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page