Skip to content

Getting Started ​

You will make your first authenticated request in about two minutes. There are three steps: register, copy your API key, call an endpoint.

The base URL is https://api.harshitbishnoi.dev. Running the API locally instead? Swap it for http://localhost:3000.

1. Register a developer account ​

bash
curl -X POST https://api.harshitbishnoi.dev/auth/register \
  -H 'content-type: application/json' \
  -d '{
    "email": "alice@example.com",
    "password": "a-long-passphrase",
    "name": "Alice"
  }'

Passwords must be at least 8 characters. The response is 201 Created:

json
{
  "success": true,
  "data": {
    "user": {
      "id": "0f1c…",
      "email": "alice@example.com",
      "name": "Alice",
      "tier": "free",
      "isAdmin": false,
      "isActive": true,
      "createdAt": "2026-07-09T10:00:00.000Z"
    },
    "apiKey": {
      "id": "7ba2…",
      "label": "Default",
      "key": "exdb_XEtT1o…"
    }
  }
}

Copy the key now

apiKey.key is the only time the plaintext key is ever returned. The server stores a SHA-256 hash of it and cannot show it to you again. If you lose it, create a new key with POST /me/keys and revoke the old one.

2. Make your first call ​

Send the key in an x-api-key header:

bash
curl https://api.harshitbishnoi.dev/exercises?limit=2 \
  -H "x-api-key: exdb_XEtT1o…"

An Authorization: Bearer exdb_… header works identically, if that fits your HTTP client better.

json
{
  "success": true,
  "data": [
    {
      "id": "8c1e5a10-0000-4000-8000-000000000001",
      "slug": "barbell-back-squat",
      "name": "Barbell Back Squat",
      "status": "active",
      "category": "strength",
      "difficulty": "intermediate",
      "movementPattern": "squat",
      "tags": ["compound", "lower-body"],
      "updatedAt": "2026-06-15T10:00:00.000Z"
    }
  ],
  "pagination": { "limit": 2, "offset": 0 }
}

List endpoints return summaries. Fetch GET /exercises/{id} for the full record — instructions, coaching cues, contraindications, mechanics, and programming data.

Every catalog, sync, account, and billing endpoint requires a key. The only exceptions are GET /health, POST /auth/register, and POST /auth/login.

3. Understand your quota ​

The free tier allows 1,000 requests per day, reset at midnight UTC. Every response carries your current standing:

HeaderMeaning
X-RateLimit-LimitRequests allowed per day on your tier
X-RateLimit-RemainingRequests left today
X-RateLimit-ResetISO 8601 timestamp when the quota resets

Exceed it and you get 429 Too Many Requests with a Retry-After header giving the seconds to wait.

Errors ​

Every error is RFC 9457 Problem Details with content type application/problem+json:

json
{
  "type": "https://docs.harshitbishnoi.dev/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "limit must be less than or equal to 100",
  "instance": "/exercises?limit=500",
  "code": "VALIDATION_ERROR",
  "requestId": "485fa7dd-03b1-44e1-ae56-6b88d13b652b"
}

Branch on code — it is stable. detail is written for humans and may be reworded. type is a stable URI identifying the error class.

requestId also comes back in the X-Request-Id header. Quote it when you report a problem: on a 5xx the detail is deliberately generic, and the request id is the only way to find the server log line behind it.

Where next ​

Read the API reference for every endpoint, parameter, and response shape.

If you are building a mobile app, do not call the API on every screen. Sync the catalog into a local database once, then refresh only what changed. The sync guide walks through the whole loop.

Released under the MIT License.