Bulk actions

Bulk actions enable you to create or modify multiple items with a single API request. They are particularly useful if you want to create or modify a large number of items while keeping the number of API requests minimal. Bulk actions currently support up to 5,000 items.

The bulk action API endpoint is asynchronous. It returns a bulk action object with an ID, a status, and the list of items included. Customers are notified by webhook events as a bulk action is processed.

The following steps should be followed to use the bulk action API endpoint:

  1. Create a bulk action
  2. Retrieve the status of a bulk action
  3. Receive webhook events related to a bulk action
  4. Retrieve the results of the bulk action

1. Create a bulk action

Calling the Create bulk action API endpoint creates an asynchronous bulk action. The endpoint requires a target_object (e.g., payment_order), an action (e.g., create), and an array of items.

When creating objects (such as creating a payment order), every item must use the same body parameters as the corresponding API endpoint (for instance, Create payment order).

When updating objects (for instance, approving a payment order), each entry must contain the id of the existing object and the same body parameters as the corresponding API endpoint (for instance, Approve payment order).

Each item on the list can contain an idempotency_key to ensure idempotency. This will also help identify successful and failed executions in the subsequent API calls and events.

By default, if at least one item has an invalid payload, the bulk action will not be created and none of the items will be created or updated. To proceed with creating all valid items even if some are invalid, set fail_on_validation_error to false.

Below is a bulk action API request example:

curl --request POST \
     --url https://sandbox.numeral.io/v1/bulk_actions \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-api-key: YOUR_API_KEY' \
     --data '
{
  "target_object": "payment_order",
  "action": "create",
  "fail_on_validation_error": false,
  "items": [
    {
      "idempotency_key": "89c0761a-ca19-44c5-83df-8d814604d93d",
      "type": "sepa",
      "direction": "credit",
      "currency": "EUR",
      "amount": 15000,
      "connected_account_id": "5b135307-38b4-47f3-b542-75e11f830a7a",
      "receiving_account_id": "97e7bf06-14cd-401b-b9e8-fee2c78c0ace",
      "reference": "Invoice xxxx",
      "auto_approval": true
    },
    {
      "idempotency_key": "3808fa27-26bd-4b4d-8dcd-a3d39f852ad0",
      "type": "sepa",
      "direction": "credit",
      "currency": "EUR",
      "amount": 2000,
      "connected_account_id": "5b135307-38b4-47f3-b542-75e11f830a7a",
      "receiving_account_id": "5ab06daf-d8d2-4e1e-a3cd-77c991740f59",
      "reference": "Invoice yyyy",
      "auto_approval": true
    }
  ]
}
'

Below is a bulk action API response example:

{
  "id": "daa012d7-542e-412c-859e-9777079ffda4",
  "object": "bulk_action",
  "target_object": "payment_order",
  "action": "create",
  "status": "created",
  "total_items": 200,
  "total_successful": 0,
  "total_failed": 0,
  "processed_at": "0001-01-01T00:00:00Z",
  "created_at": "2024-02-29T16:16:40.445697Z"
}

2. Retrieve the status of a bulk action

After creating a bulk action, the id returned by the API can be used to retrieve updates using the Retrieve a bulk action endpoint. This endpoint returns details on the processing state of the job, including:

  • status: the status of the job, either created, processing, or executed
  • total_items, total_successful, and total_failed attributes provide the total number of items as well as the break-down of successful and failed items

Below are examples of bulk actions:

{
  "id": "daa012d7-542e-412c-859e-9777079ffda4",
  "object": "bulk_action",
  "target_object": "payment_order",
  "action": "create",
  "status": "processing",
  "total_items": 200,
  "total_successful": 10,
  "total_failed": 0,
  "processed_at": "2024-02-29T16:16:48.51439Z",
  "created_at": "2024-02-29T16:16:40.445697Z"
}
{
  "id": "daa012d7-542e-412c-859e-9777079ffda4",
  "object": "bulk_action",
  "target_object": "payment_order",
  "action": "create",
  "status": "executed",
  "total_items": 200,
  "total_successful": 200,
  "total_failed": 0,
  "processed_at": "2024-02-29T16:16:48.51439Z",
  "created_at": "2024-02-29T16:16:40.445697Z"
}
{
  "id": "b782cd41-5d6d-4861-b962-13017c929c1f",
  "object": "bulk_action",
  "target_object": "payment_order",
  "action": "create",
  "status": "executed",
  "total_items": 200,
  "total_successful": 198,
  "total_failed": 2,
  "processed_at": "2024-02-29T16:40:36.888269Z",
  "created_at": "2024-02-29T16:40:36.295469Z"
}

