Bearer token (OAuth2 password grant)
Use this method for all standard API calls — M-Pesa deposits, disbursements, wallet operations, webhooks, and more.Request a token
Send aPOST request to /api/token/ with your API caller credentials in the request body and your application credentials as HTTP Basic auth.
Token request parameters
| Parameter | Location | Description |
|---|---|---|
grant_type | Body | Always password |
username | Body | Your API caller username |
password | Body | Your API caller password |
CLIENT-ID | Basic auth username | Your application’s Client ID |
CLIENT-SECRET | Basic auth password | Your application’s Client Secret |
Use the token in requests
Include the token in theAuthorization header of every subsequent request:
Tokens expire after a period of inactivity. When a request returns a
401 Unauthorized response, request a new token using the same flow above.Public key
Your Public Key identifies your business for checkout and collection requests. You can find it in your dashboard under API Applications. Public keys follow the formatISPubKey_live_... in production and ISPubKey_test_... in the sandbox.
Pass your public key in one of two ways:
Option 1 — Request body:
When testing in the sandbox, use
ISPubKey_test_... credentials. Using a live public key against sandbox.kulmipay.com will return an authentication error.Common authentication errors
| Status | Error | What to do |
|---|---|---|
401 Unauthorized | Invalid credentials | Check your username, password, Client ID, and Client Secret |
401 Unauthorized | Token expired | Request a new access token |
400 Bad Request | Invalid API credential | Your public key or secret key is malformed or from the wrong environment |
400 Bad Request | Invalid API credential for live environment | You’re using a test key against the live API, or vice versa |
Keeping credentials secure
- Never expose your Client Secret or API caller password in client-side code, public repositories, or logs.
- Store credentials in environment variables or a secrets manager, not in source files.
- If a credential is compromised, rotate it immediately from the API Applications section of your dashboard.
