Transactions
Parent Transactions
Trace a transaction back through the records that created it.
In simple terms, a parent transaction is a transaction that generates another transaction in your ledger.
Because transactions in Blnk are immutable, each status change creates a new transaction record. This new record references the previous one as its “parent”.
Blnk records the ID of this parent transaction in the parent_transaction field of the new (child) transaction. This creates a clear lineage of transactions, allowing you to trace a transaction back to its origin, see how it evolved, and connect it to any related siblings.
{
"transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
"parent_transaction": "txn_c4e70eb8-e4d6-4e04-a2e2-92a43b969e0c"
}
parent_transaction is set in these cases:
- Queued transactions act as the parent of the next state (
APPLIED,INFLIGHT, orREJECTED). - Inflight transactions are the parent of their final outcome (
APPLIEDorVOID). - Split transactions are the parent of the resulting individual transactions.
- Bulk transactions are the parent of the included individual transactions.
- Scheduled transactions are the parent of the executed state (
APPLIEDorREJECTED). - Refunds use the original transaction as their parent.
Single transaction
Consider a single $100 transaction in your ledger. Its lifecycle might look like this:

- When the transaction is first created, it starts in the
QUEUEDstate. - Once Blnk processes it, a new transaction is created in the
APPLIEDstate. - The initial
QUEUEDtransaction becomes the parent of the newAPPLIEDtransaction.
Inflight transaction
Consider an inflight transaction of $100. Its lifecycle looks like this:

-
When the transaction is created, it starts in the
QUEUEDstate. -
Once Blnk processes it, a new transaction is created in the
INFLIGHTstate. -
The initial
QUEUEDtransaction becomes the parent of the newINFLIGHTtransaction. -
Once the inflight transaction is committed, a new transaction is created in the
APPLIEDstate. -
If the inflight transaction is voided instead, a new transaction is created in the
VOIDstate. -
The
INFLIGHTtransaction becomes the parent of theAPPLIEDand/orVOIDtransactions.
With the INFLIGHT record as the parent, you can retrieve the complete outcome of that transaction by filtering for every transaction whose parent_transaction matches the INFLIGHT transaction ID:
curl -X POST "http://YOUR_BLNK_INSTANCE_URL/transactions/filter" \
-H "X-blnk-key: <api-key>" \
-H "Content-Type: application/json" \
-d '{
"filters": [
{
"field": "parent_transaction",
"operator": "eq",
"value": "<inflight_transaction_id>"
}
]
}'const response = await blnk.Search.filter(
{
filters: [
{
field: 'parent_transaction',
operator: 'eq',
value: '<inflight_transaction_id>',
},
],
},
'transactions',
);results, _, _ := client.Transaction.Filter(blnkgo.FilterParams{
Filters: []blnkgo.Filter{
{
Field: "parent_transaction",
Operator: blnkgo.OpEqual,
Value: "<inflight_transaction_id>",
},
},
})response = blnk.search.filter(
{
"filters": [
{
"field": "parent_transaction",
"operator": "eq",
"value": "<inflight_transaction_id>",
},
],
},
"transactions",
)ApiResponse<JsonNode> response = blnk.search().filter(
FilterParams.create()
.filters(List.of(
FilterCondition.create()
.field("parent_transaction")
.operator("eq")
.value("<inflight_transaction_id>")
)),
"transactions");{
"data": [
{
"transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
"parent_transaction": "<inflight_transaction_id>",
"status": "APPLIED"
}
]
}
Queued parent transactions
A queued parent transaction refers to the very first transaction in a chain - the one that initiates the entire transaction lifecycle.
In most cases, this initial transaction starts in the QUEUED state, serving as the root from which all subsequent transactions (like INFLIGHT or APPLIED) are derived.
Blnk records the ID of this initial transaction in the meta_data.QUEUED_PARENT_TRANSACTION field of every subsequent transaction. Filter on that field to retrieve every transaction in the same lifecycle chain:
curl -X POST "http://YOUR_BLNK_INSTANCE_URL/transactions/filter" \
-H "X-blnk-key: <api-key>" \
-H "Content-Type: application/json" \
-d '{
"filters": [
{
"field": "meta_data.QUEUED_PARENT_TRANSACTION",
"operator": "eq",
"value": "<queued_parent_transaction_id>"
}
]
}'const response = await blnk.Search.filter(
{
filters: [
{
field: 'meta_data.QUEUED_PARENT_TRANSACTION',
operator: 'eq',
value: '<queued_parent_transaction_id>',
},
],
},
'transactions',
);results, _, _ := client.Transaction.Filter(blnkgo.FilterParams{
Filters: []blnkgo.Filter{
{
Field: "meta_data.QUEUED_PARENT_TRANSACTION",
Operator: blnkgo.OpEqual,
Value: "<queued_parent_transaction_id>",
},
},
})response = blnk.search.filter(
{
"filters": [
{
"field": "meta_data.QUEUED_PARENT_TRANSACTION",
"operator": "eq",
"value": "<queued_parent_transaction_id>",
},
],
},
"transactions",
)ApiResponse<JsonNode> response = blnk.search().filter(
FilterParams.create()
.filters(List.of(
FilterCondition.create()
.field("meta_data.QUEUED_PARENT_TRANSACTION")
.operator("eq")
.value("<queued_parent_transaction_id>")
)),
"transactions");{
"data": [
{
"transaction_id": "txn_59347177-aa7e-d8ad-9f4f-d09628b32ec3",
"meta_data": {
"QUEUED_PARENT_TRANSACTION": "<queued_parent_transaction_id>"
},
"status": "APPLIED"
}
]
}
Blnk automatically creates this field whenever you use the queue system to process any transaction - single, inflight, split, or bulk transactions.
In the case of split or bulk transactions, it becomes particularly useful, as it lets you trace the entire chain and identify the final outcome of each branch.
Queued parent for bulk/split transactions
Consider a split transaction of $100. Half to person A and half to person B. The lifecycle of this transaction would be as follows:

- The split transaction is first created in the
QUEUEDstate. - Blnk then generates two individual transactions - one for Person A and one for Person B - both in the
QUEUEDstate. - The original
QUEUEDsplit transaction becomes the parent of these two newQUEUEDtransactions. - As Blnk processes the two individual transactions, it creates two new transactions in the
APPLIEDstate. - Each individual child
QUEUEDtransaction becomes the parent of its correspondingAPPLIEDtransaction.
Unlike the inflight transaction example above, you can’t query by parent_transaction to get the final outcome of a split transaction.
This is because the final APPLIED transactions aren’t directly linked to the original split transaction. Instead, they’re linked to the two individual QUEUED transactions created from it - each representing a separate outcome for Person A and Person B.
Instead you’ll need to query by the meta_data.QUEUED_PARENT_TRANSACTION field, which is present in all related transactions, regardless of their parent.