> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hooksnode.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bank events

> bank.credit.received and bank.debit.posted, made from bank alert emails.

A bank event is one transaction from one bank alert email. See [Bank alerts](/sources/bank-alerts) to turn them on.

* `bank.credit.received`: money came into the account.
* `bank.debit.posted`: money left the account.

```json bank.credit.received theme={null}
{
  "type": "bank.credit.received",
  "source_id": "2mJ8kQ4vXw9aB3cD5eF7gH1iK0L",
  "provider": "gmail",
  "mailbox": "finance@acme.ng",
  "bank": {
    "name": "GTBank",
    "sender": "gens@gtbank.com",
    "known": true
  },
  "transaction": {
    "direction": "credit",
    "amount_minor": 4500000,
    "currency": "NGN",
    "balance_minor": 128730050,
    "account_masked": "01******31",
    "account_last4": "0231",
    "narration": "TRF FROM ADA OKAFOR INV-9311",
    "reference": "000013260924101502123456789012",
    "counterparty": "ADA OKAFOR",
    "counterparty_bank": "Access Bank",
    "session_id": "000013260924101502123456789012",
    "occurred_at": "2026-09-24T10:15:02+01:00"
  },
  "confidence": "high",
  "parser": "rules",
  "email": {
    "id": "18f2c1a9b7d3e4f5",
    "thread_id": "18f2c1a9b7d3e4f5",
    "subject": "GeNS Transaction Alert [Credit: NGN 45,000.00]",
    "from": { "name": "GTBank", "email": "gens@gtbank.com" },
    "received_at": "2026-09-24T09:15:05Z"
  }
}
```

The example values are made up. The fields that the email does not have are left out.

## Fields

<ResponseField name="type" type="string" required>`bank.credit.received` or `bank.debit.posted`.</ResponseField>
<ResponseField name="source_id" type="string" required>The mail source that read the email.</ResponseField>
<ResponseField name="provider" type="string" required>`gmail`, `outlook` or `imap`.</ResponseField>
<ResponseField name="mailbox" type="string" required>The mailbox address.</ResponseField>

<ResponseField name="bank" type="object" required>
  <Expandable title="bank fields">
    <ResponseField name="name" type="string">The bank's name, when hooksnode knows the sender.</ResponseField>
    <ResponseField name="sender" type="string">The sender address of the alert.</ResponseField>
    <ResponseField name="known" type="boolean">`true` when the sender is on the list of [supported banks](/sources/bank-alerts#supported-banks).</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="transaction" type="object" required>
  <Expandable title="transaction fields" defaultOpen>
    <ResponseField name="direction" type="string" required>`credit` or `debit`.</ResponseField>
    <ResponseField name="amount_minor" type="integer" required>The amount in minor units. `4500000` is 45,000.00.</ResponseField>
    <ResponseField name="currency" type="string" required>An ISO 4217 code: `NGN`, `USD`, `GBP` or `EUR`. hooksnode uses `NGN` only when the sender is a known Nigerian bank and the email names no currency.</ResponseField>
    <ResponseField name="balance_minor" type="integer">The balance after the transaction, in minor units.</ResponseField>
    <ResponseField name="account_masked" type="string">The account number as the email shows it.</ResponseField>
    <ResponseField name="account_last4" type="string">The last digits of the account.</ResponseField>
    <ResponseField name="narration" type="string">The narration or description.</ResponseField>
    <ResponseField name="reference" type="string">The transaction reference.</ResponseField>
    <ResponseField name="counterparty" type="string">The other party: the payer for a credit, the payee for a debit.</ResponseField>
    <ResponseField name="counterparty_bank" type="string">The other party's bank, when the email names it.</ResponseField>
    <ResponseField name="session_id" type="string">The NIP session ID, when present.</ResponseField>
    <ResponseField name="occurred_at" type="string">The time of the transaction (RFC 3339). When the email has no time, this is when the email arrived.</ResponseField>
    <ResponseField name="occurred_at_text" type="string">The time as the email wrote it.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="confidence" type="string" required>`high` or `medium`. See [The parser never guesses](/sources/bank-alerts#the-parser-never-guesses).</ResponseField>
<ResponseField name="parser" type="string" required>`rules` or `ai`.</ResponseField>
<ResponseField name="ai_model" type="string">The model that read the email, when `parser` is `ai`.</ResponseField>

<ResponseField name="email" type="object" required>
  The alert email. Use `email.id` to find the full email or to deduplicate.

  <Expandable title="email fields">
    <ResponseField name="id" type="string">The provider's message ID.</ResponseField>
    <ResponseField name="thread_id" type="string">The conversation ID.</ResponseField>
    <ResponseField name="internet_message_id" type="string">The `Message-ID` header.</ResponseField>
    <ResponseField name="subject" type="string">The subject.</ResponseField>
    <ResponseField name="from" type="object">`{ "name", "email" }`</ResponseField>
    <ResponseField name="received_at" type="string">When the email arrived (RFC 3339).</ResponseField>
  </Expandable>
</ResponseField>

## Handle bank events safely

* Use `email.id` (or `transaction.reference`) as your idempotency key.
* Post `high` credits at once. Send `medium` credits to a person to check.
* Money moves only on the bank's side. Treat these events as a notice, and confirm large amounts in your bank's portal or statement.
