Delete a bank statement
DELETE/api/v1/bank_statements/:id
Deletes the statement and its stored file. Allowed only BEFORE commit, and committed is where that boundary sits - NOT reconciliation. committed turns true as soon as the extraction persists operations - the LINES, which land before operations_count is written - so read it before calling: a statement reporting committed: true is refused whatever its state. In practice this endpoint cancels an import that produced nothing - a statement still at committed: false, in any state. An archived statement is refused too. The body is the statement as it stood when you asked for it to go - serialized before the delete, because afterwards its file no longer exists to describe.
Request
Responses
- 200
- 401
- 403
- 404
- 409
- 422
The statement was deleted, and is returned as it last stood.
The request carries no bearer token, or one that is invalid or expired. doorkeeper_authorize! is the first gate of the chain, so this is answered before the workspace, the company, the feature flag and the statement are ever resolved - and before any Idempotency-Key is claimed.
The token may not perform this call, and three gates of the shared chain answer it identically: the OAuth SCOPE derived from the HTTP verb (this one needs destroy, with write as the alternative), the workspace GRANT the application holds, and the bank_reconciliation FEATURE FLAG. The action's own Pundit check is a fourth. All four render the same body, so message is what distinguishes them; nothing was performed in any case. The example below is refused on the scope.
No statement with this id is reachable by the token's grants. One belonging to another workspace answers the same way, so the response cannot be used to probe for one. A second KEYLESS delete lands here too - the row is already gone, which is the convergence the header exists to turn into a replayed 200 instead.
You sent the optional Idempotency-Key and a call bearing it is still in flight - idempotency_request_in_progress. Nothing was deleted by THIS call. A DELETE carries no body, so its fingerprint can never differ from the first call's: idempotency_key_reuse is unreachable here, and once the first call completes the same key replays its stored 200 rather than conflicting.
The delete was refused, and details is what tells the two refusals apart.
Without details - the statement may not be deleted, and statement_not_reviewable covers both reasons with message naming which. EITHER the statement is past commit - committed: true, meaning its extraction has already persisted operations - and that one is PERMANENT: the statement will never become deletable, so do not poll and do not retry. Use PATCH /lines to correct it, or leave it in place. OR it is archived, which is equally terminal - an archived file was stored, never extracted. Reconciliation is NOT the boundary: a completed statement carrying extracted lines nobody has reconciled yet is already past commit.
With details - you sent the optional Idempotency-Key and its length is outside the accepted 1-255 characters, which is validation_failed with details.idempotency_key. Nothing was deleted: the key is checked in front of the action.