# Run the workflow as a background process

**You’ll build a simple integration where a workflow is executed entirely in the background, without any user interface.** &#x20;

The example includes server-side code and shows how to create a workflow execution and run it programmatically in the background. The workflow executes asynchronously without rendering a user interface, and results can be retrieved via webhooks or API polling—making it easy to integrate into automated backend flows.

This approach is perfect for back-office processes like verifying business data, enriching records, or executing decision logic based on existing inputs—without interrupting the user journey or exposing a UI.

**Use this approach when:**

* No user input is needed to complete the workflow
* You're enriching existing records or verifying external data
* You want to automate internal or compliance-driven processes
* You're building batch jobs or backend workflows triggered by events

***

{% stepper %}
{% step %}

## Set up the server

### **Create a Workflow Execution**

**Add an endpoint on your server that creates a Workflow Execution**

{% hint style="danger" %}
We recommend creating a new execution each time a user starts a workflow, to ensure that the flow is fresh and state is isolated for every attempt.
{% endhint %}

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```javascript
const express = require('express');
const axios = require('axios');
const { v4: uuidv4 } = require('uuid');

const API_BASE = 'https://api.transactionlink.io';

// --- Recommended: organization token (tot_) ---
const ORG_TOKEN = process.env.ORG_TOKEN ?? 'tot_<your-organization-token>';

// --- Legacy: JWT — deprecated, will be removed in a future release ---
// const jwt = await axios.post(`${API_BASE}/auth/authorize`, { key, secret });
// const AUTH_HEADER = `Bearer ${jwt.data.accessToken}`;

const AUTH_HEADER = ORG_TOKEN; // recommended

const api = axios.create({ baseURL: API_BASE, headers: { Authorization: AUTH_HEADER } });

const app = express();
app.use(express.json());

app.post('/create-workflow-embedded', async (_req, res) => {
    const { data } = await api.post('/token', {
        recordId: uuidv4(),
        workflowDefinitionId: uuidv4(),
    });

    res.json({ token: data.token });
});

app.get('/workflow-status', async (req, res) => {
    const { data } = await api.get(`/workflows/${req.query.execution_id}`);

    res.json({ status: data.status, executionId: data.id });
});

app.listen(8080, () => console.log('Running on port 8080'));
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

## Get notified about workflow status

There are two ways to notify your backend when something happens in the workflow

#### 1. Webhook Task

You can add a **Webhook Task** directly in your workflow. This lets you send a custom HTTP POST request to your server at **any point** during the flow — with a payload you fully control.

Use it when:

* You want to notify your backend during a specific step in the process
* You need to trigger external logic or update another system
* You want to send dynamic data collected earlier in the flow
* You want to notify your server when the process is completed — with your own payload

{% hint style="info" %}
**Tip:** Place a Webhook Task at the end of the workflow to send a custom completion signal, including any relevant context or identifiers.
{% endhint %}

Both options can be used together or independently — depending on your use case.

#### 2. Polling the API (Long polling)

As an alternative, you can implement **long polling** from your backend. This involves periodically calling the TransactionLink API to check the status of a specific workflow execution.

While not real-time, long polling can be useful when:

* You cannot expose a public webhook endpoint
* Your infrastructure requires strict control over incoming connections
* You need fallback logic when webhooks are unavailable or blocked

{% hint style="danger" %}
Keep in mind: Webhooks (automatic or via task) are the recommended approach for real-time and scalable integration.
{% endhint %}
{% endstep %}

{% step %}

## Congratulations!

You’ve successfully set up a basic TransactionLink integration.

Now, learn how to **customize your workflow experience** — from styling the hosted page to configuring dynamic logic and automating data collection using workflow tasks and parameters.

{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.transactionlink.io/docs/workflows/quickstarts/run-the-workflow-as-a-background-process.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
