This feature is only available in the Enterprise version

Data Lake

Queries

Run, save, and schedule queries against your data lake.

Run SQL with Create new query, then save and schedule the reports you want to keep.

In Insights, the Queries tab holds that work: Saved, Scheduled, and History.

A query is one read-only DuckDB SELECT or WITH. Start from a template, or paste your own statement.

What you can query

The lake has four tables: transactions, balances, ledgers, and identity. Open Schema for the columns and how they join.

A payment can be on the ledger before it shows up here. Keep that delay in mind for recent activity.

QuestionWhere to get it
Money that moved over a periodCreate new query or Insights
Wallets, ledgers, and identities in that historyCreate new query or Insights
Amount in a wallet right nowGet balance
Amount in a wallet at a past timeHistorical balances

Date range

The date range is the period of history the query is for. Set it to the days the report needs, and the lake opens only those days.

On transactions, that period is when money moved through a status. A September range is September’s payments.

On balances, ledgers, and identity, that period is when the record was created. A September range is wallets, ledgers, and identities created in September.

start_date and end_date are the first and last day of that period on Create new query.

A saved query sets its date range with range_mode. There are two types:

TypeWhat it stores
fixedstart_date and end_date. Every run opens those same days.
rollingrolling_days. Each run opens that many days, ending when the query runs.

See Create saved query.

Choose that period in the toolbar. The query is about those days, and no others.

Date range in the Insights toolbar, beside Run

Accepted SQL queries

Insights accepts one read-only SELECT or WITH against the data lake. The dialect is DuckDB SQL.

DuckDB functions such as TRY_CAST, DATE_TRUNC, ANY_VALUE, and BOOL_AND are available.

PostgreSQL-only or MySQL-only syntax is not guaranteed to run. Any other statement is rejected.

AllowedRejected
One SELECT or WITHINSERT, UPDATE, DELETE, DDL, COPY, ATTACH, or multiple statements
transactions, balances, ledgers, identityAny other table
Named columnsSELECT *

Open Schema for tables and how they connect.

Start a query

Send instance_id, start_date, end_date, and one read-only sql.

curl -X POST 'https://api.cloud.blnkfinance.com/data/lake/query' \
  -H 'X-blnk-key: CLOUD_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "instance_id": "YOUR_INSTANCE_ID",
    "start_date": "2026-08-01",
    "end_date": "2026-08-31",
    "sql": "SELECT currency, COUNT(*) AS txn_count FROM transactions GROUP BY currency LIMIT 1000"
  }'

Field details are on Create new query.

Click New query to open a blank editor. Set the toolbar date range, paste a SELECT or WITH, and click Run.

Insights workbench after New query, with Untitled lake query and the Queries tab open

Save a query

Saving stores the SQL. It does not run the query.

Send instance_id, name, sql, and a range_mode of fixed or rolling.

curl -X POST 'https://api.cloud.blnkfinance.com/data/lake/queries' \
  -H 'X-blnk-key: CLOUD_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "instance_id": "YOUR_INSTANCE_ID",
    "name": "Applied volume by currency",
    "sql": "SELECT currency, COUNT(*) AS txn_count FROM transactions GROUP BY currency LIMIT 1000",
    "range_mode": "fixed",
    "start_date": "2026-08-01",
    "end_date": "2026-08-31"
  }'

Run it later with saved_query_id on Create new query. See Create saved query.

Click Save after a run you want to keep. Until you save, the draft is named Untitled lake query.

Saved queries live on this instance. Open one from Saved to put that SQL back in the editor.

Set the date range, run a query, then save it from Actions

Schedule a query

A schedule runs the last saved SQL and keeps a result preview. It does not send notifications.

  • Editor changes do not run until you save again.
  • If a run returns empty, check the date range first.

Send cron_expression and timezone for the saved query.

curl -X PUT 'https://api.cloud.blnkfinance.com/data/lake/queries/{query_id}/schedule' \
  -H 'X-blnk-key: CLOUD_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "cron_expression": "0 9 * * *",
    "timezone": "America/New_York",
    "enabled": true
  }'

0 9 * * * is every day at 09:00 in that timezone. See Schedule saved query.

Schedule query appears in Actions once the query is saved with no unsaved edits.

Open the schedule

Open Actions, then Schedule query.

Set the schedule

  • Preset: Hourly, Daily at 09:00, Weekly on Monday, or Monthly on the 1st.
  • Cron expression: fills from the preset. Leave it unless you need a custom schedule.
  • Timezone: the timezone for the schedule

Click Save schedule.

Open Actions, choose Schedule query, pick a preset and timezone, then save the schedule

Reopen a past run

List query runs returns recent runs for one instance.

Get query run returns one run, including the SQL snapshot and a result preview.

curl -X GET 'https://api.cloud.blnkfinance.com/data/lake/query-runs?instance_id=YOUR_INSTANCE_ID&limit=20' \
  -H 'X-blnk-key: CLOUD_API_KEY'

Use History to reopen SQL you already ran, including queries you never saved.

Saved is the query you chose to keep. History stores each execution.

Open History on the Queries tab to reopen a past run

Troubleshooting

My totals do not match the dashboard

Check whether the query sums precise_amount as-is, or divides by precision first. See Precision.

Also check whether it mixed currencies. For a live balance, use the Ledger API.

Transaction counts look inflated after a join

Check whether balances, ledgers, or identity were collapsed to one row per ID before the join. See How they connect.

Open inflight holds look wrong

Check that start_date and end_date, or the toolbar, cover the hold and its commit or void.

You can also use the Open inflight holds template.

Query returns no rows

Check start_date and end_date, or the toolbar. The range has to include the days you expect.

Query fails with a type error

A column may be typed differently across days. Wrap dates and amounts in TRY_CAST.

Query rejected: statement not allowed

Check that the statement is one SELECT or WITH. See Accepted SQL queries.

Query is slow or times out

Check the date range and how many currencies you are scanning.

Also check whether you selected * and whether the query has a LIMIT. Keep it under 5000.

Best practices

  • Live data retrieval should use the Ledger API. The data lake is best for historical insights over a period.
  • Each status is its own row. Filter status, and use parent_transaction for a commit or void.
  • The date range follows created_at. See Date range.
  • Widen the range when a hold and its commit or void fall on different days.
  • Wrap dates and amounts in TRY_CAST so one mismatched row does not fail the query.