Skip to main content

Bank Ingest

Bank ingests are the raw transactions that power Naqood's reconciliation experience. Each record stores the amount, currency, date, bank account, and any match metadata that links it to invoices, purchases, or journal entries.

All operations require a Naqood API secret with bank permissions. Authenticate with the Secret guide or obtain a key via OAuth, then include the organization slug in every request.

Core objects

BankIngest

FieldTypeDescription
idID!Unique identifier for the ingest
bankAccountBankAccountLinked Naqood bank account (ID, name, bank name, currency)
amountStringDecimal string; positives are inflows, negatives are outflows
currencyStringISO‑4217 code such as AED, USD, EUR
descriptionStringHuman-readable text shown in the UI
transactionDateDatePosting date of the movement
createdAtTimestampWhen Naqood stored the ingest
reconciledBooleantrue once matched to another document
matchTypeStringType of match (invoice, purchase, accountTransfer, etc.)
matchEntityIdIDID of the matched entity
matchDetailsJSONObjectOptional metadata such as transfer fees
noteStringFree-form internal notes
archivedBooleanHide noise or duplicates without deleting them

BankIngestFilterResult

FieldDescription
countTotal records that match the filter
offsetCurrent offset returned in the page
limitPage size
entriesArray of BankIngest objects

Query transactions

Use the bankIngest query to page through transactions with filters and sorting.

query BankIngests($slug: Slug!, $after: Date) {
bankIngest(
slug: $slug
limit: 50
offset: 0
orderBy: { field: "transaction_date", order: DESC }
filter: {
and: [
{ archived: { equalTo: false } }
{ reconciled: { equalTo: false } }
{ transactionDate: { greaterThanOrEqualTo: $after } }
]
}
) {
count
entries {
id
amount
currency
transactionDate
reconciled
matchType
matchEntityId
note
bankAccount {
id
name
currency
}
journalEntry {
id
number
}
}
}
}

Filter operators: equalTo, notEqualTo, greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo, in, plus and/or groups. Use orderBy to sort by transaction_date, created_at, or amount in ASC/DESC order.

Import transactions

Create or update one or more ingests with createBankIngestBulk.

mutation CreateBankIngests($input: CreateBankIngestBulkInput!) {
createBankIngestBulk(input: $input) {
bankIngests {
id
amount
currency
description
transactionDate
archived
bankAccount {
id
name
}
}
}
}

Input definition

input CreateBankIngestBulkInput {
slug: Slug!
transactions: [BankIngestTransactionInput!]!
bankAccountBalances: [BankAccountBalanceUpdateInput!]
}

input BankIngestTransactionInput {
bankAccountId: ID
externalBankAccountId: String
amount: String!
currency: String!
description: String
foreignId: String
accountCode: Int
transactionDate: Date
note: String
}

input BankAccountBalanceUpdateInput {
bankAccountId: ID
externalBankAccountId: String
externalBalance: String!
externalBalanceDate: Timestamp!
}

Field notes

  • Choose one identifier strategy per request: supply bankAccountId everywhere or supply externalBankAccountId everywhere. Mixing them causes a validation error.
  • foreignId provides idempotency. Duplicate values are skipped so you can retry the same payload safely.
  • accountCode pre-fills a suggested journal entry based on your chart of accounts.
  • bankAccountBalances (optional) keeps Naqood's running balance aligned with the statement balance you observed upstream.

Sample payload

{
"input": {
"slug": "acme-co",
"transactions": [
{
"bankAccountId": "aeedb594-1234-5678-9abc-def012345678",
"amount": "-1250.45",
"currency": "AED",
"description": "Vendor payment #88312",
"foreignId": "bank-88312",
"transactionDate": "2025-11-05"
}
],
"bankAccountBalances": [
{
"bankAccountId": "aeedb594-1234-5678-9abc-def012345678",
"externalBalance": "52000.98",
"externalBalanceDate": "2025-11-05T00:00:00Z"
}
]
}
}

Troubleshooting

ErrorCauseFix
Bank account(s) not foundProvided account ID does not belong to the organizationVerify the identifier and keep a single identifier strategy per request
Bank ingest already reconciledAttempted to reconcile an ingest that already has a journal entryCheck reconciled before calling the mutation or void the prior entry
Bank ingest amount must be positive/negativeAmount sign does not match the chosen match typeEnsure invoices use positive values and purchases use negative values
Transfer entries must have opposite amountsAccount transfer pairing failedPair two ingests with opposite signs and matching dates
invalid api key or not authenticatedAuthorization header missing or secret lacks scopeSee the Authentication guide

Response payloads

Bulk mutations return a BankIngestBulkPayload:

type BankIngestBulkPayload {
bankIngests: [BankIngest!]!
}

Use the returned objects to update your local cache or confirm which ingests were created, reconciled, or updated.