Integration Patterns

Frontend Recommendations

Learn the best patterns for displaying asynchronous bem results to your end-users in real-time and how to create a feedback loop for automated, user-driven fine-tuning.

Updated 8/9/2025

Once you have a robust backend architecture for receiving bem events, the next step is to present that data to your end-users. This article covers the recommended patterns for creating a real-time user experience and leveraging user feedback to continuously improve your bem Functions.

Displaying bem Results to End Users

Because bem processes data asynchronously, you need a mechanism to push results from your server to your frontend client in real-time. This ensures that a user sees the structured data as soon as it's ready, without needing to refresh the page.

A webhook is a server-to-server communication. The best practice is to establish a separate, real-time communication channel between your server and the user's browser.

Backend Implementation: After your webhook endpoint receives an event from bem and stores it, it should then publish a message to a real-time channel. This message should contain the referenceID and the structured data.

Frontend Implementation: Your frontend application subscribes to this channel. When a new message arrives with a matching referenceID for the data the user is viewing, the UI updates automatically.

Common Real-Time Communication Patterns:

  • WebSockets (e.g., Socket.IO): This is the gold standard for bidirectional, real-time communication. Your server can push events to the client, and the client can send messages back over the same persistent connection. This is ideal for highly interactive applications.
  • Server-Sent Events (SSE): SSE provides a simpler, one-way connection where the server can push data to the client. It's built on standard HTTP and is natively supported in modern browsers via the EventSource API, making it very easy to implement on the frontend if you only need server-to-client updates.
  • Third-Party Push Services (e.g., Pusher, Ably): For enterprise applications, using a managed service is often the most robust and scalable solution. These platforms handle the complexity of managing persistent connections at scale. Your backend receives the bem webhook and then uses the service's SDK to publish an event; your frontend client uses the same SDK to subscribe and receive the update.

Automated User-Driven Fine-Tuning

One of the most powerful features of bem is its ability to learn from user corrections. By allowing your operators or end-users to edit the structured data, you can create a continuous feedback loop that automatically fine-tunes your Functions, dramatically improving their accuracy over time.

This "human-in-the-loop" pattern is the key to achieving near-perfect automation.

How it Works:

  1. Display Data: Your frontend displays the structured data from bem in an editable form or table.
  2. User Corrects: A user notices an error (e.g., an incorrect line item) and edits the value in the UI.
  3. Send Correction to bem****: When the user saves their change, your frontend sends the unique identifier for the result (transformationID from the event payload) and the complete, corrected JSON object back to your backend. Your backend then makes a secure PUT request to the bem API.

Example: Sending a Correction to bem

Here is a frontend JavaScript example of how to send a correction from your application. Your frontend should send the correction to your own backend, which will then securely call the bem API.

1// The unique ID for the specific result the user is correcting.
2// You would get this from the 'transform' event payload.
3const transformationId = 'tr_2bxoJPNdSD4LgRT4YVC4gt72hlI';
4
5// The full, corrected JSON object after the user's edits.
6const correctedDataObject = {
7  "vendor_name": "Corrected Vendor Name Inc.",
8  "total_amount": 150.75,
9  "line_items": [
10    {
11      "item_description": "Product A - Corrected",
12      "quantity": 1,
13      "unit_price": 150.75
14    }
15  ]
16};
17
18// Your backend should expose an endpoint that will securely call the bem API.
19// This endpoint will receive the correction and forward it to bem.
20fetch('/api/bem/corrections', {
21  method: 'POST', // Your internal endpoint can be a POST
22  headers: {
23    'Content-Type': 'application/json',
24  },
25  body: JSON.stringify({
26    transformationID: transformationId,
27    correctedJSON: correctedDataObject,
28  }),
29})
30.then(response => {
31  if (response.ok) {
32    console.log('Correction submitted successfully!');
33    // Optionally show a success message to the user.
34  } else {
35    console.error('Failed to submit correction.');
36  }
37});

Your backend would then receive this payload and make a secure PUT request to the bem API at https://api.bem.ai/v1-beta/transformations. The body of this PUT request should be structured as follows:

1{
2  "transformations": [
3    {
4      "transformationID": "tr_2bxoJPNdSD4LgRT4YVC4gt72hlI",
5      "correctedJSON": {
6        "vendor_name": "Corrected Vendor Name Inc.",
7        "total_amount": 150.75,
8        "line_items": [
9          {
10            "item_description": "Product A - Corrected",
11            "quantity": 1,
12            "unit_price": 150.75
13          }
14        ]
15      }
16    }
17  ]
18}

Over time, these corrections will train a unique model tailored specifically to your data, driving accuracy higher and reducing the need for manual review.