API Customers
Read the customer rollup Seev derives from your API transactions, and understand what its totals do and do not count.
API Customers is a read-only view built by grouping the transactions in Developer Transactions. Nothing is stored separately, so there is no customer record here to create, edit, or delete. To manage the customers you save for invoices and payment links, use the Dashboard Customers guide.
Read the rollup
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Customer name taken from the transaction metadata. Empty when your integration sent none. |
email | string | No | Email from the transaction metadata, lowercased when used as the grouping key. |
phone | string | No | Phone number from the transaction metadata. |
customerId | string | No | Your own customer identifier, read from the customerId or customer_id key of the meta object you sent at checkout. |
recipientId | string | No | Your own recipient identifier, read from recipientId or recipient_id in the same meta object. |
transactionCount | number | Yes | Count of grouped transactions, in every status. |
totalAmount | number | Yes | Sum of the grouped transaction amounts in the currency's major unit, since transaction amounts are stored as the smallest-unit Checkout API value divided by 100. |
currency | string | No | Currency of the most recently created transaction in the group, not of the total. |
lastStatus | string | No | Status of the most recently created transaction: pending, completed, failed, or cancelled. |
lastReference | string | No | Payment reference of that same transaction. Open it in Developer Transactions for the full detail. |
lastTransactionAt | string | Yes | Creation time of the most recent transaction. Rows are sorted by this, newest first. |
Sandbox and production rollups are separate and are marked as such. Changing the developer environment reloads the list, so check the environment badge before you quote a total anywhere.
Send an identifier so the grouping works
Transactions are grouped by the first of these that your integration provided, in order: email, then customerId, then recipientId. If none is present, Seev falls back to the transaction's own gateway session reference or payment reference, which is unique per payment. That means every anonymous payment becomes its own single-transaction row.
To keep one customer as one row, send a stable identifier in the meta object when you create the checkout session:
{
"type": "checkout",
"recipient": { "name": "Kwame Asante", "email": "kwame@example.com" },
"amount": 10000,
"currency": "GHS",
"redirect_url": "https://yourapp.com/payment/callback",
"meta": {
"orderId": "order_123",
"customerId": "cus_4821"
}
}amount is in the currency's smallest unit, so 10000 means GHS 100.00. The full request body is documented in Checkout API.
Interpret the totals carefully
The rollup is a convenience view built from whatever your integration sent. Four behaviours will surprise you if you treat it as a ledger.
| Behaviour | Cause | What to do |
|---|---|---|
| The same person appears several times | Different payments carried different identifiers, or some carried none and fell back to a per-payment reference. | Send the same customerId or the same email on every checkout for that customer. Existing rows are not merged retroactively. |
totalAmount is larger than what you were paid | Every transaction is counted regardless of status, so pending, failed, and cancelled amounts are in the sum. | Use Developer Transactions filtered to completed for anything financial. Treat this total as activity volume. |
totalAmount mixes currencies | Amounts are summed across the group while currency reports only the most recent transaction's currency. | For a customer who paid in more than one currency, read the per-transaction rows instead. |
lastStatus looks stale | The row tracks the most recently created transaction, not the most recently updated one. A newer session that is still pending outranks an older one that completed a moment ago. | Open lastReference in Developer Transactions and read the status there. |
Fill in missing customer details
A row with no name, email, or phone means the checkout session was created without them. Seev shows the strongest identifier it has rather than an empty row, which keeps the record inspectable.
Sandbox sessions often lack contact details, and that is expected. If production rows are missing details you thought you were sending, check the recipient object and the meta keys in your create-session request against the key names listed in the table above, since a key spelled differently is read as absent. Do not guess an identity into your own records from a rollup row.