# Typing Speed API
> Measure typing speed and accuracy. Compute words-per-minute, characters-per-minute and accuracy from a character (or word) count and the elapsed time, optionally subtracting uncorrected errors for a net WPM; compare what was typed against a reference text to count per-character mistakes and score the attempt; and estimate how long a given amount of text will take at a target speed. Uses the standard typing convention that one word equals five characters. Perfect for typing tests and games, coding-speed tools, onboarding and skills assessments, and leaderboards. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 4 endpoints. A focused typing calculator, distinct from general unit or percentage maths.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/wpm-api/..."
```

## Pricing
- **Free** (Free) — 1,145 calls/Mo, 2 req/s
- **Starter** ($2/Mo) — 9,850 calls/Mo, 8 req/s
- **Pro** ($22/Mo) — 149,500 calls/Mo, 20 req/s
- **Mega** ($60/Mo) — 790,000 calls/Mo, 50 req/s

## Endpoints

### Typing

#### `GET /v1/from-text` — WPM + accuracy from typed text

**Parameters:**
- `typed` (query, required, string) — What was typed Example: `the quick brown fox`
- `reference` (query, optional, string) — The target text Example: `the quick brown fox`
- `time_seconds` (query, required, string) — Elapsed seconds Example: `15`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/wpm-api/v1/from-text?typed=the+quick+brown+fox&reference=the+quick+brown+fox&time_seconds=15"
```

**Response:**
```json
{
    "data": {
        "cpm": 76,
        "errors": 0,
        "net_wpm": 15.2,
        "gross_wpm": 15.2,
        "characters": 19,
        "time_seconds": 15,
        "accuracy_percent": 100,
        "correct_characters": 19
    },
    "meta": {
        "timestamp": "2026-06-03T01:09:40.195Z",
        "request_id": "4f5f302b-f6c2-4de8-bdf7-5475bb791dec"
    },
    "status": "ok",
    "message": "WPM + accuracy from typed text",
    "success": true
}
```

#### `GET /v1/time` — Time to type N words

**Parameters:**
- `words` (query, required, string) — Number of words Example: `100`
- `wpm` (query, required, string) — Target WPM Example: `50`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/wpm-api/v1/time?words=100&wpm=50"
```

**Response:**
```json
{
    "data": {
        "wpm": 50,
        "words": 100,
        "minutes": 2,
        "seconds": 120
    },
    "meta": {
        "timestamp": "2026-06-03T01:09:40.279Z",
        "request_id": "798acdbc-407a-416b-96ca-e58738fd74fb"
    },
    "status": "ok",
    "message": "Time to type N words",
    "success": true
}
```

#### `GET /v1/wpm` — WPM from characters + time

**Parameters:**
- `characters` (query, optional, string) — Typed characters (or use words) Example: `300`
- `words` (query, optional, string) — Typed words (alternative)
- `time_seconds` (query, required, string) — Elapsed seconds Example: `60`
- `errors` (query, optional, string) — Uncorrected errors

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/wpm-api/v1/wpm?characters=300&time_seconds=60"
```

**Response:**
```json
{
    "data": {
        "cpm": 300,
        "errors": 0,
        "net_wpm": 60,
        "gross_wpm": 60,
        "characters": 300,
        "time_seconds": 60,
        "accuracy_percent": 100
    },
    "meta": {
        "timestamp": "2026-06-03T01:09:40.369Z",
        "request_id": "229709c7-c5a6-41e3-ac26-78382201b507"
    },
    "status": "ok",
    "message": "WPM from chars + time",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/wpm-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "name": "Typing Speed API",
        "notes": "Gross WPM = (characters / 5) / minutes. Net WPM subtracts uncorrected errors per minute. Nothing is stored.",
        "version": "v1",
        "endpoints": [
            {
                "path": "/v1/wpm",
                "params": {
                    "errors": "uncorrected errors (optional)",
                    "characters": "typed chars (or words)",
                    "time_seconds": "elapsed seconds (required)"
                },
                "returns": "gross/net WPM, CPM, accuracy"
            },
            {
                "path": "/v1/from-text",
                "params": {
                    "typed": "what was typed (required)",
                    "reference": "the target text (optional)",
                    "time_seconds": "required"
                },
                "returns": "WPM and accuracy, counting per-character errors"
            },
            {
                "path": "/v1/time",
                "params": {
                    "wpm": "required",
                    "words": "required"
                },
                "returns": "minutes/seconds to type that many words"
            },
            {
                "path": "/v1/meta",
                "params": [],
                "returns": "this document"
            }
        ],
        "description": "Calculate typing speed and accuracy. Get words-per-minute, characters-per-minute and accuracy from a character count and 
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/wpm-api
OpenAPI spec: https://www.oanor.com/api/wpm-api/openapi.json
