Developer-facing reference for the VaultQuest backend REST API. Covers pool actions, dashboard summary, saved-pools watchlist, and activity export. Frontend contributors can build UI integrations against these shapes without reading the backend source.
All responses use application/json unless noted. Successful responses wrap
data in { "data": ... }. Paginated responses include a meta.pagination
block. Errors return { "error": { "code": "...", "message": "..." } }.
There is no session-based auth. Wallet-scoped endpoints accept the connected wallet address as a query parameter. The frontend is responsible for passing the user's own address — the API trusts this parameter.
Create a new wallet action intent.
Headers
| Header | Required | Description |
|---|---|---|
Idempotency-Key |
Yes | UUID v4. Reusing the same key with the same payload is a safe no-op (returns 200). Reusing with a different payload returns 409. |
Request body
{
"wallet_address": "GABCDEF1234567890",
"action_type": "deposit",
"action_payload": {
"vault_id": "42",
"amount": "1000000",
"token": "USDC"
}
}| Field | Type | Values |
|---|---|---|
wallet_address |
string | Stellar wallet address (max 120 chars) |
action_type |
enum | deposit withdraw create_vault claim select_winner |
action_payload |
object | Arbitrary JSON; shape depends on action_type |
Response — 201 Created (new action) or 200 OK (idempotent replay)
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"idempotency_key": "a4e8b0c2-...",
"wallet_address": "GABCDEF1234567890",
"action_type": "deposit",
"action_payload": { "vault_id": "42", "amount": "1000000", "token": "USDC" },
"status": "pending",
"tx_hash": null,
"soroban_event_id": null,
"correlation_id": "...",
"error_code": null,
"error_detail": null,
"retry_count": 0,
"created_at": "2025-05-29T12:00:00.000Z",
"updated_at": "2025-05-29T12:00:00.000Z",
"submitted_at": null,
"confirmed_at": null,
"redacted_at": null
}
}List actions for a wallet, newest first.
Query parameters
| Param | Required | Default | Description |
|---|---|---|---|
wallet |
Yes | — | Wallet address |
status |
No | — | Filter: pending submitted confirmed failed reverted orphaned |
cursor |
No | — | UUID of the last item from the previous page |
limit |
No | 25 | Items per page (1–100) |
Response — 200 OK
{
"data": [ /* array of action objects */ ],
"meta": {
"pagination": {
"next_cursor": "550e8400-...",
"limit": 25,
"has_more": true
}
}
}Get a single action by ID.
Response — 200 OK — action object (same shape as POST response)
Response — 404 Not Found
{ "error": { "code": "NOT_FOUND", "message": "action <id> not found" } }Attach a transaction hash after the wallet has broadcast to the network.
Advances status from pending → submitted.
Request body
{ "tx_hash": "abc123..." }Response — 200 OK — updated action object
Cancel a pending action (e.g. user rejected the wallet prompt).
Advances status from pending → failed.
Request body
{
"error_code": "WALLET_REJECTED",
"error_detail": "User dismissed the wallet popup"
}error_code values |
Meaning |
|---|---|
WALLET_REJECTED |
User explicitly rejected the signing request |
WALLET_TIMEOUT |
Signing timed out with no response |
NETWORK_ERROR |
Could not reach the RPC endpoint |
Response — 200 OK — updated action object
Scrub all personal data for a wallet (GDPR / right-to-erasure). Sets
action_payload to null and stamps redacted_at on all rows.
Scrubbed rows are excluded from future export responses.
Response — 200 OK
{ "data": { "scrubbed": 12 } }Export the wallet's full activity history as JSON or CSV.
Query parameters
| Param | Required | Default | Description |
|---|---|---|---|
wallet |
Yes | — | Wallet address |
format |
No | json |
json or csv |
from |
No | — | ISO 8601 datetime — return actions created at or after this time |
to |
No | — | ISO 8601 datetime — return actions created at or before this time |
limit |
No | 500 | Max rows returned (1–1000) |
Response — 200 OK (JSON format)
{
"data": [
{
"id": "550e8400-...",
"wallet_address": "GABCDEF1234567890",
"action_type": "deposit",
"action_payload": { "vault_id": "42", "amount": "1000000", "token": "USDC" },
"status": "confirmed",
"tx_hash": "abc123...",
"error_code": null,
"created_at": "2025-05-29T12:00:00.000Z",
"submitted_at": "2025-05-29T12:00:05.000Z",
"confirmed_at": "2025-05-29T12:00:30.000Z"
}
]
}Response — 200 OK (CSV format)
Returns Content-Type: text/csv with Content-Disposition: attachment; filename="vaultquest-activity-<wallet-prefix>.csv".
"id","date","action_type","pool_id","amount","token","status","tx_hash","error_code","submitted_at","confirmed_at"
"550e8400-...","2025-05-29T12:00:00.000Z","deposit","42","1000000","USDC","confirmed","abc123...","","2025-05-29T12:00:05.000Z","2025-05-29T12:00:30.000Z"
Notes
- Scrubbed rows (
redacted_at != null) are never included in export output. - Large histories: use
from/todate ranges to paginate manually. Thelimitcap is 1 000 rows per request. - Wallet-scoping: the export only returns data for the
walletparameter value. Never returns another user's data.
Aggregated dashboard rollup for a wallet. Provides per-status action counts, in-flight tx hashes the wallet should keep polling, and a freshness flag.
Query parameters
| Param | Required | Default | Description |
|---|---|---|---|
wallet |
Yes | — | Wallet address |
stale_after_ms |
No | 300 000 (5 min) | If the most recent ledger update is older than this, is_stale is true |
Response — 200 OK
{
"data": {
"wallet_address": "GABCDEF1234567890",
"total_actions": 14,
"by_status": {
"pending": 0,
"submitted": 1,
"confirmed": 11,
"failed": 1,
"reverted": 1,
"orphaned": 0
},
"pending_tx_hashes": ["abc123..."],
"is_stale": false,
"latest_activity_at": "2025-05-29T12:00:00.000Z",
"latest_confirmed_at": "2025-05-29T11:55:00.000Z"
}
}Return the saved pools for a wallet, newest first.
Query parameters
| Param | Required | Default | Description |
|---|---|---|---|
wallet |
Yes | — | Wallet address |
Response — 200 OK
{
"data": [
{
"id": "550e8400-...",
"wallet_address": "GABCDEF1234567890",
"pool_id": "pool-42",
"pool_name": "Weekly USDC",
"status": "open",
"tvl": "12500.5",
"asset": "USDC",
"participant_count": 24,
"expected_yield": "5.2% APY",
"prize": "50 USDC",
"opens_at": "2026-05-29T12:00:00.000Z",
"locks_at": "2026-06-05T12:00:00.000Z",
"draws_at": "2026-06-12T12:00:00.000Z",
"created_at": "2026-05-29T12:00:00.000Z",
"updated_at": "2026-05-29T12:00:00.000Z"
}
]
}Create or update a saved pool entry for a wallet. Reusing the same wallet and pool ID updates the stored summary instead of creating duplicates.
Request body
{
"wallet_address": "GABCDEF1234567890",
"pool": {
"pool_id": "pool-42",
"pool_name": "Weekly USDC",
"status": "open",
"tvl": "12500.5",
"asset": "USDC",
"participant_count": 24,
"expected_yield": "5.2% APY",
"prize": "50 USDC",
"opens_at": "2026-05-29T12:00:00.000Z",
"locks_at": "2026-06-05T12:00:00.000Z",
"draws_at": "2026-06-12T12:00:00.000Z"
}
}Response — 201 Created for a new saved pool, or 200 OK when updating an existing entry
{
"data": {
"saved": {
"id": "550e8400-...",
"wallet_address": "GABCDEF1234567890",
"pool_id": "pool-42",
"pool_name": "Weekly USDC",
"status": "open",
"tvl": "12500.5",
"asset": "USDC",
"participant_count": 24,
"expected_yield": "5.2% APY",
"prize": "50 USDC",
"opens_at": "2026-05-29T12:00:00.000Z",
"locks_at": "2026-06-05T12:00:00.000Z",
"draws_at": "2026-06-12T12:00:00.000Z",
"created_at": "2026-05-29T12:00:00.000Z",
"updated_at": "2026-05-29T12:00:00.000Z"
}
}
}Remove a saved pool entry for the wallet supplied in the query string.
Query parameters
| Param | Required | Default | Description |
|---|---|---|---|
wallet |
Yes | — | Wallet address |
Response — 200 OK
{ "data": { "deleted": 1 } }| Code | HTTP | Meaning |
|---|---|---|
NOT_FOUND |
404 | Resource does not exist |
INVALID_PAYLOAD |
400 | Request body or query params failed validation |
ILLEGAL_TRANSITION |
409 | Status transition is not allowed (e.g. cancel a confirmed action) |
IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOAD |
409 | Same Idempotency-Key used with a different body |
TX_HASH_ALREADY_ATTACHED |
409 | tx_hash is already owned by another action |
UNAUTHORIZED |
401 | Request lacks required credentials (internal endpoints) |
pending ──► submitted ──► confirmed
│ └──────► reverted
└──────────────────────► failed
submitted ────────────────► orphaned
Terminal states (no further transitions): confirmed, failed, reverted, orphaned.
action_type |
Payload fields |
|---|---|
deposit |
vault_id, amount, token |
withdraw |
vault_id, amount, token |
create_vault |
vault_id, amount, token |
claim |
vault_id |
select_winner |
vault_id |
The action_payload is stored verbatim and surfaced as-is in responses and
exports. Consumers should treat unknown fields as additive and not error on them.