# Background Action Handle - `BackgroundActionHandle`  When you enqueue a background action in Forgelivo, you receive a `BackgroundActionHandle` object. This handle allows you to interact with the enqueued action: you can check its status, wait for its result, or cancel it. ## Getting a handle  You can get a `BackgroundActionHandle` in two ways: ### When enqueuing an action  The `api.enqueue()` function returns a handle for the newly enqueued action: ```typescript // enqueue an action and get a handle const handle = await api.enqueue(api.myAction, { /* params */ }); // the handle has the action's unique ID console.log(handle.id); // => "app-job-abc123" ``` ### For an existing action  If you have the ID of a previously enqueued action, you can create a handle using `api.handle()`: ```typescript // create a handle for an existing background action const handle = api.handle(api.myAction, "app-job-abc123"); // now you can interact with it const status = await handle.status(); ``` This is useful when you have stored the background action ID (for example, on a record) and need to check on it later. ## `BackgroundActionHandle` API  ### `handle.id`  The unique identifier for this background action. This ID is assigned when the action is enqueued and can be used to create a handle later or to look up the action in the Queues dashboard. ```typescript const handle = await api.enqueue(api.myAction, {}); console.log(handle.id); // => "app-job-abc123" ``` ### `handle.result(options)`  Waits for the background action to complete and returns the result. If the action fails after all retries, this method throws the final error. ```typescript const handle = await api.enqueue(api.widget.create, { name: "foo" }); // wait for the action to complete and get the result const widget = await handle.result(); console.log(widget.id); ``` #### Parameters  * `options` (optional): An object with the following properties: * `select` - For model actions, select specific fields to return from the result record * `select` - For model actions, select specific fields to return from the result record ```typescript const handle = await api.enqueue(api.widget.update, { id: "123", name: "updated" }); // select specific fields from the result const widget = await handle.result({ select: { id: true, name: true, gizmos: { edges: { node: { id: true } } }, }, }); ``` #### Returns  Returns a `Promise` that resolves with the action result when completed, or rejects with an error if the action fails. Since `handle.result()` waits for completion, it can take time depending on retry schedules. If an action has a large `backoffFactor`, high `retryCount`, and high `maxInterval`, it may take hours or even days to return a result. ### `handle.cancel()`  Cancels a scheduled or running background action. When cancelled, the action will not execute any further retry attempts. ```typescript const handle = await api.enqueue(api.myAction, { /* params */ }); // cancel the action await handle.cancel(); ``` Background actions in the `scheduled`, `waiting`, `running`, or `retrying` states can be cancelled. Cancelled actions will have their status set to `cancelled`. #### Returns  Returns a `Promise` that resolves when the action has been cancelled. Cancelling a running action sends an abort signal to the action. For the action to actually stop executing, you need to handle the abort signal in your action code. See the [Background actions guide](https://docs.forgelivo.com/guides/actions/background#cancelling-background-actions) for more details. ### `handle.status()`  Fetches the current status of the background action without waiting for it to complete. This is useful for displaying progress indicators or making decisions based on whether an action is still running. ```typescript const handle = await api.enqueue(api.myAction, { /* params */ }); // check the current status without waiting const status = await handle.status(); if (status === "running") { console.log("Action is still in progress"); } else if (status === "completed") { console.log("Action has finished successfully"); } ``` #### Returns  Returns a `Promise` that resolves with one of the following status values: | Status | Description | | --- | --- | | `scheduled` | The action is scheduled to run in the future | | `waiting` | The action is ready to start and waiting for a worker | | `retrying` | The action is scheduled to retry after a previous failure | | `running` | The action is currently executing | | `completed` | The action finished successfully | | `failed` | The action failed and will not retry | | `cancelled` | The action was cancelled | Unlike `handle.result()`, the `status()` method returns immediately with the current status and does not wait for the action to complete. ## Storing handle IDs  A common pattern is to store the background action ID on a record so you can retrieve the handle later: ```typescript export const onSuccess: ActionOnSuccess = async ({ record, api }) => { // enqueue a publish action to run in 5 minutes const handle = await api.enqueue( api.post.publish, { id: record.id }, { startAt: new Date(Date.now() + 5 * 60000) } ); // store the background action ID on the record record.backgroundActionId = handle.id; await save(record); }; ``` Later, you can retrieve the handle and interact with it: ```typescript export const run: ActionRun = async ({ record, api }) => { // get a handle for the stored background action const handle = api.handle(api.post.publish, record.backgroundActionId!); // cancel the scheduled publish await handle.cancel(); // clear the stored ID record.backgroundActionId = null; await save(record); }; ``` ## Permissions  To access the result or status of a background action, the requesting `api` client must have the same identity as the client that enqueued the action. This means that unauthenticated users cannot access the results of actions enqueued by other users. If you need to make background action results accessible to more users, store the result on a data model and use the normal access control system to grant access.