list_transactions
Read the user's transaction history exactly as the Envoy app shows it, newest first, with an opaque pagination cursor.
POST https://api.envoy.money/tools/list_transactions
Read the user's transaction history exactly as the Envoy app shows it, newest first, with an opaque pagination cursor. from must not be later than to.
| Title | Service | Read only | Destructive | Idempotent | External sites |
|---|---|---|---|---|---|
| List transactions | shared | true | false | true | false |
Send a Central Auth bearer with agent scope. A key-bound connection also sends Envoy-Installation-Proof over this exact request. JSON bodies are limited to 64 KB; a larger body returns HTTP 413 with INVALID_INPUT.
Input
| Field | Required | Type | Description and rules |
|---|---|---|---|
from | No | string | Start date. format date |
to | No | string | End date. format date |
limit | No | integer | Maximum transactions. minimum 1; maximum 50 |
cursor | No | string | Opaque pagination cursor bound to this connection, date range and page size. minLength 1; maxLength 2048 |
Unknown fields are rejected. The exact input schema is on the schemas page.
Synthetic request
{
"limit": 10
}Success data
Every reply uses the shared envelope: ok, the purchase, next, user_action and error. Follow next; outputs may gain fields, so ignore ones you do not recognize.
This tool returns its payload in data:
Field in data | Required | Type | Description and rules |
|---|---|---|---|
transactions | Yes | array of object | — |
transactions[].id | Yes | string | Opaque statement line identifier, stable for this connection and client. It contains no card binding and grants no access. minLength 1; maxLength 128 |
transactions[].occurred_at | Yes | string | When it happened. format date-time |
transactions[].amount | Yes | object | — |
transactions[].direction | Yes | "debit" | "credit" | "none" | debit: money left the account. credit: money came back or was added. none: no money moved, e.g. a declined payment. |
transactions[].title | Yes | string | What the user sees as the line's name: the merchant for a purchase. minLength 1; maxLength 200 |
transactions[].subtitle | Yes | string or null | The line's second row in the app. For an agent purchase, the agent's name. maxLength 200 |
transactions[].by_agent | Yes | boolean | True when an agent made this purchase through Envoy. |
transactions[].kind | Yes | "purchase" | "reversal" | "refund" | "load" | "withdraw" | "fee" | "decline" | "card_issued" | "card_funded" | "card_closed" | "adjustment" | "other" | What happened. other: a kind this version does not name. |
transactions[].status | Yes | "completed" | "pending" | "failed" | "unknown" | completed: done. pending: still in progress (the app shows "In progress"). failed: did not complete (the app shows "Didn't complete"). |
transactions[].card | Yes | "envoy" | "elixir_card" | "unknown" | Which card it was on. elixir_card: the user's Elixir card, badged "Elixir card" in the app. |
next_cursor | Yes | string or null | Opaque next cursor. |
Synthetic result
Example synthetic-compatible-payload (synthetic data):
{
"ok": true,
"contract": "envoy@2026-10",
"tool": "list_transactions",
"request_id": "req_synthetic",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"server_time": "2026-09-29T12:00:00Z",
"replayed": false,
"purchase": null,
"data": {
"transactions": [
{
"id": "synthetic-line",
"occurred_at": "2026-09-29T11:00:00Z",
"amount": {
"minor": 10000,
"currency": "INR",
"display": "₹100.00"
},
"direction": "debit",
"title": "Example Store",
"subtitle": "Example Agent",
"by_agent": true,
"kind": "purchase",
"status": "completed",
"card": "envoy"
}
],
"next_cursor": null
},
"next": {
"action": "continue",
"tool": null,
"args": null,
"instruction": "Envoy needs nothing more. Carry on with the user's task.",
"after_seconds": null,
"by": null
},
"user_action": null,
"follow_ups": [],
"error": null
}Errors
A failure has ok: false, changes nothing, and carries error plus one next. Branch on error.code and next, not on the HTTP status. The contract declares every code below for every tool; which one a call returns depends on the request and the purchase state.
| Code | HTTP status | Meaning | What the agent does |
|---|---|---|---|
INVALID_INPUT | 400 | Fix the supplied input. | Fix every field listed in error.fields, then call the same tool once more. |
UNAUTHENTICATED | 401 | Reconnect through Central Auth. | Ask the user to reconnect Envoy, then retry this call. |
NOT_ALLOWED | 403 | The operation is not allowed. | This connection may not do that. Tell the user; do not retry. |
SERVICE_NOT_ENABLED | 403 | The service is not enabled. | This Envoy service is not enabled for the user. Tell the user; do not retry. |
NOT_FOUND | 404 | Purchase absent or owned by another user. | No purchase matches that reference. Check the purchase id from this task; do not start a new purchase to recover. |
IDEMPOTENCY_CONFLICT | 409 | The same key has different input. | Retry with the original inputs unchanged, or use a new idempotency_key only for a genuinely new purchase. |
ACTIVE_PURCHASE_EXISTS | 409 | An active purchase already exists. | Another purchase is in progress. Show the user the user_action message and stop this attempt. |
STATE_CONFLICT | 409 | The operation conflicts with the current state. | This conflicts with the current state. Tell the user; do not retry. |
NO_RAIL | 422 | No rail can serve this purchase; nothing was created. | Envoy cannot pay this purchase. Tell the user why using error.message; do not retry or split it. |
RATE_LIMITED | 429 | Wait before retrying. | Wait next.after_seconds, then retry the same call unchanged. |
UNAVAILABLE | 503 | The service is unavailable; follow retryable and next. | Wait next.after_seconds, then retry the same call unchanged; never pay elsewhere meanwhile. |
CLIENT_UPDATE_REQUIRED | 426 | Update the client. | This client is too old. Tell the user to update it. |