API Reference
One REST API to bank your farmers. Everything you create belongs to your organization. Amounts are in Ghana cedis (GHS).
1. Get a key
Create an organization, then open Developers. ffsp_test_ keys use simulated money; ffsp_live_ keys move real money through GCB.
2. Authenticate
BASE=https://<your-domain>/api/public/v1
FFSP_KEY=ffsp_test_xxxxxxxxxxxxxxxx
curl "$BASE/ping" -H "Authorization: Bearer $FFSP_KEY"
# {"ok":true,"mode":"test"}3. Safe retries
Send an Idempotency-Key header on every POST. Repeating a request with the same key returns the original result instead of moving money twice.
Errors
{ "error": { "code": "insufficient_funds", "message": "Farmer has insufficient balance" } }401 unauthorized— Missing, invalid or revoked key404 not_found— Resource doesn't exist in your org409 insufficient_funds— Farmer balance too low409 insufficient_wallet_funds— Fund your organization wallet409 account_frozen— Farmer account is frozen422 validation_error— See error.details502 bank_error— GCB rejected or is unavailable500 internal_error— Retry with the same Idempotency-Key
Webhooks
Events: transaction.success, transaction.pending, transaction.failed, farmer.created, loan.disbursed, loan.repayment. Verify every request:
// Node.js
const crypto = require("crypto");
const ts = req.headers["ffsp-timestamp"];
const expected = "sha256=" + crypto.createHmac("sha256", WEBHOOK_SECRET)
.update(`${ts}.${rawBody}`).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["ffsp-signature"])))
return res.status(401).end();Farmers
/farmersCreate a farmer account
Opens a GCB savings account under your organization.
full_name*— 2–120 charsphone*— Ghana number, 0XXXXXXXXX or +233ghana_card— GHA-000000000-0external_id— Your own ID, unique per orgemail, community, region, metadata— Optional
curl -X POST "$BASE/farmers" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"full_name":"Ama Owusu","phone":"0241234567","ghana_card":"GHA-000000000-0","community":"Kumawu","region":"Ashanti","external_id":"coop-0042"}'{
"id": "6f1c2c8e-…",
"object": "farmer",
"external_id": "coop-0042",
"full_name": "Ama Owusu",
"phone": "0241234567",
"account_number": "DOS0241234567",
"balance": 0,
"currency": "GHS",
"status": "active",
"kyc_status": "unverified",
"mode": "test"
}/farmers?limit=20&offset=0List farmers
Paginated. Filter with ?external_id=.
curl -X GET "$BASE/farmers?limit=20&offset=0" \ -H "Authorization: Bearer $FFSP_KEY"
{
"object": "list",
"data": [
{
"id": "6f1c2c8e-…",
"object": "farmer",
"external_id": "coop-0042",
"full_name": "Ama Owusu",
"phone": "0241234567",
"account_number": "DOS0241234567",
"balance": 0,
"currency": "GHS",
"status": "active",
"kyc_status": "unverified",
"mode": "test"
}
],
"total": 1,
"limit": 20,
"offset": 0
}/farmers/{id}Get a farmer
curl -X GET "$BASE/farmers/{id}" \
-H "Authorization: Bearer $FFSP_KEY"{
"id": "6f1c2c8e-…",
"object": "farmer",
"external_id": "coop-0042",
"full_name": "Ama Owusu",
"phone": "0241234567",
"account_number": "DOS0241234567",
"balance": 0,
"currency": "GHS",
"status": "active",
"kyc_status": "unverified",
"mode": "test"
}/farmers/{id}Update or freeze
Set status to frozen to block all money movement.
curl -X PATCH "$BASE/farmers/{id}" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"status":"frozen"}'{
"id": "6f1c2c8e-…",
"object": "farmer",
"external_id": "coop-0042",
"full_name": "Ama Owusu",
"phone": "0241234567",
"account_number": "DOS0241234567",
"balance": 0,
"currency": "GHS",
"status": "frozen",
"kyc_status": "unverified",
"mode": "test"
}/farmers/{id}/balanceGet balance
curl -X GET "$BASE/farmers/{id}/balance" \
-H "Authorization: Bearer $FFSP_KEY"{
"object": "balance",
"farmer_id": "6f1c…",
"account_number": "DOS0241234567",
"balance": 150,
"currency": "GHS"
}/farmers/{id}/transactionsStatement
Paginated transaction history.
curl -X GET "$BASE/farmers/{id}/transactions" \
-H "Authorization: Bearer $FFSP_KEY"{
"object": "list",
"data": [
{
"id": "a83b…",
"object": "transaction",
"type": "credit",
"direction": "C",
"amount": 150,
"currency": "GHS",
"status": "success",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}
],
"total": 1
}Money movement
/farmers/{id}/creditCredit
Moves money from your organization wallet into the farmer's account.
curl -X POST "$BASE/farmers/{id}/credit" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"amount":150,"narration":"Cocoa bonus"}'{
"id": "a83b…",
"object": "transaction",
"type": "credit",
"direction": "C",
"amount": 150,
"currency": "GHS",
"status": "success",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}/farmers/{id}/debitDebit
Moves money from the farmer's account back to your organization wallet.
curl -X POST "$BASE/farmers/{id}/debit" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"amount":40,"narration":"Input purchase"}'{
"id": "a83b…",
"object": "transaction",
"type": "debit",
"direction": "D",
"amount": 40,
"currency": "GHS",
"status": "success",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}/transfersTransfer
Farmer to farmer, within your organization.
curl -X POST "$BASE/transfers" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"from_farmer_id":"6f1c…","to_farmer_id":"9e0a…","amount":25,"narration":"Shared transport"}'{
"id": "a83b…",
"object": "transaction",
"type": "transfer_out",
"direction": "D",
"amount": 25,
"currency": "GHS",
"status": "success",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}/farmers/{id}/deposits/momoDeposit from mobile money
Farmer approves a prompt on their phone. Returns pending; you get a webhook when it settles.
network*— MTN | TELECEL | AT
curl -X POST "$BASE/farmers/{id}/deposits/momo" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"momo_number":"0241234567","network":"MTN","amount":100}'{
"id": "a83b…",
"object": "transaction",
"type": "momo_deposit",
"direction": "C",
"amount": 150,
"currency": "GHS",
"status": "pending",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}/farmers/{id}/withdrawals/momoWithdraw to mobile money
Funds are reserved immediately and refunded automatically if the payout fails.
curl -X POST "$BASE/farmers/{id}/withdrawals/momo" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"momo_number":"0241234567","network":"MTN","amount":50}'{
"id": "a83b…",
"object": "transaction",
"type": "momo_withdrawal",
"direction": "D",
"amount": 150,
"currency": "GHS",
"status": "pending",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}/farmers/{id}/withdrawals/bankWithdraw to a bank
Instant transfer (GIP) to any Ghana bank. Verify the account first.
curl -X POST "$BASE/farmers/{id}/withdrawals/bank" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"bank_code":"300304","account_number":"1234567890123","account_name":"Ama Owusu","amount":200}'{
"id": "a83b…",
"object": "transaction",
"type": "bank_withdrawal",
"direction": "D",
"amount": 150,
"currency": "GHS",
"status": "pending",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}/transactions/{id}Get a transaction
Also re-checks status with the bank if still pending.
curl -X GET "$BASE/transactions/{id}" \
-H "Authorization: Bearer $FFSP_KEY"{
"id": "a83b…",
"object": "transaction",
"type": "credit",
"direction": "C",
"amount": 150,
"currency": "GHS",
"status": "success",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}/transactions?status=pendingList transactions
curl -X GET "$BASE/transactions?status=pending" \ -H "Authorization: Bearer $FFSP_KEY"
{
"object": "list",
"data": [
{
"id": "a83b…",
"object": "transaction",
"type": "credit",
"direction": "C",
"amount": 150,
"currency": "GHS",
"status": "success",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}
]
}Loans
/loansIssue a loan
Disburses the principal from your wallet into the farmer's account. Interest is flat.
curl -X POST "$BASE/loans" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"farmer_id":"6f1c…","principal":500,"interest_rate":10,"term_months":6,"purpose":"Fertilizer"}'{
"id": "c11d…",
"object": "loan",
"farmer_id": "6f1c…",
"principal": 500,
"interest_rate": 10,
"term_months": 6,
"total_due": 550,
"amount_repaid": 0,
"outstanding": 550,
"status": "active",
"due_date": "2027-04-13"
}/loans/{id}Get a loan
curl -X GET "$BASE/loans/{id}" \
-H "Authorization: Bearer $FFSP_KEY"{
"id": "c11d…",
"object": "loan",
"farmer_id": "6f1c…",
"principal": 500,
"interest_rate": 10,
"term_months": 6,
"total_due": 550,
"amount_repaid": 0,
"outstanding": 550,
"status": "active",
"due_date": "2027-04-13"
}/loans/{id}/repaymentsRecord a repayment
Debits the farmer's savings into your wallet. Loan closes when fully repaid.
curl -X POST "$BASE/loans/{id}/repayments" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"amount":100}'{
"loan": {
"id": "c11d…",
"object": "loan",
"farmer_id": "6f1c…",
"principal": 500,
"interest_rate": 10,
"term_months": 6,
"total_due": 550,
"amount_repaid": 100,
"outstanding": 450,
"status": "active",
"due_date": "2027-04-13"
},
"transaction": {
"id": "a83b…",
"object": "transaction",
"type": "loan_repayment",
"direction": "D",
"amount": 100,
"currency": "GHS",
"status": "success",
"reference": "FFSP-M2K…",
"farmer_id": "6f1c…"
}
}Organization & banks
/organization/walletWallet balance
Your organization's float that funds credits and loans.
curl -X GET "$BASE/organization/wallet" \ -H "Authorization: Bearer $FFSP_KEY"
{
"object": "wallet",
"account_number": "DOS0200000001",
"balance": 9850,
"currency": "GHS"
}/organization/wallet/fundFund wallet from MoMo
curl -X POST "$BASE/organization/wallet/fund" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"momo_number":"0241234567","network":"MTN","amount":1000}'{
"id": "a83b…",
"object": "transaction",
"type": "wallet_funding",
"direction": "C",
"amount": 150,
"currency": "GHS",
"status": "pending",
"reference": "FFSP-M2K…",
"farmer_id": null
}/banksList banks
Bank codes for withdrawals.
curl -X GET "$BASE/banks" \ -H "Authorization: Bearer $FFSP_KEY"
{
"object": "list",
"data": [
{
"code": "300304",
"name": "GCB Bank"
}
]
}/accounts/verifyVerify account name
curl -X POST "$BASE/accounts/verify" \
-H "Authorization: Bearer $FFSP_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"account_number":"1234567890123","bank_code":"300304"}'{
"account_number": "1234567890123",
"bank_code": "300304",
"account_name": "AMA OWUSU"
}