TwigaPlus

API

Collect and pay out Tanzanian shillings. Amounts are TZS strings with two decimal places, such as 1500.00. Send whole shillings only.

https://api.twigaplus.com

Authentication

Create a key in the dashboard. Send it on every request. The key is shown once. Identity must be approved before a key can move money. A suspended account rejects every key, including keys created before the suspension.

Authorization: Bearer twg_...
  • collections:write create a collection
  • collections:read read a collection
  • payouts:write send a payout
  • payouts:read quote or read a payout

Idempotency

idempotency_key is required when creating a collection or payout. Use 8 to 80 characters: letters, numbers, _, :, or -. The same key and the same request return the original result. The same key with a different request is rejected.

Errors

Failed requests return JSON.

{ "detail": "Insufficient balance" }
POST/api/v1/partner/collections

Ask the customer to approve a prompt on their phone. The smallest amount is 500 TZS. The fee is taken when the payment completes.

collections:write

Request

{
  "amount": "1500.00",
  "phone": "+255712345678",
  "first_name": "Amina",
  "last_name": "Juma",
  "email": "amina@example.com",
  "idempotency_key": "order-1042"
}

Response

{
  "id": "68e5c0f1ab12cd34ef567890",
  "status": "pending",
  "gross": "1500.00",
  "fee": "45.00",
  "net": "1455.00",
  "phone": "255712345678",
  "currency": "TZS"
}
GET/api/v1/partner/collections/{id}

Reads the collection stored by TwigaPlus. A pending collection is refreshed before that stored status is returned. Status is pending, completed, failed, or expired. gross is what the customer pays. net is what is credited.

collections:read

POST/api/v1/partner/payouts/quote

amount is what the recipient should receive, at least 5000 TZS. gross is the amount held from the balance, including the network fee.

payouts:read

Request

{ "amount": "5000.00" }

Response

{
  "currency": "TZS",
  "gross": "5100.00",
  "fee": "100.00",
  "net": "5000.00",
  "fee_percentage": "0.00",
  "available": "25000.00"
}
POST/api/v1/partner/payouts

Sends net to the phone and holds gross until the network confirms. net must be at least 5000 TZS. phone is a Tanzanian mobile number. note is optional.

payouts:write

Request

{
  "amount": "5000.00",
  "phone": "+255712345678",
  "idempotency_key": "payout-88",
  "note": "Salary"
}

Response

{
  "id": "68e5c1aaab12cd34ef567891",
  "status": "pending",
  "gross": "5100.00",
  "fee": "100.00",
  "net": "5000.00",
  "phone": "255712345678",
  "currency": "TZS",
  "created_at": "2026-10-08T03:00:00Z"
}
GET/api/v1/partner/payouts/{id}

Reads the payout stored by TwigaPlus. A pending payout is refreshed before that stored status is returned. Status is pending, completed, or rejected.

payouts:read

Webhooks

Add an HTTPS endpoint in the dashboard. TwigaPlus posts when a collection or payout reaches a final state. Respond with a 2xx status. The signature is hex HMAC-SHA256 of the timestamp, a dot, and the raw body, using your signing secret.

X-TwigaPlus-Event: collection.completed
X-TwigaPlus-Timestamp: 1760000000
X-TwigaPlus-Signature: hex hmac sha256 of "{timestamp}.{raw body}"
{
  "id": "evt_ab12",
  "type": "collection.completed",
  "data": {
    "id": "68e5c0f1ab12cd34ef567890",
    "status": "completed",
    "gross": "1500.00",
    "fee": "45.00",
    "net": "1455.00",
    "phone": "255712345678",
    "currency": "TZS"
  }
}

Events: collection.completed, collection.failed, collection.expired, payout.completed, payout.failed, payout.reversed.