Docs

Confirm a statement import

POST /api/v1/programmatic/imports/{id}/confirm

POST/api/v1/programmatic/imports/{id}/confirm
Importsv1imports:create

Atomically queues a parsed statement preview for transaction creation.

Parameters

NameInType Description
idpathstringRequired Parsed statement import job identifier. <id>
Idempotency-KeyheaderstringRequired Unique 16–128 character retry key. Reuse it only when retrying the identical confirmation. confirm_20260722_01J2Y8M4R1

Request body

application/json

Confirmation options applied atomically when imported transactions are queued.

{
  "skip_duplicates": true
}

Code examples

curl --request POST \
  --url 'https://api.tetri.app/api/v1/programmatic/imports/<id>/confirm' \
  --header 'Authorization: Bearer $TETRI_API_TOKEN' \
  --header 'Idempotency-Key: confirm_20260722_01J2Y8M4R1' \
  --header 'Content-Type: application/json' \
  --data '{ "skip_duplicates": true }'

Responses

201Import confirmation accepted and transaction creation queued.
{
  "data": {
    "type": "import_jobs",
    "id": "<uuid>",
    "attributes": {
      "bank_key": "revolut",
      "bank_name": "Revolut",
      "file_name": "statement.csv",
      "file_type": "csv",
      "total_rows": 150,
      "imported_count": 148,
      "skipped_count": 1,
      "skipped_existing_count": 1,
      "error_count": 1,
      "status": "completed",
      "preview_version": 3,
      "parse_options": {
        "amount_semantics": "signed_debit_negative",
        "amount_semantics_required": false
      },
      "error_message": "<string>",
      "account_id": "<uuid>",
      "preview": [
        {}
      ],
      "opening_balance_adjusted": [
        {
          "account_id": "<uuid>",
          "account_name": "Main checking",
          "currency_code": "USD",
          "reason": "pre_opening_import_rows",
          "target_balance": "1000.00",
          "balance_as_of_date": "2026-07-12",
          "tetri_balance_before": "950.00",
          "tetri_balance_after": "1000.00",
          "delta": "50.00",
          "old_opening_balance": "100.00",
          "new_opening_balance": "150.00",
          "old_opening_balance_date": "2026-07-12",
          "new_opening_balance_date": "2026-07-12"
        }
      ],
      "reverted_at": "2026-07-12T12:00:00Z",
      "created_at": "2026-07-12T12:00:00Z",
      "updated_at": "2026-07-12T12:00:00Z"
    }
  },
  "side_effects": [
    {
      "domain": "wallets",
      "id": "<string>",
      "action": "upsert",
      "data": {}
    }
  ]
}
400Request parameters or payload failed validation. Inspect `code` and `message`.
{
  "statusCode": 400,
  "code": "PROGRAMMATIC_PAGINATION_MODE_CONFLICT",
  "message": "<string>",
  "error": "Bad Request",
  "request_id": "8cf64dcc-0f73-4f8d-a845-3d80c1040475"
}
401The personal access token is missing, invalid, expired, or revoked.
{
  "statusCode": 400,
  "code": "PROGRAMMATIC_PAGINATION_MODE_CONFLICT",
  "message": "<string>",
  "error": "Bad Request",
  "request_id": "8cf64dcc-0f73-4f8d-a845-3d80c1040475"
}
403The token lacks the required scope or no longer has workspace access.
{
  "statusCode": 400,
  "code": "PROGRAMMATIC_PAGINATION_MODE_CONFLICT",
  "message": "<string>",
  "error": "Bad Request",
  "request_id": "8cf64dcc-0f73-4f8d-a845-3d80c1040475"
}
404The resource does not exist in the token workspace or is not visible to this API.
{
  "statusCode": 400,
  "code": "PROGRAMMATIC_PAGINATION_MODE_CONFLICT",
  "message": "<string>",
  "error": "Bad Request",
  "request_id": "8cf64dcc-0f73-4f8d-a845-3d80c1040475"
}
409The idempotency key was reused with a different request or the resource state conflicts.
{
  "statusCode": 400,
  "code": "PROGRAMMATIC_PAGINATION_MODE_CONFLICT",
  "message": "<string>",
  "error": "Bad Request",
  "request_id": "8cf64dcc-0f73-4f8d-a845-3d80c1040475"
}
429The credential exceeded its request rate limit.
{
  "statusCode": 400,
  "code": "PROGRAMMATIC_PAGINATION_MODE_CONFLICT",
  "message": "<string>",
  "error": "Bad Request",
  "request_id": "8cf64dcc-0f73-4f8d-a845-3d80c1040475"
}