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

# Steps

> How steps are saved, found again, and replayed.

## Four kinds of steps

| Step | What it does |
| - | - |
| [`step.run`](https://docs.nelkap.com/reference/step-run) | Runs a piece of work once, and saves what it returns. |
| [`step.sleep`](https://docs.nelkap.com/reference/step-sleep) | Pauses the run for a duration. |
| [`step.wait`](https://docs.nelkap.com/reference/step-wait) | Pauses the run until an event arrives. |
| [`step.score`](https://docs.nelkap.com/reference/step-score) | Records a score of the run. |

## How a step is found again

On each call, the SDK matches your steps to the saved ones by kind and name, in the order your code reaches them. So a name can repeat: the second `step.run('send')` gets the second saved `send`.

A sleep takes its duration as its name, and a wait takes its key.

## Keep the path the same

Code outside steps runs again on each call, so it must take the same path every time. Anything that can change between two calls, like the time, a random ID, or an API response, goes in a step:

```ts theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
const invoiceId = await nelkap.step.run('invoice id', () => crypto.randomUUID());
```

## Results are saved as JSON

A step returns what its function returned, passed through JSON. A `Date` comes back as a string, and `undefined` as `null`. The first call gets the same value as every call after it.

## Loops and parallel steps

Steps work in loops. Each batch below is saved on its own, so a load that stops goes on from the last batch that made it:

```ts theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
for (const [index, batch] of batches.entries()) {
  await nelkap.step.run(`batch ${index}`, () => importRows(batch));
}
```

Steps also run side by side. They're saved in the order your code calls them:

```ts theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
const [profile, orders] = await Promise.all([
  nelkap.step.run('profile', () => getProfile(userId)),
  nelkap.step.run('orders', () => getOrders(userId)),
]);
```

## Steps in your own functions

You can call `nelkap.step` from any function your workflow calls. The SDK finds the run on its own.

## When you change a workflow

Runs already underway match their saved steps by name, not by position. A step you add or rename runs as a new step.


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