---
name: typosuggest
description: Self-serve AI agent skill to provision a free TypoSuggest account over HTTP, index project items/products/pages, and wire up sub-millisecond typo-tolerant & phonetic autocomplete search (<1ms p99) via widget.js, REST API, or MCP.
homepage: https://typosuggest.pial.digital
---

# TypoSuggest — Agent Skill (`skill.md`)

You are reading the agent execution playbook for **TypoSuggest** (`https://typosuggest.pial.digital`), an in-memory, typo-tolerant and phonetic (including Banglish/South Asian transliteration) autocomplete search engine with `<1ms` median latency.

Everything — account registration, API key provisioning, dataset ingestion, and search verification — works **directly over plain HTTP JSON**. No browser login is required to get started.

Base URL: `https://typosuggest.pial.digital`

---

## End-to-End Agent Workflow (4 Steps)

When your human asks you to **"add TypoSuggest search to my website/app"** or **"set up TypoSuggest"**, execute these 4 steps in order:

### Step 1: Register an Account & Provision API Keys (`POST /v1/auth/register`)

 Check if `TYPOSUGGEST_PUBLIC_KEY`, `TYPOSUGGEST_SECRET_KEY`, and `TYPOSUGGEST_DATASET_ID` already exist in the project's `.env` file. If not, register a free account in one HTTP request:

```bash
curl -sS -X POST https://typosuggest.pial.digital/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My App Search",
    "email": "dev@example.com",
    "password": "ReplaceWithStrongPassword123!"
  }'
```

*Tip for agents:* If the human hasn't given an email address, either ask them which email they want for their dashboard login (`https://typosuggest.pial.digital/dashboard`) or generate a clean project email + strong password and **print both clearly in your final summary** so they can log in later.

**Response (`201 Created`):**

```json
{
  "token": "eyJhbG...",
  "starter_dataset_id": "550e8400-e29b-41d4-a716-446655440000",
  "secret_key": "ac_sec_...",
  "public_key": "ac_pub_...",
  "tenant": {
    "id": "...",
    "name": "My App Search",
    "email": "dev@example.com",
    "plan_tier": "free",
    "max_datasets": 2,
    "max_rows": 2500,
    "max_monthly_queries": 10000
  }
}
```

**What you get immediately (active in 0ms, no email verification required to use the API):**
- `starter_dataset_id` — Ready-to-use dataset UUID (`my-first-dataset`) warmed in RAM.
- `secret_key` (`ac_sec_...`) — **Server-side only.** Use for ingesting, updating, and deleting items, or authenticating MCP tools. Never expose `ac_sec_...` in client-side browser code.
- `public_key` (`ac_pub_...`) — **Safe for browsers & mobile apps.** Read-only key restricted strictly to `GET /v1/suggest` and `widget.js`.

Save these in the project's `.env` (and `.env.example` with placeholders):
```env
TYPOSUGGEST_DATASET_ID=550e8400-e29b-41d4-a716-446655440000
TYPOSUGGEST_PUBLIC_KEY=ac_pub_...
TYPOSUGGEST_SECRET_KEY=ac_sec_...
```

---

### Step 2: Ingest the Project's Searchable Items (`POST /v1/datasets/{dataset_id}/items:add`)

Inspect the user's codebase (database seed files, product catalogs, markdown docs, routes, or JSON data) to gather the items that should be searchable, then push them using the `secret_key`:

```bash
curl -sS -X POST "https://typosuggest.pial.digital/v1/datasets/${TYPOSUGGEST_DATASET_ID}/items:add" \
  -H "X-API-Key: ${TYPOSUGGEST_SECRET_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "id": "prod-1", "text": "Samsung Galaxy S24 Ultra", "group": "Smartphones", "count": 500 },
      { "id": "prod-2", "text": "Apple iPhone 16 Pro Max", "group": "Smartphones", "count": 480 },
      { "id": "prod-3", "text": "Sony WH-1000XM5 Wireless Headphones", "group": "Audio", "count": 320 }
    ]
  }'
```

You can also pass a simple string array if you don't need custom IDs or groups:
```json
{
  "texts": ["Samsung Galaxy S24 Ultra", "Apple iPhone 16 Pro Max"]
}
```

**Field limits & rules:**
- `id` (optional): Custom item/SKU identifier (`<= 128` chars). Passing an existing `id` or `text` upserts/increments the item cleanly.
- `text` (required): Searchable phrase (`1–300` chars).
- `group` (optional): Category label shown in the autocomplete dropdown (`<= 64` chars, defaults to `"item"`).
- `count` (optional): Popularity/ranking weight (`0–1,000,000`). Higher `count` ranks higher when prefixes tie.
- Batch limit: Up to `25,000` items per HTTP request (`Free` tier holds up to `2,500` items across `2` datasets; `Pro` tier `$9/mo` holds `25,000` items across `10` datasets).

---

### Step 3: Verify Typo-Tolerant Search (`GET /v1/suggest`)

Test the live index with an intentional typo using the `public_key`:

```bash
curl -sS "https://typosuggest.pial.digital/v1/suggest?dataset_id=${TYPOSUGGEST_DATASET_ID}&q=samsng+galxy&limit=5" \
  -H "X-API-Key: ${TYPOSUGGEST_PUBLIC_KEY}"
```