3. Receive webhook events related to a bulk action

As bulk actions are processed and go through their lifecycle, the following events are created and sent to webhooks:

TopicTypeDescription
bulk_actioncreatedBulk action was created.
bulk_actionprocessingBulk action has started.
bulk_actionexecutedBulk action has been executed.

The final bulk_action.executed event will notify you when to retrieve the results of the bulk action.

📘

In addition to bulk action events, Numeral also creates events related to the corresponding items. This means that a bulk action creating 500 payment orders will result in at least:

  • One bulk_action.created event
  • One bulk_action.processing event
  • One bulk_action.executed event
  • As many events as the number of payment orders successfully created. This number can be found in the bulk_action.total_successful attribute

4. Retrieve the results of the bulk action

The Retrieve bulk action items API endpoint can be used to retrieve the results of a bulk action. Items that have been successfully processed are grouped in the succeeded array. Items that failed to be processed are grouped in the failed and include related errors.

The API response includes 2 main attributes:

  • Successfully processed items are grouped in the succeeded array, with their corresponding id and idempotency_key
  • Failed items are grouped in the failed array, with their corresponding error and idempotency_key

Here are examples of responses from this API request:

{
  "id": "daa012d7-542e-412c-859e-9777079ffda4",
  "object": "bulk_action",
  "target_object": "payment_order",
  "action": "create",
  "status": "executed",
  "total_items": 5,
  "total_successful": 5,
  "total_failed": 0,
  "processed_at": "2024-02-29T16:16:48.51439Z",
  "created_at": "2024-02-29T16:16:40.445697Z",
  "succeeded": [
    {
      "id": "be039045-eaeb-47ba-89ec-710dfdfcaf50",
      "idempotency_key": "577b4b79-d51d-4658-830c-c45fc173183f"
    },
    {
      "id": "53603abd-bc82-465f-8e46-cf324848aa21",
      "idempotency_key": "1d0486d4-987b-48e4-a227-d43441763c0b"
    },
    {
      "id": "b3b68150-fd49-4e20-8102-b0ac4bf4f2a3",
      "idempotency_key": "e2de24d1-7e2e-4ac8-99e8-cf685fdfd7fa"
    },
    {
      "id": "67e8c088-814a-47df-9a46-e178bb990d59",
      "idempotency_key": "44f1121a-7806-46ce-8fbb-d6740036c53c"
    },
    {
      "id": "b8db325b-0671-41b2-9a49-18de8515fbe9",
      "idempotency_key": "0b5343e5-c13a-4b9e-9b66-9ab76d92ae5a"
    }
  ],
  "failed": []
}
{
  "id": "137a3849-f86c-4d5d-a5eb-57cf01e585ba",
  "object": "bulk_action",
  "target_object": "payment_order",
  "action": "create",
  "status": "executed",
  "total_items": 5,
  "total_successful": 3,
  "total_failed": 2,
  "processed_at": "2024-02-29T16:42:42.874712Z",
  "created_at": "2024-02-29T16:42:41.618789Z",
  "succeeded": [
    {
      "id": "fb9ca4d2-3fb4-4713-93e4-882d5d49ebb5",
      "idempotency_key": "577b4b79-d51d-4658-830c-c45fc173183f"
    },
    {
      "id": "fb9ca4d2-3fb4-4713-93e4-882d5d49ebb5",
      "idempotency_key": "1d0486d4-987b-48e4-a227-d43441763c0b"
    }, 
    {
      "id": "d31681d8-12fa-4a13-b88f-759bbc8e7c01",
      "idempotency_key": "e2de24d1-7e2e-4ac8-99e8-cf685fdfd7fa"
    }
  ],
  "failed": [
    {
      "error": "account not found",
      "idempotency_key": "44f1121a-7806-46ce-8fbb-d6740036c53c"
    },
    {
      "error": "account not found",
      "idempotency_key": "0b5343e5-c13a-4b9e-9b66-9ab76d92ae5a"
    }
  ]
}