# Commit inflight transactions

Commit inflight transactions, including partial commits, bulk commits, and scheduled commits in Blnk.

After you [create an inflight transaction](/transactions/inflight/create-inflight), commit it when the main balance should change.

Commit clears the inflight balance fields and moves the reserved amount into the main balances.

<Note>By default, Blnk queues the commit. The response stays `INFLIGHT` with `queued: true` until the worker finishes. Set `skip_queue: true` to apply the commit in the same request.</Note>

<Frame>
![Scenarios when inflight transactions are finished processing](img/transactions/inflight-outcomes.png)
</Frame>

## Commit one transaction

<Tabs>
<Tab title="Using the API">

<Steps>
<Step title="Commit the full amount">

Call [Update inflight](/reference/update-inflight) with the inflight transaction id and `"status": "commit"`.

```text Update inflight
PUT /transactions/inflight/{transaction_id}
```

<CodeGroup>
```bash cURL wrap {5}
curl -X PUT "http://YOUR_BLNK_INSTANCE_URL/transactions/inflight/{transaction_id}" \
  -H "X-blnk-key: <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "commit"
  }'
```

```typescript TypeScript wrap {4}
const response = await blnk.Transactions.updateStatus(
  '{transaction_id}',
  {
    status: 'commit',
  },
);
```

```go Go wrap {4}
transaction, _, _ := client.Transaction.Update(
    "{transaction_id}",
    blnkgo.UpdateStatus{
        Status: blnkgo.InflightStatusCommit,
    },
)
```

```python Python wrap {4}
response = blnk.transactions.update_status(
  "{transaction_id}",
  {
    "status": "commit",
  },
)
```

```java Java wrap {4}
ApiResponse<JsonNode> response = blnk.transactions().updateStatus(
    "{transaction_id}",
    UpdateTransactionStatus.create()
        .status("commit"));
```
</CodeGroup>

```json 200 Queued wrap {3,4}
{
  "transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
  "status": "INFLIGHT",
  "queued": true
}
```

`queued: true` means the commit is waiting on a worker, not that the main balance has changed. 

With `skip_queue: true`, the same call returns the `APPLIED` child and sets `parent_transaction` to the inflight id.

