Soft delete, no confirmation; the client offers Undo (TXN-4)
Required scope: `transactions:write` (personal access tokens; sessions have every scope).
Required scope: transactions:write (personal access tokens; sessions have every scope).
Authorization
bearerAuth Authorization: Bearer <token>: a mobile session token, or a personal access token
(srp_…) created in Account → API tokens (DEV-1).
Personal access tokens:
- Act as their user. The household comes from
X-SpendRock-Household, else the user's default. - Carry scopes (DEV-2), and each operation's description names the one it needs:
budget:read/budget:write(months, groups, items, funds, favorites, harvest),transactions:read/transactions:write(transactions, merchant suggestions),households:read/households:manage(households, members, invites),account:read/account:write(me, settings). A write scope includes its read scope. A call outside the token's scopes gets 403insufficient_scope, with the needed scope indetails.required_scope. - Can't manage tokens or passwords (403
session_required). - May expire (401
unauthenticatedafterwards). - Are rate-limited (DEV-3): 120 requests/minute per token with bursts up to 120. Every
response carries
X-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Reset(seconds until the bucket is full again); over the limit the answer is 429rate_limitedwithRetry-After(seconds). Limits are kept per server instance, so they're approximate.
Sessions (web cookie or mobile bearer) have every scope and aren't limited this way. Cross-origin browser calls (CORS, for the API docs playground) must use a bearer token; cookies are never accepted cross-origin.
In: header
Path Parameters
ULID.
^[0-9A-HJKMNP-TV-Z]{26}$Header Parameters
The household to act on (HH-12). Defaults to the user's default household. 403 not_a_member if the caller isn't a current member (HH-16).
^[0-9A-HJKMNP-TV-Z]{26}$Response Body
application/json
application/json
application/json
application/json
curl -X DELETE "https://example.com/transactions/01J8Z3N4Q5R6S7T8V9W0X1Y2Z3"{ "transaction": { "id": "01J8Z3N4Q5R6S7T8V9W0X1Y2Z3", "type": "expense", "amount": 1234, "date": "2019-08-24", "merchant": "string", "note": "string", "budget_month": "2026-12", "splits": [ { "item_id": "01J8Z3N4Q5R6S7T8V9W0X1Y2Z3", "amount": 1234, "item_name": "string" } ], "status": "tracked", "deleted_at": "2019-08-24T14:15:22Z", "location": { "lat": -90, "lng": -180, "accuracy_m": 0 }, "created_by": "string", "created_by_name": "string", "updated_by": "string", "updated_by_name": "string", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z" }, "months": [ { "month": "2026-12", "left_to_budget": 1234, "groups": [ { "id": "01J8Z3N4Q5R6S7T8V9W0X1Y2Z3", "name": "string", "color": "string", "is_income": true, "items": [ { "id": "01J8Z3N4Q5R6S7T8V9W0X1Y2Z3", "name": "string", "kind": "income", "is_fund": true, "favorite": true, "fund_target": 0, "group_id": "01J8Z3N4Q5R6S7T8V9W0X1Y2Z3", "planned": 1234, "spent": 1234, "received": 1234, "remaining": 1234, "note": "string", "fund": { "carry_in": 1234, "adjustments": [ { "amount": 1234, "at": "2019-08-24T14:15:22Z", "by": "string" } ], "ending": 1234 } } ], "totals": { "planned": 1234, "spent": 1234, "received": 1234, "remaining": 1234 } } ], "favorites": [ "01J8Z3N4Q5R6S7T8V9W0X1Y2Z3" ], "center": { "planned": 1234, "spent": 1234, "remaining": 1234 }, "untracked_count": 0, "copied_from": "2026-12", "created_at": "2019-08-24T14:15:22Z" } ], "untracked_count": 0}Edit amount/date/merchant/note/type/splits/budget month, untrack (empty splits), or remove the location (TXN-3, TXN-4, TXN-5) PATCH
Required scope: `transactions:write` (personal access tokens; sessions have every scope).
Restore with original tracking; splits whose item no longer exists in that month are dropped (TXN-4a) POST
Required scope: `transactions:write` (personal access tokens; sessions have every scope).