> ## Documentation Index
> Fetch the complete documentation index at: https://boxrouter.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How Actions Works

> Follow a GitHub job from queued to finished, see who pays for it, and learn what does and does not persist.

GitHub schedules your workflow. For each eligible job, BoxRouter starts a sandbox and requests its deletion when the job ends.

![GitHub queues a job and tells the BoxRouter App. BoxRouter checks it and picks a route. A sandbox starts and its runner registers once. The runner runs the steps and logs go to GitHub. BoxRouter requests cleanup; when confirmed, the sandbox is deleted. A failed check refuses the job and nothing starts.](https://mintcdn.com/nv-4965711d/RMVlH8Z1jdQT60zr/images/diagrams/actions-job-light.svg?fit=max\&auto=format\&n=RMVlH8Z1jdQT60zr\&q=85\&s=01962b65de73d6312722c03c03e8e1f0)

![GitHub queues a job and tells the BoxRouter App. BoxRouter checks it and picks a route. A sandbox starts and its runner registers once. The runner runs the steps and logs go to GitHub. BoxRouter requests cleanup; when confirmed, the sandbox is deleted. A failed check refuses the job and nothing starts.](https://mintcdn.com/nv-4965711d/RMVlH8Z1jdQT60zr/images/diagrams/actions-job-mobile-light.svg?fit=max\&auto=format\&n=RMVlH8Z1jdQT60zr\&q=85\&s=aae24cfaee3eecc3fcf1b7c8c84dd0fe)

Each job gets its own sandbox. This diagram shows cleanup when deletion is confirmed.

## One Job, Start to Finish

1. GitHub queues a job with a `boxrouter-…` label in `runs-on` and notifies the BoxRouter App.
2. BoxRouter checks the job before starting anything. If a check fails, the run panel shows the reason and no sandbox starts. [Troubleshooting](https://boxrouter.ai/docs/actions/troubleshooting.md#refusals) lists the refusal codes.
   * The repository is private and turned on.
   * The trigger is a push, dispatch or same-repository pull request.
   * The label is a supported BoxRouter label.
   * A provider key or Credits can pay for it.
3. BoxRouter picks an eligible route for the runner label using your [routing settings](https://boxrouter.ai/docs/routing-settings.md). The [run page](https://boxrouter.ai/docs/actions/runs.md) shows the provider and size.
4. BoxRouter asks GitHub for a runner registration valid for this one job.
5. A sandbox starts from the BoxRouter runner image, and the GitHub runner inside it registers with that credential.
6. GitHub assigns the job to that runner, which runs your steps and streams logs to GitHub.
7. When the job ends, BoxRouter records the result and requests sandbox cleanup. Check its cleanup status on the [run page](https://boxrouter.ai/docs/actions/runs.md).

## Who Keeps What

| GitHub Keeps | BoxRouter Provides |
| - | - |
| The workflow, its logs, and step output | The sandbox the job runs in |
| Artifacts and caches | A run record: provider, size, timeline, sandbox link |
| Repository and environment secrets | The job's one-time runner registration |
| Approvals, concurrency, matrices | Cleanup of the sandbox after the job |
| The job's result | The job's cost, from the provider's usage |

## Who Pays

A job's sandbox is paid like any other sandbox, for as long as it exists. On your provider key, the provider bills your account, and BoxRouter adds no fee. On Credits, BoxRouter charges your balance.

If no connected provider key or Credits can pay for a job, BoxRouter refuses it before any sandbox
starts, with the reason `funding_unavailable`. If Credits or a [spend limit](https://boxrouter.ai/docs/spend-limits.md) can't
cover the job, the reason is `insufficient_credit` or `spend_limit_exceeded`.

Your routing settings decide which key, Credits and provider are tried first; the `runs-on` label cannot change who pays. See [Routing settings](https://boxrouter.ai/docs/routing-settings.md) and [Cost](https://boxrouter.ai/docs/cost.md). The permissions behind the runner registration are in [Connect GitHub](https://boxrouter.ai/docs/github/connect.md#permissions).

## Cancel, Re-Run, and Failures

* Cancelling a run requests that GitHub stop it. Check the run's status and the sandbox's cleanup in the run panel.
* A re-run starts a new attempt in a new sandbox.
* A failing step is a workflow failure that GitHub shows.
* A BoxRouter or provider fault shows as a BoxRouter failure; see [Troubleshooting](https://boxrouter.ai/docs/actions/troubleshooting.md#during-and-after-a-job).

## What Persists between Jobs

Each job gets a fresh sandbox. Files, installed tools and environment changes from one job do not carry into the next. Check the run's cleanup status to confirm the old sandbox was deleted.

| To Keep | Use |
| - | - |
| Dependencies and build output | `actions/cache`, or a setup action's built-in cache such as `actions/setup-node` with `cache: npm` |
| Files for a later job or download | `actions/upload-artifact` |
| Installed tools | Install them in each job, or cache their download |

GitHub's cache service stores the data, so GitHub's scopes, size limits, and expiry apply. A cache saved from one provider restores on another.

A restore downloads from GitHub, so its speed depends on the network between the provider and GitHub. The data must fit the sandbox's free disk. Check free space with `df -h` before restoring a large cache.

## Next Steps

> [card] [Find a Run](https://boxrouter.ai/docs/actions/runs.md)
>
> Follow a run, its sandbox, and its cost.

> [card] [How Actions Security Works](https://boxrouter.ai/docs/actions/security.md)
>
> Which jobs run and what they can reach.

> [card] [Troubleshoot Actions](https://boxrouter.ai/docs/actions/troubleshooting.md)
>
> Fix a refused label or a queued job.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.