# Running Pace Calculator (`mangudai/running-pace-calculator`) Actor

Calculate running pace, finish time and distance, build even or negative split tables, predict race times from 800 m to 50 km out of one result, and get VDOT training paces. Distances accept names like marathon or 10k. Pure offline math, no API key, no scraping.

- **URL**: https://apify.com/mangudai/running-pace-calculator.md
- **Developed by:** [Mangudäi](https://apify.com/mangudai) (community)
- **Categories:** Developer tools, Open source, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Running pace calculator

Work out running pace, finish time, distance and split times, predict race results at any distance from one performance, and get VDOT training paces. Everything is computed offline from your input. No API key, no login, no scraping, nothing to break.

Give it a distance and a time and it returns pace per kilometre, pace per mile, pace per 400 m, speed in km/h and mph, an estimated VDOT, and a split table. Give it a race result and it returns predicted times at 17 standard distances plus the five Daniels training zones.

### What it does

Seven calculation types, mixed freely in one run:

- `pace` gives pace and speed from a distance and a time.
- `time` gives finish time from a distance and a pace or speed.
- `distance` gives how far you go from a time and a pace or speed.
- `splits` builds a split table with even, negative or positive pacing.
- `predict` estimates race times at 800 m through 50 km from one result.
- `training` returns easy, marathon, threshold, interval and repetition paces.
- `convert` turns any pace or speed into every other representation.

### Input

One object per calculation in the `calculations` array.

```json
{
  "calculations": [
    { "type": "pace", "distance": "marathon", "time": "3:45:00", "splitEvery": 5, "unit": "km" },
    { "type": "time", "distance": 10, "unit": "km", "pace": "4:30", "paceUnit": "min/km" },
    { "type": "splits", "distance": "half marathon", "time": "1:45:00", "splitEvery": 5, "strategy": "negative", "strategyPercent": 2 },
    { "type": "predict", "distance": "5k", "time": "22:30" },
    { "type": "training", "distance": "5k", "time": "22:30" },
    { "type": "convert", "pace": "8:00", "paceUnit": "min/mi" }
  ]
}
```

Field notes:

- `distance` takes a number with `unit` (km, mi, m, yd, ft) or a name: marathon, half marathon, 10k, 5k, mile, 1500m, 10 mile, 50k and more.
- `time` takes `3:45:00`, `22:30`, `1h30m15s`, `90m` or a plain number of seconds.
- `pace` takes `4:30` with `paceUnit` set to min/km or min/mi. A plain number is read as minutes.
- `speed` takes a number with `speedUnit` of kph, mph or m/s.
- `splitEvery` sets the split interval in the calculation's unit, so 5 with unit km means 5 km splits.
- `strategy` is even, negative or positive, and `strategyPercent` sets how far the first and last splits sit from the average.
- `weightKg` adds an estimated calorie burn to every row.

Run-level settings cover all calculations: `includeSplits`, `maxSplits`, `predictionMethod`, `riegelExponent` and `weightKg`.

### Output

One row per result. Summary rows carry the headline numbers, split rows carry one split each, prediction rows carry one target distance each, and training rows carry one zone each.

| Field | Meaning |
| --- | --- |
| `type`, `rowType`, `label` | Which calculation and which kind of row |
| `distance`, `unit`, `distanceKm`, `distanceMiles`, `distanceMeters` | Distance in the requested unit and in every common unit |
| `time`, `timeSeconds` | Elapsed time |
| `pacePerKm`, `pacePerMile`, `pacePer400m` | Pace in mm:ss |
| `speedKph`, `speedMph`, `speedMps` | Speed |
| `splitNumber`, `splitTime`, `cumulativeTime` | Split table columns |
| `vdot`, `vo2max` | Estimated VDOT and oxygen cost |
| `intensityPercent`, `paceRange` | Training zone intensity and its pace band |
| `predictionMethod`, `timeRiegel`, `timeCameron`, `timeVdot` | All three prediction models side by side |
| `caloriesBurned` | Estimate, only when `weightKg` is set |
| `error` | Filled when one calculation fails, the rest still run |

### How the numbers are worked out

Pace, speed and split arithmetic are exact. Predictions use three published models so you can compare them:

- Riegel: `T2 = T1 * (D2 / D1) ^ 1.06`. The exponent is adjustable.
- Cameron: an empirical fit that holds from roughly 400 m to 50 km.
- VDOT: the Daniels and Gilbert oxygen-cost model, solved for the time at the target distance that gives the same VDOT as your input performance.

Training paces come from inverting the same oxygen-cost curve at each zone's share of VDOT. Against the published VDOT tables the model lands within a few seconds: VDOT 60 predicts a 35:22 10K, VDOT 50 predicts a 3:10:40 marathon.

These are estimates from one performance. Weather, hills, fitness on the day and how well you paced the effort all move the real result.

### Use cases

- Build a pace band or wrist chart for a goal race.
- Check what a recent parkrun or time trial implies for a half marathon or marathon.
- Set training paces for a block without hunting through a printed table.
- Convert treadmill speed into outdoor pace.
- Generate split tables in bulk for a running club, a coaching sheet or a pace group.

### Pricing

Pay per result. You are charged for the rows the run produces and nothing else.

# Actor input Schema

## `calculations` (type: `array`):

One object per calculation. Set "type" to pace, time, distance, splits, predict, training or convert. Distances accept a number with "unit", or a name such as marathon, half marathon, 10k, 5k or mile. Times accept 3:45:00, 22:30 or 1h30m15s. Paces accept 4:30 with "paceUnit" of min/km or min/mi.

## `includeSplits` (type: `boolean`):

Add a row per split for pace and time calculations. Set "splits": false on a single calculation to turn it off there.

## `maxSplits` (type: `integer`):

Guard against very small split intervals. A calculation that would produce more splits than this returns an error row instead.

## `predictionMethod` (type: `string`):

Which model fills the headline predicted time. Riegel and Cameron times and the VDOT equivalent are always returned as extra columns.

## `riegelExponent` (type: `number`):

Fatigue exponent for the Riegel model. 1.06 is the classic value. Well trained runners often sit near 1.05, less trained runners near 1.08.

## `weightKg` (type: `number`):

Optional. When set, each row gets an estimated calorie burn. Leave empty to skip it.

## Actor input object example

```json
{
  "calculations": [
    {
      "type": "pace",
      "label": "Marathon goal pace",
      "distance": "marathon",
      "time": "3:45:00",
      "splitEvery": 5,
      "unit": "km"
    },
    {
      "type": "time",
      "label": "10K at 4:30 per km",
      "distance": 10,
      "unit": "km",
      "pace": "4:30",
      "paceUnit": "min/km",
      "splits": false
    },
    {
      "type": "splits",
      "label": "Half marathon negative split",
      "distance": "half marathon",
      "time": "1:45:00",
      "splitEvery": 5,
      "strategy": "negative",
      "strategyPercent": 2
    },
    {
      "type": "predict",
      "label": "Race times from a 22:30 5K",
      "distance": "5k",
      "time": "22:30"
    },
    {
      "type": "training",
      "label": "Training paces from a 22:30 5K",
      "distance": "5k",
      "time": "22:30"
    },
    {
      "type": "convert",
      "label": "8:00 per mile in other units",
      "pace": "8:00",
      "paceUnit": "min/mi"
    }
  ],
  "includeSplits": true,
  "maxSplits": 200,
  "predictionMethod": "riegel",
  "riegelExponent": 1.06
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "calculations": [
        {
            "type": "pace",
            "label": "Marathon goal pace",
            "distance": "marathon",
            "time": "3:45:00",
            "splitEvery": 5,
            "unit": "km"
        },
        {
            "type": "time",
            "label": "10K at 4:30 per km",
            "distance": 10,
            "unit": "km",
            "pace": "4:30",
            "paceUnit": "min/km",
            "splits": false
        },
        {
            "type": "splits",
            "label": "Half marathon negative split",
            "distance": "half marathon",
            "time": "1:45:00",
            "splitEvery": 5,
            "strategy": "negative",
            "strategyPercent": 2
        },
        {
            "type": "predict",
            "label": "Race times from a 22:30 5K",
            "distance": "5k",
            "time": "22:30"
        },
        {
            "type": "training",
            "label": "Training paces from a 22:30 5K",
            "distance": "5k",
            "time": "22:30"
        },
        {
            "type": "convert",
            "label": "8:00 per mile in other units",
            "pace": "8:00",
            "paceUnit": "min/mi"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mangudai/running-pace-calculator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "calculations": [
        {
            "type": "pace",
            "label": "Marathon goal pace",
            "distance": "marathon",
            "time": "3:45:00",
            "splitEvery": 5,
            "unit": "km",
        },
        {
            "type": "time",
            "label": "10K at 4:30 per km",
            "distance": 10,
            "unit": "km",
            "pace": "4:30",
            "paceUnit": "min/km",
            "splits": False,
        },
        {
            "type": "splits",
            "label": "Half marathon negative split",
            "distance": "half marathon",
            "time": "1:45:00",
            "splitEvery": 5,
            "strategy": "negative",
            "strategyPercent": 2,
        },
        {
            "type": "predict",
            "label": "Race times from a 22:30 5K",
            "distance": "5k",
            "time": "22:30",
        },
        {
            "type": "training",
            "label": "Training paces from a 22:30 5K",
            "distance": "5k",
            "time": "22:30",
        },
        {
            "type": "convert",
            "label": "8:00 per mile in other units",
            "pace": "8:00",
            "paceUnit": "min/mi",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("mangudai/running-pace-calculator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "calculations": [
    {
      "type": "pace",
      "label": "Marathon goal pace",
      "distance": "marathon",
      "time": "3:45:00",
      "splitEvery": 5,
      "unit": "km"
    },
    {
      "type": "time",
      "label": "10K at 4:30 per km",
      "distance": 10,
      "unit": "km",
      "pace": "4:30",
      "paceUnit": "min/km",
      "splits": false
    },
    {
      "type": "splits",
      "label": "Half marathon negative split",
      "distance": "half marathon",
      "time": "1:45:00",
      "splitEvery": 5,
      "strategy": "negative",
      "strategyPercent": 2
    },
    {
      "type": "predict",
      "label": "Race times from a 22:30 5K",
      "distance": "5k",
      "time": "22:30"
    },
    {
      "type": "training",
      "label": "Training paces from a 22:30 5K",
      "distance": "5k",
      "time": "22:30"
    },
    {
      "type": "convert",
      "label": "8:00 per mile in other units",
      "pace": "8:00",
      "paceUnit": "min/mi"
    }
  ]
}' |
apify call mangudai/running-pace-calculator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=mangudai/running-pace-calculator",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/w91FG93fxr7W43aKt/builds/hRGEU6F5FlEoEqg7W/openapi.json
