Read Your Expenses

List the expenses recorded for your business, filter them by status or date, and fetch a single expense by its id.

Expenses are recorded in Duplo Dashboard by the people who submit and approve them. The API provides a way for your systems to read those same records back, so you can reconcile them against your own ledger or pull them into a report. It is read-only, and nothing here creates or changes an expense.

This guide assumes you already have an API key and can authenticate. If not, start with Getting Started.

Listing expenses

The Fetch expenses endpoint returns one page of your business's expenses.

curl --request GET \
  --url 'https://dashboard.tryduplo.com/api/expenses?page=1&limit=20&status=approved' \
  --header 'Authorization: Bearer <your-api-key>'

Every filter is optional. Send none of them and you get the first page of everything.

ParameterAcceptsNotes
pageA number, for example 1Which page to return
limitA number, for example 20How many expenses per page
startDateAn ISO 8601 timestampOnly expenses dated on or after this
endDateAn ISO 8601 timestampOnly expenses dated on or before this
statuspending, approved, rejected, saved, N/AOnly expenses in that state

As with every response on this API, the payload arrives under data in the standard envelope. The sample below shows only that payload, which carries the page of expenses in its own data array and the pagination counters in meta:

JSON
{
  "data": [
    {
      "id": "98d34e0c-69dc-4683-9bbe-6e6921ed155c",
      "businessId": "0f6b2a52-3f0b-4d1e-9a6f-1f9b6c3d5e88",
      "amount": 125000,
      "currency": "NGN",
      "description": "Team offsite venue",
      "status": "approved",
      "date": "2026-01-14T00:00:00.000Z",
      "claimReimbursement": false,
      "receipt": ["https://files.tryduplo.com/receipts/98d34e0c.pdf"],
      "payoutId": "3b1c9d77-2a44-4f2e-8c31-77bb1f0a9d21",
      "expenseCategory": { "name": "Travel" },
      "department": { "name": "Engineering" },
      "recipient": { "accountName": "Lagos Venues Limited" },
      "createdAt": "2026-01-15T09:22:11.004Z"
    }
  ],
  "meta": {
    "total": 143,
    "page": 1,
    "limit": 20,
    "count": 20,
    "previousPage": null,
    "nextPage": 2,
    "pageCount": 8,
    "totalRecords": 143
  }
}

To walk the whole set, keep requesting the page in meta.nextPage until there is no next page.

An expense that has already been paid out carries that payout's id in payoutId. Pass it to Get a payout to see how the money actually left, including the destination account. See Read your payouts.

Fetching one expense

When you already have an id, Get an expense by id returns that single record in the same shape as one entry in the list.

curl --request GET \
  --url https://dashboard.tryduplo.com/api/expenses/98d34e0c-69dc-4683-9bbe-6e6921ed155c \
  --header 'Authorization: Bearer <your-api-key>'

Ids are scoped to your business. An id belonging to another business returns 404 with Expense not found for this business, the same as an id that does not exist at all.

How is this guide?

Last updated on

On this page