Octopus Cards

Transactions

List transactions or retrieve a single transaction by ID

GET /api/v1/transactions

Returns a paginated list of all transactions across your wallets. Supports filtering by type, wallet, date range, amount range, and free-text search.

Request

curl "{{host}}/api/v1/transactions?page=1&limit=25&transaction_type=DEBIT" \
  -H "Authorization: Bearer <token>"
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

type Transaction struct {
    ID                  int      `json:"id"`
    WalletID            int      `json:"wallet_id"`
    CurrencyID          int      `json:"currency_id"`
    Amount              float64  `json:"amount"`
    TransactionType     string   `json:"transaction_type"`
    Status              string   `json:"status"`
    SourceCurrency      *string  `json:"source_currency"`
    DestinationCurrency *string  `json:"destination_currency"`
    ForexRate           *float64 `json:"forex_rate"`
    ConversionCharges   *float64 `json:"conversion_charges"`
    Remarks             string   `json:"remarks"`
    CreatedAt           string   `json:"created_at"`
}

func main() {
    req, _ := http.NewRequest("GET", "{{host}}/api/v1/transactions?limit=25", nil)
    req.Header.Set("Authorization", "Bearer <token>")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    // Read pagination from headers
    fmt.Println("Total:", resp.Header.Get("X-Total-Count"))
    fmt.Println("Page:", resp.Header.Get("X-Page"))

    var txns []Transaction
    json.NewDecoder(resp.Body).Decode(&txns)

    for _, t := range txns {
        fmt.Printf("[%s] %s %.2f%s\n", t.Status, t.TransactionType, t.Amount, t.Remarks)
    }
}

Query Parameters

KeyTypeDefaultDescription
pageinteger1Page number (1-based)
limitinteger50Items per page (1–10,000)
transaction_typestringFilter by type: CREDIT or DEBIT
statusstringFilter by status: PENDING, COMPLETED, or FAILED
wallet_idintegerFilter by wallet ID
currency_idintegerFilter by currency ID
start_datestringStart of date range (RFC 3339)
end_datestringEnd of date range (RFC 3339)
min_amountnumberMinimum transaction amount
max_amountnumberMaximum transaction amount
searchstringSearch in remarks (case-insensitive)

Response

[
  {
    "id": 456,
    "wallet_id": 1,
    "currency_id": 1,
    "amount": 50.00,
    "transaction_type": "DEBIT",
    "status": "COMPLETED",
    "source_currency": null,
    "destination_currency": null,
    "forex_rate": null,
    "conversion_charges": null,
    "remarks": "USD Wallet debited by amount 50.00 - Order #12345",
    "created_at": "2025-01-15T14:30:00Z"
  },
  {
    "id": 455,
    "wallet_id": 1,
    "currency_id": 1,
    "amount": 1000.00,
    "transaction_type": "CREDIT",
    "status": "COMPLETED",
    "source_currency": "EUR",
    "destination_currency": "USD",
    "forex_rate": 1.0850,
    "conversion_charges": 2.50,
    "remarks": "FX conversion from EUR wallet",
    "created_at": "2025-01-15T10:00:00Z"
  }
]

Response Headers

HeaderDescription
X-PageCurrent page number
X-Per-PageItems per page
X-Total-CountTotal matching transactions
X-Total-PagesTotal pages
X-Page-SizeItems in current page
X-Has-Moretrue if more pages exist

Response Fields

KeyTypeDescription
idintegerUnique transaction identifier
wallet_idintegerWallet this transaction belongs to
currency_idintegerCurrency of the transaction
amountnumberTransaction amount (always positive — direction is indicated by transaction_type)
transaction_typestringCREDIT (money in) or DEBIT (money out)
statusstringPENDING, COMPLETED, or FAILED
source_currencystring or nullSource currency code for FX conversions (e.g. EUR)
destination_currencystring or nullDestination currency code for FX conversions (e.g. USD)
forex_ratenumber or nullExchange rate applied, if FX conversion
conversion_chargesnumber or nullFee charged for FX conversion
remarksstringHuman-readable description of the transaction
created_atstringISO 8601 / RFC 3339 timestamp

Enumerations

transaction_type

ValueDescription
CREDITFunds added to wallet (top-up, refund, FX conversion in)
DEBITFunds removed from wallet (order settlement, adjustment, FX conversion out)

status

ValueDescription
PENDINGTransaction awaiting processing
COMPLETEDTransaction settled, balance updated
FAILEDTransaction did not complete, balance unchanged

Errors

400 Bad Request — Invalid filter value (e.g. invalid transaction type).

{
  "error": {
    "name": "BadRequestError",
    "code": "BAD_REQUEST",
    "message": "Invalid transaction type. Must be CREDIT or DEBIT"
  }
}

401 Unauthorized — Missing or invalid JWT token.

{
  "error": {
    "name": "UnauthorizedError",
    "code": "UNAUTHORIZED",
    "message": "Authorization header required"
  }
}

403 Forbidden — Request IP not in whitelist.

{
  "error": {
    "name": "ForbiddenError",
    "code": "FORBIDDEN",
    "message": "IP address not authorized"
  }
}

500 Internal Server Error — Database query failed.

{
  "error": {
    "name": "InternalServerError",
    "code": "INTERNAL_SERVER_ERROR",
    "message": "Failed to retrieve transactions"
  }
}

GET /api/v1/transactions/:id

Returns a single transaction by its ID. The transaction must belong to your client account.

Request

curl "{{host}}/api/v1/transactions/456" \
  -H "Authorization: Bearer <token>"
req, _ := http.NewRequest("GET", "{{host}}/api/v1/transactions/456", nil)
req.Header.Set("Authorization", "Bearer <token>")

resp, err := http.DefaultClient.Do(req)
if err != nil {
    panic(err)
}
defer resp.Body.Close()

var txn Transaction
json.NewDecoder(resp.Body).Decode(&txn)

fmt.Printf("[%s] %s %.2f%s\n", txn.Status, txn.TransactionType, txn.Amount, txn.Remarks)

Request Parameters

KeyTypeRequiredDescription
idintegerYesTransaction ID (path parameter). Must be between 1 and 2,147,483,647.

Response

{
  "id": 456,
  "wallet_id": 1,
  "currency_id": 1,
  "amount": 50.00,
  "transaction_type": "DEBIT",
  "status": "COMPLETED",
  "source_currency": null,
  "destination_currency": null,
  "forex_rate": null,
  "conversion_charges": null,
  "remarks": "USD Wallet debited by amount 50.00 - Order #12345",
  "created_at": "2025-01-15T14:30:00Z"
}

Response fields are identical to the list endpoint above.

Errors

400 Bad Request — ID is not a valid integer or out of range.

{
  "error": {
    "name": "BadRequestError",
    "code": "BAD_REQUEST",
    "message": "Invalid transaction ID"
  }
}

404 Not Found — No transaction exists with this ID, or it does not belong to your client.

{
  "error": {
    "name": "NotFoundError",
    "code": "NOT_FOUND",
    "message": "Transaction not found"
  }
}

401 Unauthorized — Missing or invalid JWT token.

{
  "error": {
    "name": "UnauthorizedError",
    "code": "UNAUTHORIZED",
    "message": "Authorization header required"
  }
}

403 Forbidden — Request IP not in whitelist.

{
  "error": {
    "name": "ForbiddenError",
    "code": "FORBIDDEN",
    "message": "IP address not authorized"
  }
}

On this page