Continuing from the [earlier example](/transactions/inflight/create-inflight#inflight-balance-tracking), a full commit of the \$100 hold looks like this:

| `balance_id` | **Main balance** | **Inflight balance** | **Inflight credit** | **Inflight debit** |
| :-- | :-- | :-- | :-- | :-- |
| `balance_A` | 100 | 0 | 0 | 0 |
| `balance_B` | 100 | 0 | 0 | 0 |

</Step>
<Step title="Commit part of the amount">

<span id="partial-commits" />

Set `precise_amount` to the amount you want to commit, in its smallest unit. The rest stays `INFLIGHT`.

You can commit more than once. The total cannot exceed the original inflight amount.

A \$100 hold can take three \$30 commits (\$90). A fourth \$30 commit fails because \$120 is more than the original \$100.

<CodeGroup>
```bash cURL wrap {6}
curl -X PUT "http://YOUR_BLNK_INSTANCE_URL/transactions/inflight/{transaction_id}" \
  -H "X-blnk-key: <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "commit",
    "precise_amount": 4000
  }'
```

```typescript TypeScript wrap {5}
const response = await blnk.Transactions.updateStatus(
  '{transaction_id}',
  {
    status: 'commit',
    precise_amount: 4000,
  },
);
```

```go Go wrap {5}
transaction, _, _ := client.Transaction.Update(
    "{transaction_id}",
    blnkgo.UpdateStatus{
        Status: blnkgo.InflightStatusCommit,
        PreciseAmount: big.NewInt(4000),
    },
)
```

```python Python wrap {5}
response = blnk.transactions.update_status(
  "{transaction_id}",
  {
    "status": "commit",
    "precise_amount": 4000,
  },
)
```

```java Java wrap {4}
ApiResponse<JsonNode> response = blnk.transactions().updateStatus(
    "{transaction_id}",
    UpdateTransactionStatus.create()
        .status("commit")
        .preciseAmount(4000));
```
</CodeGroup>

A partial commit of \$40 from the \$100 hold leaves the remaining \$60 inflight:

| `balance_id` | **Main balance** | **Inflight balance** | **Inflight credit** | **Inflight debit** |
| :-- | :-- | :-- | :-- | :-- |
| `balance_A` | 160 | -60 | 0 | 60 |
| `balance_B` | 40 | 60 | 60 | 0 |

[Void](/transactions/inflight/void-inflight) releases whatever is still held. It does not reverse amount you already committed.

</Step>
</Steps>

</Tab>
<Tab title="Using the Dashboard">

<Steps>
<Step title="Commit the full amount">

Open the inflight transaction. **Commit** completes it.

![Commit and void on a transaction](img/transactions/inflight-actions.png)

Select **Commit transaction**, or press `C`. Leave **Amount to commit** empty, then confirm.

![Commit transaction modal](img/transactions/commit-transaction-modal.png)

A new linked transaction is created with status `APPLIED`.

</Step>
<Step title="Commit part of the amount">

Enter the amount in **Amount to commit**, then confirm. The rest stays inflight.

Leave **Amount to commit** empty on the last commit. That applies whatever is still held.

</Step>
</Steps>

</Tab>
</Tabs>

## Commit multiple inflights

<Version>Available in version 0.14.2 and later.</Version>

<Steps>
<Step title="Commit the holds">

Use [Bulk commit inflight](/reference/bulk-commit-inflight) for holds you created one by one. Each bulk commit request accepts at most **100** items.

<Tip>Omit `precise_amount` on an item to commit its full remainder, or set it for a partial commit of that item.</Tip>

<Warning>This endpoint is not for a split or a bulk batch. Those use one parent id in [Commit a split or a bulk batch](#commit-a-split-or-a-bulk-batch).</Warning>

```text Bulk commit inflight
POST /transactions/inflight/bulk/commit
```

<CodeGroup>
```bash cURL wrap
curl -X POST "http://YOUR_BLNK_INSTANCE_URL/transactions/inflight/bulk/commit" \
  -H "X-blnk-key: <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "transactions": [
      {
        "transaction_id": "txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94"
      },
      {
        "transaction_id": "txn_c5d9e2a1-7b4f-4a3c-9e8d-1f6a2b4c8d30",
        "precise_amount": 4000
      }
    ]
  }'
```

```typescript TypeScript wrap
const response = await blnk.Transactions.bulkCommitInflight({
  transactions: [
    {
      transaction_id: 'txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94',
    },
    {
      transaction_id: 'txn_c5d9e2a1-7b4f-4a3c-9e8d-1f6a2b4c8d30',
      precise_amount: 4000,
    },
  ],
});
```

```go Go wrap
result, _, _ := client.Transaction.BulkCommitInflight(blnkgo.BulkCommitInflightRequest{
    Transactions: []blnkgo.BulkCommitInflightItem{
        {
            TransactionID: "txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94",
        },
        {
            TransactionID: "txn_c5d9e2a1-7b4f-4a3c-9e8d-1f6a2b4c8d30",
            PreciseAmount: big.NewInt(4000),
        },
    },
})
```

```python Python wrap
response = blnk.transactions.bulk_commit_inflight({
  "transactions": [
    {
      "transaction_id": "txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94",
    },
    {
      "transaction_id": "txn_c5d9e2a1-7b4f-4a3c-9e8d-1f6a2b4c8d30",
      "precise_amount": 4000,
    },
  ],
})
```

```java Java wrap
ApiResponse<JsonNode> response = blnk.transactions().bulkCommitInflight(
    BulkCommitInflightRequest.create()
        .transactions(List.of(
            BulkCommitInflightItem.create()
            .transactionId("txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94"),
            BulkCommitInflightItem.create()
            .transactionId("txn_c5d9e2a1-7b4f-4a3c-9e8d-1f6a2b4c8d30")
            .preciseAmount(4000)
        )));
```
</CodeGroup>

</Step>
<Step title="Read the result">

<Version>From Blnk Core 0.15.0, bulk commit goes through the queue by default. `queued` means the job was accepted. Parents stay `INFLIGHT` until workers create `APPLIED` children.</Version>

One failed item does not block the rest.

| Status | Code | Meaning |
| :-- | :-- | :-- |
| `queued` | `QUEUED` | New commit job added. |
| `queued` | `ALREADY_QUEUED` | Already queued. The duplicate is skipped. |

```json 200 Queued wrap
{
  "succeeded": 2,
  "failed": 0,
  "results": [
    {
      "transaction_id": "txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94",
      "status": "queued",
      "code": "QUEUED"
    },
    {
      "transaction_id": "txn_c5d9e2a1-7b4f-4a3c-9e8d-1f6a2b4c8d30",
      "status": "queued",
      "code": "ALREADY_QUEUED"
    }
  ]
}
```

`QUEUED` and `ALREADY_QUEUED` both count toward `succeeded`. Set `skip_queue: true` to process each item in the request. Those results use `succeeded` or `failed` instead of `queued`.

</Step>
</Steps>

## Commit a split or a bulk batch

<Steps>
<Step title="Choose the parent id">

A split uses the root `transaction_id`. A bulk batch uses `batch_id`. That id commits every pending leg.

<Tip>
If you don't have the parent id, open any child transaction and copy `meta_data.QUEUED_PARENT_TRANSACTION`. Use that id to commit the whole split or batch.

If create skipped the queue, use the child's `parent_transaction` instead.
</Tip>

</Step>
<Step title="Commit the split or batch">

Call [Update single inflight](/reference/update-inflight) with that id and `"status": "commit"`. Do not send that id to [Bulk commit inflight](/reference/bulk-commit-inflight).

```text Update inflight
PUT /transactions/inflight/{parent_id}
```

<CodeGroup>
```bash cURL wrap {5}
curl -X PUT "http://YOUR_BLNK_INSTANCE_URL/transactions/inflight/{parent_id}" \
  -H "X-blnk-key: <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "commit"
  }'
```

```typescript TypeScript wrap {4}
const response = await blnk.Transactions.updateStatus(
  '{parent_id}',
  {
    status: 'commit',
  },
);
```

```go Go wrap {4}
transaction, _, _ := client.Transaction.Update(
    "{parent_id}",
    blnkgo.UpdateStatus{
        Status: blnkgo.InflightStatusCommit,
    },
)
```

```python Python wrap {4}
response = blnk.transactions.update_status(
  "{parent_id}",
  {
    "status": "commit",
  },
)
```

```java Java wrap {4}
ApiResponse<JsonNode> response = blnk.transactions().updateStatus(
    "{parent_id}",
    UpdateTransactionStatus.create()
        .status("commit"));
```
</CodeGroup>

```json 200 Queued wrap
{
  "transaction_id": "txn_0b59f6e6-6c4a-4efa-915c-526f77ef61ab",
  "status": "INFLIGHT",
  "queued": true
}
```

On the default queue, the response stays `INFLIGHT` with `queued: true`. Every leg and its later `APPLIED` child shares `meta_data.QUEUED_PARENT_TRANSACTION`.

With `skip_queue: true`, the response reflects the first leg processed. Each leg's `APPLIED` child points at that leg through `parent_transaction`, so check each leg on its own.

</Step>
</Steps>

## Verify the outcome

<span id="verify-with-webhooks" />

You can confirm a commit or a void in two ways. Listen for the event, or filter the child transactions in the database.

<Steps>
<Step title="Listen for the event">

Blnk sends `transaction.applied` when a commit finishes, and `transaction.void` when a void finishes.

On the default queue, match `meta_data.QUEUED_PARENT_TRANSACTION` on the child to the inflight id. If the request skipped the queue, match `parent_transaction` to that id.

<Tabs>
<Tab title="transaction.applied">

```json transaction.applied wrap {2,5,14,18}
{
  "event": "transaction.applied",
  "data": {
    "transaction_id": "txn_e0f5ab98-bb87-4b09-aefe-839ddb11598b",
    "parent_transaction": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
    "precise_amount": 20000,
    "amount": 200,
    "precision": 100,
    "source": "bln_7f91a1ae-6073-4b7a-952c-23abf94a6634",
    "destination": "bln_59b83b9c-842c-427f-91eb-43cdeaf5c01a",
    "reference": "ref_001adcfgf_q",
    "currency": "GBP",
    "description": "For vacation",
    "status": "APPLIED",
    "inflight": false,
    "created_at": "2025-02-23T09:43:49.623494+01:00",
    "meta_data": {
      "QUEUED_PARENT_TRANSACTION": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
      "inflight": true
    }
  }
}
```

</Tab>
<Tab title="transaction.void">

```json transaction.void wrap {2,5,14,18}
{
  "event": "transaction.void",
  "data": {
    "transaction_id": "txn_c3d4e5f6-a7b8-9012-cdef-345678901234",
    "parent_transaction": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
    "precise_amount": 6000,
    "amount": 60,
    "precision": 100,
    "source": "bln_7f91a1ae-6073-4b7a-952c-23abf94a6634",
    "destination": "bln_59b83b9c-842c-427f-91eb-43cdeaf5c01a",
    "reference": "ref_e7d61840-ecf7-45c1-a0b2-41687c7691f7_q",
    "currency": "GBP",
    "description": "For vacation",
    "status": "VOID",
    "inflight": false,
    "created_at": "2025-02-23T09:45:03.332221+01:00",
    "meta_data": {
      "QUEUED_PARENT_TRANSACTION": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
      "inflight": true
    }
  }
}
```

</Tab>
</Tabs>

</Step>
<Step title="Filter the database">

Use the [Filter API](/search/db/filtering) to read the children from the database. A finished commit has status `APPLIED`. A finished void has status `VOID`.

<Tabs>
<Tab title="Default queue">

Filter `meta_data.QUEUED_PARENT_TRANSACTION` for the inflight id, and keep children whose status is `APPLIED` or `VOID`. Each child's `parent_transaction` points at the queued commit or void, so the shared key is `QUEUED_PARENT_TRANSACTION`.

<CodeGroup>
```bash cURL wrap {7,12}
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": "<inflight_transaction_id>"
      },
      {
        "field": "status",
        "operator": "in",
        "values": ["APPLIED", "VOID"]
      }
    ]
  }'
```

```typescript TypeScript wrap {5,10}
const response = await blnk.Search.filter(
  {
    filters: [
      {
        field: 'meta_data.QUEUED_PARENT_TRANSACTION',
        operator: 'eq',
        value: '<inflight_transaction_id>',
      },
      {
        field: 'status',
        operator: 'in',
        values: ['APPLIED', 'VOID'],
      },
    ],
  },
  'transactions',
);
```

```go Go wrap {4,9}
results, _, _ := client.Transaction.Filter(blnkgo.FilterParams{
    Filters: []blnkgo.Filter{
        {
            Field: "meta_data.QUEUED_PARENT_TRANSACTION",
            Operator: blnkgo.OpEqual,
            Value: "<inflight_transaction_id>",
        },
        {
            Field: "status",
            Operator: blnkgo.OpIn,
            Values: []interface{}{"APPLIED", "VOID"},
        },
    },
})
```

```python Python wrap {5,10}
response = blnk.search.filter(
  {
    "filters": [
      {
        "field": "meta_data.QUEUED_PARENT_TRANSACTION",
        "operator": "eq",
        "value": "<inflight_transaction_id>",
      },
      {
        "field": "status",
        "operator": "in",
        "values": ["APPLIED", "VOID"],
      },
    ],
  },
  "transactions",
)
```

```java Java wrap {5,9}
ApiResponse<JsonNode> response = blnk.search().filter(
    FilterParams.create()
        .filters(List.of(
            FilterCondition.create()
            .field("meta_data.QUEUED_PARENT_TRANSACTION")
            .operator("eq")
            .value("<inflight_transaction_id>"),
            FilterCondition.create()
            .field("status")
            .operator("in")
            .values(List.of("APPLIED", "VOID"))
        )),
    "transactions");
```
</CodeGroup>

```json Response wrap {6,8,14,16}
{
  "data": [
    {
      "transaction_id": "txn_b2c3d4e5-f6a7-8901-bcde-f23456789012",
      "parent_transaction": "txn_d8f4a291-3e7c-41b6-a05d-9c2e71b48f6a",
      "status": "APPLIED",
      "meta_data": {
        "QUEUED_PARENT_TRANSACTION": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d"
      }
    },
    {
      "transaction_id": "txn_c3d4e5f6-a7b8-9012-cdef-345678901234",
      "parent_transaction": "txn_4a9c0e75-1b62-483f-8d31-7f6a25e903d4",
      "status": "VOID",
      "meta_data": {
        "QUEUED_PARENT_TRANSACTION": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d"
      }
    }
  ]
}
```

</Tab>
<Tab title="Skipped queue">

Filter `parent_transaction` for the inflight id, and keep children whose status is `APPLIED` or `VOID`. The child links straight to that inflight transaction.

<CodeGroup>
```bash cURL wrap {7,12}
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>"
      },
      {
        "field": "status",
        "operator": "in",
        "values": ["APPLIED", "VOID"]
      }
    ]
  }'
```

```typescript TypeScript wrap {5,10}
const response = await blnk.Search.filter(
  {
    filters: [
      {
        field: 'parent_transaction',
        operator: 'eq',
        value: '<inflight_transaction_id>',
      },
      {
        field: 'status',
        operator: 'in',
        values: ['APPLIED', 'VOID'],
      },
    ],
  },
  'transactions',
);
```

```go Go wrap {4,9}
results, _, _ := client.Transaction.Filter(blnkgo.FilterParams{
    Filters: []blnkgo.Filter{
        {
            Field: "parent_transaction",
            Operator: blnkgo.OpEqual,
            Value: "<inflight_transaction_id>",
        },
        {
            Field: "status",
            Operator: blnkgo.OpIn,
            Values: []interface{}{"APPLIED", "VOID"},
        },
    },
})
```

```python Python wrap {5,10}
response = blnk.search.filter(
  {
    "filters": [
      {
        "field": "parent_transaction",
        "operator": "eq",
        "value": "<inflight_transaction_id>",
      },
      {
        "field": "status",
        "operator": "in",
        "values": ["APPLIED", "VOID"],
      },
    ],
  },
  "transactions",
)
```

```java Java wrap {5,9}
ApiResponse<JsonNode> response = blnk.search().filter(
    FilterParams.create()
        .filters(List.of(
            FilterCondition.create()
            .field("parent_transaction")
            .operator("eq")
            .value("<inflight_transaction_id>"),
            FilterCondition.create()
            .field("status")
            .operator("in")
            .values(List.of("APPLIED", "VOID"))
        )),
    "transactions");
```
</CodeGroup>

```json Response wrap {5,6,13,14}
{
  "data": [
    {
      "transaction_id": "txn_b2c3d4e5-f6a7-8901-bcde-f23456789012",
      "parent_transaction": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
      "status": "APPLIED",
      "meta_data": {
        "inflight": true
      }
    },
    {
      "transaction_id": "txn_c3d4e5f6-a7b8-9012-cdef-345678901234",
      "parent_transaction": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
      "status": "VOID",
      "meta_data": {
        "inflight": true
      }
    }
  ]
}
```

</Tab>
</Tabs>

</Step>
</Steps>

## Schedule a commit

<Version>Available in version 0.14.1 and later.</Version>

Set `inflight_commit_date` when you create the hold. Blnk reserves the funds immediately and commits them at that time. 

Use this when funds need to be held now and released at a known future time, such as a hotel deposit that settles on check-in.

<Note>
Scheduled commits run on a background queue.

Enable `BLNK_QUEUE_INFLIGHT_COMMIT` in your environment, or `inflight_commit_queue` in `blnk.json`, before you set `inflight_commit_date`. See [Queue configuration](/operating/configuration/queue#queue-settings).
</Note>

<CodeGroup>
```bash cURL wrap {13}
curl -X POST "http://YOUR_BLNK_INSTANCE_URL/transactions" \
  -H "X-blnk-key: <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "precise_amount": 10000,
    "precision": 100,
    "reference": "ref_001adcfgf",
    "currency": "USD",
    "source": "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
    "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
    "description": "For vacation",
    "inflight": true,
    "inflight_commit_date": "2024-12-21T01:36:46+01:00"
  }'
```

```typescript TypeScript wrap {10}
const response = await blnk.Transactions.create({
  precise_amount: 10000,
  precision: 100,
  reference: 'ref_001adcfgf',
  currency: 'USD',
  source: 'bln_28edb3e5-c168-4127-a1c4-16274e7a28d3',
  destination: 'bln_ebcd230f-6265-4d4a-a4ca-45974c47f746',
  description: 'For vacation',
  inflight: true,
  inflight_commit_date: '2024-12-21T01:36:46+01:00',
});
```

```go Go wrap {12}
transaction, _, _ := client.Transaction.Create(blnkgo.CreateTransactionRequest{
    ParentTransaction: blnkgo.ParentTransaction{
        PreciseAmount: big.NewInt(10000),
        Precision: 100,
        Reference: "ref_001adcfgf",
        Currency: "USD",
        Source: "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
        Destination: "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
        Description: "For vacation",
    },
    Inflight: true,
    InflightCommitDate: "2024-12-21T01:36:46+01:00",
})
```

```python Python wrap {10}
response = blnk.transactions.create({
  "precise_amount": 10000,
  "precision": 100,
  "reference": "ref_001adcfgf",
  "currency": "USD",
  "source": "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
  "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
  "description": "For vacation",
  "inflight": True,
  "inflight_commit_date": "2024-12-21T01:36:46+01:00",
})
```

```java Java wrap {11}
ApiResponse<JsonNode> response = blnk.transactions().create(
    CreateTransactions.create()
        .preciseAmount(10000)
        .precision(100)
        .reference("ref_001adcfgf")
        .currency("USD")
        .source("bln_28edb3e5-c168-4127-a1c4-16274e7a28d3")
        .destination("bln_ebcd230f-6265-4d4a-a4ca-45974c47f746")
        .description("For vacation")
        .inflight(true)
        .inflightCommitDate("2024-12-21T01:36:46+01:00"));
```
</CodeGroup>

<Tip>
Format `inflight_commit_date` as `YYYY-MM-DDTHH:MM:SS+00:00` (for example, `2024-04-22T15:28:03+00:00`), where `+00:00` is the timezone offset.
</Tip>

```json 201 Created wrap {3}
{
  "transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
  "status": "INFLIGHT",
  "inflight": true,
  "inflight_commit_date": "2024-12-21T01:36:46+01:00"
}
```

If you also set `inflight_expiry_date`, the commit time has to be earlier than the expiry. Otherwise, Blnk voids the hold before the scheduled commit runs. See [Schedule inflight expiry](/transactions/inflight/void-inflight#schedule-inflight-expiry).

## Error handling

<Version>Structured errors are available from Blnk Core 0.15.0 and later.</Version>

[Update inflight](/reference/update-inflight) returns `400`, `404`, and `409` when a commit fails validation or conflicts with the current state. 

On the default queue, Blnk rejects a second commit or void before enqueueing another job. With `skip_queue: true`, Blnk validates in the request and returns the error immediately.

| Code | When it happens |
| :-- | :-- |
| `GEN_CONFLICT` | A commit or void is already queued for this inflight transaction. |
| `TXN_COMMIT_AMOUNT_EXCEEDED` | The partial commit exceeds the remaining inflight amount. |
| `TXN_ALREADY_VOIDED` | You try to commit a voided inflight transaction. |
| `TXN_NOT_INFLIGHT` | The transaction is not `INFLIGHT`. |
| `TXN_INVALID_STATUS_ACTION` | `status` is not `commit` or `void`. |
| `TXN_NOT_FOUND` | The transaction id does not exist, or it is not the split or batch parent. |

```json 409 Conflict wrap
{
  "error": "a commit or void is already queued for this transaction",
  "error_detail": {
    "code": "GEN_CONFLICT",
    "message": "a commit or void is already queued for this transaction"
  }
}
```

To resolve the error:

| Code | What to do |
| :-- | :-- |
| `GEN_CONFLICT` | Wait for the queued job to finish, or [verify the outcome](#verify-with-webhooks) before sending another request. |
| `TXN_COMMIT_AMOUNT_EXCEEDED` | Lower `precise_amount` to the remaining inflight amount, or commit the full remainder. |
| `TXN_ALREADY_VOIDED` | Treat the hold as cancelled. Do not commit it. |
| `TXN_NOT_INFLIGHT` | Use the original inflight id, not an `APPLIED` or `VOID` child. |
| `TXN_INVALID_STATUS_ACTION` | Set `status` to `commit`. |
| `TXN_NOT_FOUND` | For a split or batch, use the parent id from create, not a leg or child id. |

[Bulk commit inflight](/reference/bulk-commit-inflight) returns `400` before any item is processed when the body is invalid. Per-item failures return `200` with `failed` entries in `results`. One failed item does not block the batch.

| Code | When it happens |
| :-- | :-- |
| `TXN_BULK_EMPTY` | `transactions` is missing, empty, or the wrong shape. |
| `TXN_BULK_LIMIT_EXCEEDED` | More than 100 items in one request. |

With `skip_queue: true`, a failed item can return `NOT_FOUND`, `ALREADY_COMMITTED`, `ALREADY_VOIDED`, `NOT_INFLIGHT`, `INVALID_AMOUNT`, `LOCKED`, or `INTERNAL_ERROR`. See [API error codes](/operating/error-codes).

<RelatedTopics
  items={[
    { title: "Create inflight", href: "/transactions/inflight/create-inflight" },
    { title: "Void inflight", href: "/transactions/inflight/void-inflight" },
    { title: "Bulk commit inflight", href: "/reference/bulk-commit-inflight" },
    { title: "Update inflight", href: "/reference/update-inflight" },
    { title: "Transaction lifecycle", href: "/transactions/transaction-lifecycle" },
  ]}
/>