Using bulk actions

Bulk actions enable you to create or modify multiple objects in a single API request. 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 will result in the creation of an asynchronous bulk action This endpoint requires an object_type (e.g. payment_order) an action (e.g., create) and an array of items. Each item will represent the object to perform an action on:

  • When creating objects, each entry must use the same body params as the corresponding endpoint to create individual objects (such as “Create payment order”)
  • When applying actions on existing objects (such as “approve” or “cancel”), each entry must contain the id property (UUID) of the existing object, and the same body params as the corresponding endpoint to apply this action individually (such as “Cancel payment order”)

Each item on the list can contain an individual idempotency_key attribute to prevent it from being processed by Numeral multiple times. This will also help identify successful and failed executions in the subsequent webhook events and API calls.

Below are API request examples:

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 '
{
  "object_type": "payment_order",
  "action": "create",
  "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
    }
  ]
}
'
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 '
{
  "object_type": "payment_order",
  "action": "approve",
  "items": [
    {
      "idempotency_key": "373ac951-f125-4bb7-ac49-9ff64e0d75ea",
      "id": "20f74528-4a1c-4317-90d8-f4dcee36517f"
    },
    {
      "idempotency_key": "801907b7-6b8f-4adf-b09c-2736d2089f23",
      "id": "2518df4d-d1e2-444c-9da1-51e13c5ec170"
    }
  ]
}
'

Below is an 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 endpoint can be used to retrieve updates as part of the Retrieve a bulk action endpoint.

While optional, this endpoint will give details about 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 type = “executed” event will notify you when to optimally fetch the results of this bulk action.

Please note that individual events related to the underlying items of the bulk action will also be triggered.

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"
    }
  ]
}