BL By Lipa

User API

Exchange & wallet API

Automate buy and sell flows, read balances, send USDT on-chain, and transfer to other By Lipa users. Designed for trading bots, fintech wrappers, and backend integrations — not for public client apps.

Key + secret Prefix sc_user_ Max 5 active keys

Introduction

The User API acts on behalf of a registered By Lipa account. Your integration supplies API key and API secret headers; the gateway resolves the owning user and injects user_id into downstream services — you never pass user_id yourself.

Generate credentials in the user app: Profile → Developer API access. The secret is shown once at creation.

Authentication

Include both headers on every request:

Headers
X-Api-Key: sc_user_xxxxxxxxxxxxxxxxxxxxxxxx
X-Api-Secret: sc_ussec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

Alternatively, browser/session integrations may use Authorization: Bearer <session_token> from POST /v1/auth/login.

Quickstart

Fetch wallet balance, then place a buy order funded by mobile money:

cURL
curl "https://bylipa.com/api/v1/wallet" \
  -H "X-Api-Key: sc_user_YOUR_KEY" \
  -H "X-Api-Secret: sc_ussec_YOUR_SECRET"

curl -X POST "https://bylipa.com/api/v1/orders/buy" \
  -H "X-Api-Key: sc_user_YOUR_KEY" \
  -H "X-Api-Secret: sc_ussec_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "0712345678",
    "amount_tzs": 50000,
    "receive_address": "TYourTronWalletAddress..."
  }'

Manage API keys

These endpoints require a session Bearer token (user logged into the app), not API key auth.

GET /v1/developer/api-keys

List API keys

Returns active and revoked keys (prefix only — never the full secret).

Response
{
  "api_keys": [
    {
      "id": 1,
      "name": "Trading bot",
      "key_prefix": "sc_user_abcd1234",
      "status": "active",
      "last_used_at": "2026-06-10T12:00:00+00:00",
      "created_at": "2026-06-01T09:00:00+00:00"
    }
  ],
  "max_keys": 5
}
POST /v1/developer/api-keys

Create API key

FieldTypeRequiredDescription
namestringYesLabel for your dashboard (max 80 chars)
Response 201
{
  "message": "API key created. Copy the secret now — it will not be shown again.",
  "credentials": {
    "api_key": "sc_user_…",
    "api_secret": "sc_ussec_…"
  }
}
DELETE /v1/developer/api-keys/{id}

Revoke API key

Wallet

GET /v1/wallet

Get balance

Available, pending, and locked USDT plus live TZS equivalent.

Response
{
  "wallet": {
    "user_id": 42,
    "asset": "USDT",
    "network": "tron",
    "available": 125.5,
    "pending": 10.0,
    "locked": 0,
    "total": 135.5,
    "rate_tzs_per_usdt": 2650,
    "tzs_equivalent": 332575
  }
}
GET /v1/wallet/receive

Deposit address

TRON deposit address for topping up via on-chain USDT.

Query
?chain=tron

Orders — Buy USDT

POST /v1/orders/buy

Create buy order

Customer pays TZS via mobile money; USDT is sent to receive_address after payment confirms.

FieldTypeRequiredDescription
phonestringYesMobile money number (e.g. 0712345678)
amount_tzsnumberYesMinimum 1000 TZS
receive_addressstringYes*TRON TRC20 address (T…). Omit if using internal wallet credit.
mobile_operatorstringNompesa, tigo, airtel — auto-detected if omitted
networkstringNoDefault tron
credit_internal_walletbooleanNoCredit in-app wallet instead of external address
Request
{
  "phone": "0712345678",
  "amount_tzs": 50000,
  "receive_address": "TYourTronAddress..."
}
Response 201
{
  "order": {
    "reference": "ORD-20260610-ABC123",
    "side": "buy",
    "status": "pending_payment",
    "amount_tzs": 50000,
    "amount_usdt": 18.867925,
    "rate": 2650
  },
  "payment": {
    "instructions": "Pay via mobile money prompt on 0712345678"
  }
}

Orders — Sell USDT

POST /v1/orders/sell

Create sell order

Sell USDT from wallet; TZS disbursed to mobile money after on-chain receipt (if external) or immediately (internal wallet).

FieldTypeRequiredDescription
phonestringYesPayout mobile money number
amount_usdtnumberYesUSDT amount to sell
debit_internal_walletbooleanNoSell from in-app balance (default false = deposit USDT first)
withdraw_addressstringNoOverride payout destination
Large sells may require step-up verification — see X-Step-Up-Token.

Orders — List

GET /v1/orders

List orders

Query parameters: page, per_page (max 100), side (buy|sell), search, date_from, date_to.

Orders — Retrieve

GET /v1/orders/{reference}

Get order by reference

Returns 404 if the order belongs to another user.

Send USDT on-chain

POST /v1/wallet/send

Send to external address

FieldTypeRequiredDescription
amount_usdtnumberYesAmount to send
to_addressstringYesDestination wallet
networkstringNoDefault tron

Transfer to another user

POST /v1/wallet/transfer

P2P transfer

Provide exactly one of phone or username for the recipient.

Request
{
  "username": "magori",
  "amount_usdt": 5.0
}

Rates (public)

No authentication required.

GET /v1/rates/quote

Quote by TZS

Example
GET https://bylipa.com/api/v1/rates/quote?side=buy&amount_tzs=100000
GET /v1/rates/quote-usdt

Quote by USDT

Step-up verification

Withdrawals above configured thresholds return HTTP 403:

403 response
{
  "message": "Verification required for withdrawals above 100 USDT.",
  "requires_step_up": true,
  "purpose": "usdt_send"
}

Complete OTP via session auth, then retry with header X-Step-Up-Token: <token>.

Errors

See the overview error table. User API never exposes stack traces.