---
title: Unified Reading API
description: A public, read-only API for date-only numerology and astrology calculations. No authentication, nothing stored.
canonical: https://unifiedreading.com/docs
last-updated: 2026-10-24
---

# Unified Reading API

Unified Reading has a small public API for the calculations that need only a birth date: the Life Path number, the Western Sun sign and the Chinese zodiac animal, plus the Lunar New Year table behind the Chinese zodiac. It is read-only, needs no API key and stores nothing. The combined personal reading is only available through the [website form](https://unifiedreading.com/), where the person enters their own details.

- Base URL: `https://unifiedreading.com/api/v1`
- OpenAPI 3.1 spec: [https://unifiedreading.com/openapi.json](https://unifiedreading.com/openapi.json)
- API catalog (RFC 9727): [https://unifiedreading.com/.well-known/api-catalog](https://unifiedreading.com/.well-known/api-catalog)
- Authentication: none. See [auth.md](https://unifiedreading.com/auth.md).
- MCP server with the same calculation: `https://unifiedreading.com/mcp`, listed in the [official MCP registry](https://registry.modelcontextprotocol.io/v0/servers/com.unifiedreading%2Funified-reading/versions/latest) as `com.unifiedreading/unified-reading`
- Agent resources: the public [emrecolako/unified-reading](https://github.com/emrecolako/unified-reading) repo has the SDK source, [AGENTS.md](https://github.com/emrecolako/unified-reading/blob/main/AGENTS.md), agent skills (`npx skills add emrecolako/unified-reading`) and an [Agent Plugins](https://github.com/emrecolako/unified-reading/blob/main/plugin.json) manifest.
- JavaScript SDK and CLI: [`unified-reading` on npm](https://www.npmjs.com/package/unified-reading) (`npx unified-reading profile 1990-07-14`)

## SDK and CLI

The [`unified-reading`](https://www.npmjs.com/package/unified-reading) npm package wraps every endpoint, with TypeScript types and no dependencies ([source](https://github.com/emrecolako/unified-reading/tree/main/sdk)).

```bash
npx unified-reading profile 1990-07-14
npx unified-reading year 1990
```

The same package runs a stdio MCP server that bridges to `https://unifiedreading.com/mcp`, for MCP clients that only launch local commands:

```json
{ "mcpServers": { "unified-reading": { "command": "npx", "args": ["-y", "unified-reading", "mcp"] } } }
```

```js
import { UnifiedReading } from "unified-reading";
const profile = await new UnifiedReading().profile("1990-07-14");
```

## GET /api/v1/profile

Query parameter `date` (required): the birth date as `YYYY-MM-DD`, from 1900 up to today. Send only the date, never a name, birth time or place.

```bash
curl "https://unifiedreading.com/api/v1/profile?date=1990-07-14"
```

Response (shortened):

```json
{
  "date": "1990-07-14",
  "lifePath": { "number": 4, "title": "The Builder", "guide": "https://unifiedreading.com/life-path/4" },
  "sunSign": { "sign": "Cancer", "decan": 3, "element": "Water", "modality": "Cardinal", "rulingPlanet": "Moon" },
  "chineseZodiac": { "animal": "Horse", "element": "Metal", "yinYang": "Yang" },
  "notes": ["The Sun sign assumes midday; ..."],
  "fullReading": "https://unifiedreading.com/#details"
}
```

- Master numbers 11, 22 and 33 are kept, not reduced.
- The Chinese animal follows the Lunar New Year date for the birth year, not January 1.
- The Sun sign assumes midday, so a birth on a sign change day may fall in the neighbouring sign.

## POST /api/v1/profiles/batch

The same profile for up to 20 dates in one call, in request order. An invalid date fails only its own item.

```bash
curl -X POST "https://unifiedreading.com/api/v1/profiles/batch" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2a4e-9d1b-4c55-8a0e-1d2f3b4c5d6e" \
  -d '{"dates": ["1990-07-14", "1990-01-20"]}'
```

Each item is `{ "date", "ok": true, "profile" }` or `{ "date", "ok": false, "error": { "code": "invalid_date", "message" } }`. The calculation has no side effects, so retrying is always safe. An optional `Idempotency-Key` header (1-255 visible ASCII characters) is validated and echoed back, so a client can match a retry to its first attempt.

## GET /api/v1/chinese-zodiac/years

Every zodiac year from 1924 to 2044 with its animal, stem element, yin-yang, and the dates it starts (Lunar New Year) and ends (the day before the next one).

```bash
curl "https://unifiedreading.com/api/v1/chinese-zodiac/years?limit=12"
```

The response is `{ "data": [...], "has_more", "next_cursor", "next", "total" }`. Pages hold 12 years by default (`limit` 1-60). Pass `next_cursor` back as `cursor`, or follow the `Link: <...>; rel="next"` header, until `has_more` is `false`.

## Site search (NLWeb)

`/ask` answers [NLWeb](https://github.com/nlweb-ai/NLWeb) 0.55 queries in list mode with a keyword search over the public pages (guides, calculators, pricing, docs). Results are schema.org items with `name`, `description` and `url`.

```bash
curl -X POST https://unifiedreading.com/ask -H "Content-Type: application/json" \
  -d '{"query": {"text": "life path 7 meaning"}}'
```

Add `"prefer": {"streaming": true}` (or `Accept: text/event-stream`) for SSE `start`, `result` and `complete` events. `GET /ask?query=...&streaming=true` works too. No match returns a `NO_RESULTS` failure. Queries are not logged.

## Rate limits

All endpoints share a budget of 10 requests per minute per IP. Every response carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds) headers; a `429` adds `Retry-After`.

## Errors

Every error is JSON with a stable code, a message and a hint:

```json
{ "error": { "code": "invalid_date", "message": "date must be a real YYYY-MM-DD date from 1900 up to today.", "hint": "Use a zero-padded calendar date such as 1990-07-14.", "status": 400, "docs": "https://unifiedreading.com/docs" } }
```

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `missing_parameter` | No `date` query parameter. |
| 400 | `invalid_date` | Not a real date, before 1900, or in the future. |
| 400 | `invalid_body` | Batch body is not JSON with 1-20 `dates`, or `limit` is out of range. |
| 400 | `invalid_cursor` | `cursor` is not a year in the table. |
| 400 | `invalid_idempotency_key` | `Idempotency-Key` is empty, too long or not visible ASCII. |
| 404 | `not_found` | No endpoint at that `/api/` path. |
| 405 | `method_not_allowed` | Wrong method for the endpoint. |
| 429 | `rate_limited` | More than 10 requests per minute from one IP; wait for `Retry-After` seconds. |

## Versioning and deprecation policy

- The version is in the path (`/api/v1`) and in the `X-API-Version` response header.
- Within v1, fields and endpoints may be added, never removed or renamed. Clients should ignore fields they do not know.
- A breaking change ships under a new path (`/api/v2`). The old version keeps working for at least 90 days after the replacement is announced on this page.
- During that window every response from the old version carries a `Deprecation` header ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745)) with the announcement date, a `Sunset` header ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594)) with the shutdown date, and a `Link: <...>; rel="successor-version"` header.
- No version is deprecated today.

## Testing

There is no separate sandbox: the API is free, read-only and has no side effects, so the production endpoint is safe to test against. Use a fictional date.