**Response (`200 OK`):**
```json
{
  "dataset_id": "550e8400-e29b-41d4-a716-446655440000",
  "query": "samsng galxy",
  "results": [
    {
      "id": "prod-1",
      "text": "Samsung Galaxy S24 Ultra",
      "group": "Smartphones",
      "score": 890
    }
  ],
  "took_ms": 0.18,
  "cached": false,
  "degraded": false
}
```

---

### Step 4: Wire Up the Frontend (Widget or Custom Fetch)

Choose **Option A** for an instant drop-in dropdown UI, or **Option B** if the project already has a custom React/Vue/Next.js/Tailwind search component.

#### Option A: 1-Line Drop-In Widget (`widget.js` — 1.8 KB gzipped, zero dependencies)

Add this `<script>` tag to the HTML `<head>` or before `</body>`:

```html
<script
  src="https://typosuggest.pial.digital/widget.js"
  data-key="ac_pub_YOUR_PUBLIC_KEY"
  data-dataset="YOUR_DATASET_ID"
  data-input="#search-input"
  data-limit="6"
  defer
></script>
```

- If `data-input` is omitted, `widget.js` automatically binds to `input[type="search"]` or `input[data-typosuggest]`.
- When a user selects a suggestion (click or `Enter`), the input element dispatches a custom `typosuggest:select` event with `event.detail` containing `{ id, text, group, score }`:
  ```javascript
  document.querySelector('#search-input')?.addEventListener('typosuggest:select', (e) => {
    console.log('Selected item:', e.detail); // { id, text, group, score }
  });
  ```

#### Option B: Direct Fetch (`React` / `Next.js` / `Vue` / `Svelte` / `Mobile`)

Call `GET https://typosuggest.pial.digital/v1/suggest` directly from the browser using your `public_key` (CORS `*` is enabled globally):

```javascript
async function fetchSuggestions(query) {
  if (!query.trim()) return [];
  const params = new URLSearchParams({
    dataset_id: process.env.NEXT_PUBLIC_TYPOSUGGEST_DATASET_ID,
    q: query,
    limit: '8',
  });
  const res = await fetch(`https://typosuggest.pial.digital/v1/suggest?${params}`, {
    headers: { 'X-API-Key': process.env.NEXT_PUBLIC_TYPOSUGGEST_PUBLIC_KEY },
  });
  if (!res.ok) return [];
  const data = await res.json();
  return data.results; // [{ id, text, group, score }]
}
```

---

## Keeping Items in Sync (CRUD Endpoints)

All write endpoints require `X-API-Key: ac_sec_...` (or `Authorization: Bearer ac_sec_...`):

| Operation | Method & Path | Example JSON Payload |
| :--- | :--- | :--- |
| **Create Dataset** | `POST /v1/datasets` | `{"name": "blog-posts", "typo_tolerance": true}` |
| **Add / Upsert Items** | `POST /v1/datasets/{dataset_id}/items:add` | `{"items": [{"id": "1", "text": "iPhone 16", "group": "Phones", "count": 50}]}` |
| **Update Item** | `PUT /v1/datasets/{dataset_id}/items:update` | `{"id": "1", "new_text": "iPhone 16 Pro", "group": "Phones", "count": 90}` |
| **Delete Items** | `POST /v1/datasets/{dataset_id}/items:delete` | `{"ids": ["1"]}` or `{"texts": ["iPhone 16 Pro"]}` |
| **List Items** | `GET /v1/datasets/{dataset_id}/items?q=&page=1&limit=25` | *(Query params)* |
| **Dataset Stats** | `GET /v1/datasets/{dataset_id}/stats` | *(Returns `active_phrases`, `memory_bytes`, `typo_tolerance`)* |

---

## Native MCP Server (`/mcp`)

TypoSuggest exposes a stateless **Model Context Protocol (MCP)** JSON-RPC 2.0 server at `https://typosuggest.pial.digital/mcp`.

Connect Claude Code in one command using your `secret_key`:

```bash
claude mcp add --transport http typosuggest https://typosuggest.pial.digital/mcp \
  --header "X-API-Key: ac_sec_YOUR_SECRET_KEY"
```

Or add to `.cursor/mcp.json` / `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "typosuggest": {
      "url": "https://typosuggest.pial.digital/mcp",
      "headers": {
        "X-API-Key": "ac_sec_YOUR_SECRET_KEY"
      }
    }
  }
}
```

**Available MCP Tools:**
- `list_datasets` — List all datasets, item counts, and RAM stats for your account.
- `create_dataset` — Provision a new dataset (`name`, `typo_tolerance`).
- `ingest_texts` — Bulk ingest phrases into a dataset (`dataset_id`, `texts`, `group`).
- `delete_items` — Remove items by `texts` or `ids` (`dataset_id`, `texts`, `ids`).
- `test_suggest` — Run a live typo-tolerant autocomplete query (`dataset_id`, `query`, `limit`).

---

## Further Machine-Readable Specs

- **LLM Overview:** `https://typosuggest.pial.digital/llms.txt`
- **Full Technical Reference:** `https://typosuggest.pial.digital/llms-full.txt`
- **OpenAPI 3.1 Spec:** `https://typosuggest.pial.digital/openapi.yaml`
- **Interactive Docs:** `https://typosuggest.pial.digital/docs`
- **Developer Console:** `https://typosuggest.pial.digital/dashboard`
