Numerology REST API reference · v1
The numerology API: every number in a name, from one request.
The Simple Numerology API turns a name and a birthdate into a complete Pythagorean chart — core numbers, karmic lessons and debts, planes of expression, pinnacles, challenges and life cycles — as 47 JSON fields. It also computes personal cycles and compatibility.
The API follows REST conventions. Requests and responses are JSON, authentication is a single header, and every error has the same shape, with a stable code, the offending param and a request_id. You can start calling it with a free key in under a minute.
From the example used throughout this reference: María Stefania García López, born 12 March 1990.
Authentication
Send an API key on every authenticated request, in the X-API-Key header: X-API-Key: nk_live_…. Keys start with nk_live_, so secret scanners like GitHub's can recognise one that leaks, and so can you.
Once your email is verified (see Account & billing), create keys from the dashboard: one per environment is a good habit, so you can roll or revoke one without touching the others. A request with a missing, revoked or expired key returns 401 and uses no quota.
A key is shown once. It is stored only as a SHA-256 hash, so it can't be displayed again. Lost it? Sign in to the dashboard, create a new key and revoke the old one.
Keep keys on your server. Anyone who has one can spend your quota, so don't put it in a mobile app or in JavaScript that runs in the browser. The API deliberately sends no CORS headers, so browsers refuse to call it cross-origin. Call it from your backend and pass the result on.
Errors
The API uses conventional HTTP status codes: 2xx means success, 4xx means the request needs changing, and 5xx means something on our side failed. Every error has the same shape:
- error.typeenum
The broad class to branch on.
invalid_request_errorauthentication_errorpermission_errorquota_exceeded_errorrate_limit_errorapi_error - error.codestring
The specific reason. Stable. Every code is listed below.
- error.messagestring
A sentence for a developer. The wording may change, so don't match on it.
- error.paramstring | null
The field at fault, when there is one. For example
first_nameorcharts.3.birthdate. - error.doc_urlstring
A link to this code's entry below.
- error.request_idstring
The same value as the
X-Request-Idheader. Quote it to support.
Validation errors (422) also carry error.errors, with one {param, message} entry per invalid field.
Error codes
| Status | Code | What to do |
|---|---|---|
| 400 | bad_request | The body is not valid JSON, or the request is malformed in some other way. |
| 400 | api_version_invalid | The Numerology-Version header names a version that doesn't exist. See Versioning. |
| 400 | confirmation_mismatch | The confirm_email sent to delete an account doesn't match the account's email. |
| 400 | signature_invalid | A webhook failed Stripe signature verification. Only Stripe sees this. |
| 401 | api_key_missing | No key was sent. Add the X-API-Key header. |
| 401 | api_key_invalid | The key is unknown, revoked or expired. Don't retry with the same key. |
| 401 | authentication_required | This call needs a dashboard session or a live key, and neither was sent. |
| 401 | session_required | Key management and account deletion need a signed-in dashboard session. An API key isn't enough. |
| 402 | card_declined | The card was declined while changing plan. Update it in the billing portal and try again. |
| 402 | quota_exceeded | This period's quota is used up, or a batch needs more than what's left. Upgrade, enable overage, or wait for X-Quota-Reset. |
| 403 | forbidden | The request was refused — for a dashboard write, usually a missing or stale CSRF token. Reload the page and try again. |
| 403 | captcha_failed | The demo's captcha token was rejected, expired or already used. Solve the captcha again. |
| 404 | resource_missing | No such route, or no such key on this account. |
| 415 | unsupported_media_type | Send the body as JSON, with Content-Type: application/json. |
| 405 | method_not_allowed | The route exists but not for this HTTP method. |
| 409 | already_subscribed | Use POST /v1/subscription instead of starting a second subscription. |
| 409 | subscription_conflict | There's no subscription to change or cancel, or it's already on that plan and interval with nothing to undo. |
| 409 | no_subscription | The billing portal needs a subscription. Subscribe first. |
| 409 | key_limit_reached | An account can hold 20 active keys. Revoke one first. |
| 409 | overage_unavailable | Overage needs an active paid plan. |
| 413 | body_too_large | Request bodies are limited to 256 KB. Split large batches. |
| 422 | parameter_invalid | A field failed validation: a date that isn't YYYY-MM-DD, a name with no letters or over 100 characters, or an unknown field. See param. |
| 429 | rate_limited | Too many requests in a short window. Wait the number of seconds in Retry-After. |
| 500 | internal_error | Our fault, and we're alerted. Retry with backoff and quote the request_id if it persists. |
| 503 | billing_unavailable | Stripe couldn't be reached or isn't configured. Charts are unaffected. |
| 503 | captcha_unavailable | The demo's captcha couldn't be checked with Cloudflare. Try again shortly. |
| 503 | email_unavailable | The support email couldn't be sent. Try again shortly. |
| 503 | webhook_unconfigured | Server-side configuration. Only Stripe sees this. |
Handling errors
Retry automatically on 429, 500 and 503. On a 429, wait for the Retry-After value. Every other 4xx returns the same result until you change the request or the account.
Versioning
The API is versioned by date. The current version is 2026-10-26, and requests without a Numerology-Version header use it. Every chart response echoes the version it used in the Numerology-Version header and in api_version.
Additive changes, like new endpoints, new optional parameters or new response fields, ship to every version. Anything that could change an existing answer, such as a calculation rule, a field's type or an error's status, ships as a new version. Send the header on every request to keep your integration on the version you tested:
Numerology-Version: 2026-10-26
Versions before 2026-10-26 also open every chart, cycles and compatibility response with livemode, now always true: test-mode keys no longer exist.
Version 2026-09-26 returns the chart flat: the person's fields, planes and bridges at the top level, and pinnacles, challenges and life cycles as first_pinnacle … third_life_cycle with a pinnacle_challenge_age_ranges string, and adds chart_text, the chart as printable text.
Every change is listed in the changelog. Deprecated endpoints answer with Deprecation and Sunset headers at least six months before removal.
Quotas & rate limits
Two separate limits apply to each account.
- The quota is the number of requests your plan includes per month. Each chart, cycles or compatibility call uses one, and a batch uses one per chart. When it runs out you get
402, or, with overage enabled, the extra is billed. - The rate limit is how many requests per second your plan allows, counted over a sliding one-second window. It is generous enough for batch work and backfills, and stops a runaway loop within a second. A batch counts as one request here. Going over returns
429rate_limitedwithRetry-After.
Both limits count across all of our servers. Reading your account with GET /v1/account never uses quota. We email the account at 80% and 100% of the quota, once each per period.
| Plan | Requests / month | Requests / second | Monthly | Annual |
|---|---|---|---|---|
| Free | 100 | 5 | $0, no card | — |
| Starter | 10,000 | 25 | $19 | $190 |
| Pro | 100,000 | 100 | $99 | $990 |
Response headers
| Header | Value |
|---|---|
X-Quota-Limit | Requests your plan includes per period. |
X-Quota-Remaining | Requests left in the current period. |
X-Quota-Reset | When the period resets, as an ISO 8601 timestamp in UTC. |
X-Overage-Used | Requests served above the quota this period, when overage is on. |
RateLimit-Limit | Requests your plan allows per second. |
RateLimit-Remaining | Requests left in the current one-second window. |
RateLimit-Reset | Seconds until the window has room again. |
Retry-After | Sent with 429: seconds to wait before retrying. |
X-Request-Id | On every response. Send your own (a UUID) to trace a call end to end. |
A monthly plan's quota resets on its renewal date. Free and annual plans reset every 30 days. The count starts again at zero when you change plan.
Overage
By default the quota is a hard limit: at 100% you get 402. On a paid plan you can turn on overage from the dashboard (PATCH /v1/account/settings {"overage_enabled": true}). Requests then keep succeeding past the quota, up to a monthly cap, and the extra is billed in arrears on your next invoice at the rate in /v1/plans.
| Plan | Overage cap per month |
|---|---|
| Starter | 50,000 requests |
| Pro | 500,000 requests |
It's off unless you turn it on, so nobody gets a bill they didn't agree to. X-Overage-Used shows the running total.
Calculation conventions
Numerology traditions disagree on several rules. These are the defaults this API uses. They're frozen as part of the API contract, because changing one would silently change every chart you've already stored.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|
| A | B | C | D | E | F | G | H | I |
| J | K | L | M | N | O | P | Q | R |
| S | T | U | V | W | X | Y | Z |
Vowels are shaded. By default Y is never one.
- Vowels are A, E, I, O and U only. Y is always a consonant, so "Lynn" adds nothing to the soul urge number.
- Accents are folded, not dropped. "María" is read as "maria". Spaces, hyphens and apostrophes are ignored, so compound surnames like "García López" work as written.
- Name numbers sum the whole name at once and then reduce. They don't reduce each name separately first.
- Middle names count toward the full-name numbers (destiny, soul urge, personality, balance, karmic lessons). First-name numbers like active and cornerstone ignore them.
Master numbers 11, 22 and 33 are kept. Many fields documented as integer can return a two-digit value. Don't assume a 1–9 range. Karmic debts 13, 14, 16 and 19 appear only in karmic_debt_numbers.
Opting into other conventions
Two rules are genuinely contested, so any chart request can choose differently with options. The response always echoes the rules it used in conventions, so a stored chart records how it was computed.
- options.y_ruleenumOptional
consonant(default).vowel: always a vowel.both: counts in both sums.contextual: a vowel unless it sits next to A/E/I/O/U in the same name, so "Lynn" and "Kylie" count it but "Yolanda" and "Raymond" don't. The rule looks at spelling, not pronunciation, so the result is always the same for the same input. - options.name_reductionenumOptional
whole_name(default), orper_name: reduce each name first, then add (the Decoz method). "Sarah Lee" is 33 whole and 6 per name. - options.transliterationenumOptional
none(default): a Latin letter with no A–Z base, like ø, ł, ß or æ, contributes nothing.latin: those letters are rewritten first: ø → o, ł → l, ß → ss, æ → ae, œ → oe, đ/ð → d, þ → th and ı → i. The chart still echoes the name as you sent it. Cyrillic is never transliterated. It has its own table (below).
Cyrillic names
Cyrillic letters are valued with the Russian numerology table: the 33-letter alphabet in order, numbered 1–9 in repeating rows. No option is needed, and names can mix scripts.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|
| А | Б | В | Г | Д | Е | Ё | Ж | З |
| И | Й | К | Л | М | Н | О | П | Р |
| С | Т | У | Ф | Х | Ц | Ч | Ш | Щ |
| Ъ | Ы | Ь | Э | Ю | Я |
- Ё is its own letter (7), not Е (6). "Ёлка" and "Елка" are different names here, so send the spelling the person uses.
- Ъ and Ь count (1 and 3). Й is a consonant.
- Russian only. Letters from other Cyrillic alphabets, such as Ukrainian Ї, Є and Ґ or Serbian Ј, are refused with
422rather than skipped. - The planes of expression and intensity points are defined over the Latin alphabet and English letter frequencies. They're
nullfor names containing Cyrillic, rather than computed from an invented mapping.
Every chart includes computed_name, the letters it was actually computed from. Check it to see whether anything was ignored: "Søren" gives sren without transliteration and soren with it.
Charts
The chart object
A chart is computed on request and never stored. Sending the same name, birthdate and options always returns the same chart, so cache it on your side when that saves quota.
Every chart starts with object: "chart", system, api_version, conventions (the rules that produced it) and computed_name (the letters it was computed from).
Number fields are integers. Most are 1–9, some can be a master number (11, 22, 33), and a few can be 0 when a name has nothing to count, such as a first name with no vowels.
Attributes
- life_path_numberinteger
The full birthdate, reduced. The most widely used number in the chart.
- destiny_numberinteger
Every letter of the full birth name, summed and reduced. Also called the expression number.
- soul_urge_numberinteger
The vowels of the full name. Also called the heart's desire.
- personality_numberinteger
The consonants of the full name.
- karmic_debt_numbersarray of integers
Any of 13, 14, 16 or 19 passed through while reducing a core number. Usually empty.
Person 1 object
- person.first_namestring
As sent, accents included.
- person.middle_namestring
As sent, or an empty string.
- person.last_namestring
As sent.
- person.birthdatestring
YYYY-MM-DD.
Name numbers 9 fields
- active_numberinteger
All letters of the first name. Keeps master numbers.
- growth_numberinteger
Same letters as
active_number, always reduced to 1–9. - heritage_numberinteger
All letters of the last name.
- cornerstone_numberinteger
The first letter of the first name.
- capstone_numberinteger
The last letter of the first name.
- first_vowel_numberinteger
The first vowel of the first name, or
0if there is none. - balance_numberinteger
The initial of every name, each part of a compound surname included.
- subconscious_self_numberinteger
9 minus the number of karmic lessons: how many of the nine digits the full name contains.
- hidden_passion_numberarray of integers
The digit that occurs most often in the full name. Always a list, even with one value: when several digits tie for the highest count, all of them are returned, in ascending order, because tradition gives no rule to pick one. Ties are common, for example
[5, 7]for Yvette Young or[1, 2, 7, 9]for Ray Kay Kim. Empty only for a name with no countable letters. Readhidden_passion_number[0]if you display a single value, but expect more.
Birthdate numbers 6 fields
- birth_day_numberinteger
Day of birth, reduced. Keeps master numbers.
- birth_month_numberinteger
Month of birth, reduced.
- birth_year_numberinteger
Year of birth, reduced.
- attitude_numberinteger
Day plus month, reduced to 1–9.
- maturity_numberinteger
Life path plus destiny, reduced. Keeps master numbers.
- rational_thought_numberinteger
Day of birth plus the letters of the first name, reduced to 1–9.
Letter frequency 4 fields
- full_name_number_countsarray of objects
How many letters of the full name map to each digit: nine
{number, count}entries, 1 to 9 in order, with a count of0for digits the name lacks. Version2026-09-26returns an object keyed by the digits as strings instead, since JSON object keys cannot be integers. - karmic_lesson_numbersarray of integers
Digits 1–9 that no letter of the full name maps to.
- full_name_missing_numbersarray of integers
Same values as
karmic_lesson_numbers, under the name some sources use. - intensity_pointsarray of integers
Digits that occur more often than average for a name of typical length.
Planes & bridges 2 objects
- planes_of_expressionobject
The full name's letters by plane:
physical(D, E, W and M),mental(A, G, H, J, L, N and P),emotional(B, I, O, R, S, T, X and Z) andintuitive(C, F, K, Q, U, V and Y). Each is an integer,0when the name has none of its letters, andnullfor names in Cyrillic. - bridgesobject
life_path_expression, the difference between life path and destiny, andsoul_urge_personality, between soul urge and personality. Both 0–8.
Life stages 3 arrays
- pinnaclesarray of stages
The four pinnacles, in order. Each stage is
{stage, number, from_age, to_age}; the last hasto_agenull. Pinnacles keep master numbers. - challengesarray of stages
The four challenges, at the same ages as the pinnacles. Numbers are 0–8, and a challenge of
0is valid. - life_cyclesarray of stages
Three stages: month, day and year of birth, each reduced. The first ends with the first pinnacle.
Create a Pythagorean chart
Computes a full chart from a name and a birthdate. Each successful call uses one request from your quota. Validation errors don't.
Body parameters
- first_namestringRequired
Given name as it appears on the birth certificate. Must contain a letter. Up to 100 characters.
- last_namestringRequired
Family name. Compound surnames can be sent as one string:
"García López". - birthdatestringRequired
Date of birth as
YYYY-MM-DD. - middle_namestringOptional
One or more middle names, separated by spaces. They count toward the full-name numbers.
- optionsobjectOptional
y_ruleandname_reduction. See Calculation conventions.
Unknown fields are rejected with 422 rather than ignored, so a typo like middle_nme can't quietly produce a different chart.
Returns
A chart object, with quota and rate-limit headers.
Batch charts
Up to 100 charts in one request, all with the same options. A batch costs one request per chart, all or nothing: if it doesn't fit in what's left of your quota, nothing is computed or charged. Every item is validated before any is computed, so a batch never half-succeeds. It counts as one request toward the rate limit.
Body parameters
- chartsarrayRequired
1 to 100 people, each with
first_name,last_name,birthdateand optionalmiddle_name. - optionsobjectOptional
As for a single chart, applied to every item.
Returns
A list object: {"object": "list", "count", "data": [{"index", "chart"}]}, in request order.
Cycles & compatibility
Personal cycles
Where a person stands on a given day: their personal and universal year, month and day, and the Pinnacle, Challenge and Life Cycle in force at their age. Costs one request.
Body parameters
- birthdatestringRequired
YYYY-MM-DD. - datestringOptional
The day to compute for. Defaults to today in UTC. "Today" depends on your user's time zone, so send their local date when it matters. Must be on or after
birthdate. - years_aheadintegerOptional
0–10. Also list the personal year for each of the next N years.
Rules
The personal year is birth month + birth day + calendar year, each reduced, then added and reduced to 1–9. It runs January to December. The personal month adds the calendar month, and the personal day adds the day. Cycle numbers are always 1–9, because they index a nine-year cycle.
Compatibility
Compares two people's Life Path, Expression, Soul Urge, Personality and Birthday numbers, and returns a 0–100 score. Costs one request.
Body parameters
- aobjectRequired
A person:
first_name,last_name,birthdate, optionalmiddle_name. - bobjectRequired
The other person.
- optionsobjectOptional
As for charts.
The method
Numerology has no single compatibility table, so the rule is stated here and applied mechanically (method: "families-polarity-v1"). Numbers are compared by their single-digit root, and grouped into three families: 1-5-7, 2-4-8 and 3-6-9.
| Relationship | When | Score |
|---|---|---|
natural | Different numbers, same family | 90 |
same | The same number | 80 |
neutral | Different families, both odd or both even | 60 |
challenging | Different families, one odd and one even | 35 |
The overall score weights Life Path 35%, Expression 25%, Soul Urge 20%, Personality 10% and Birthday 10%. It's the same whichever person is a. rating is strong (75+), good (60+), mixed (45+) or challenging.
Account
Retrieve your account
Returns the plan and usage for the account that owns the calling key. It never uses quota, so it's safe to call before a large batch to check you have room.
Returns
- account_idstring
Prefixed
acct_. - planenum
The plan currently being served, which is Free while a paid plan is unpaid past its grace period.
freestarterpro - statusstring
active,past_duewhile a failed payment is retried, orcanceled. - key_id · key_prefix—
Which key made the call, redacted.
- monthly_quota · quota_remaining · quota_resets_at—
The quota.
Account & billing
Everything else happens in the dashboard: sign up with GitHub, Google or an email and password, create, roll and revoke keys, subscribe or change plan, turn on overage, and export or delete your data. These are the endpoints behind it. Their request and response schemas are in the OpenAPI document.
| Endpoint | Authenticate with | Does |
|---|---|---|
GET /v1/plans | Nothing | Every plan with its quotas and prices, to build your own pricing table. |
GET /v1/me | Session | The account, both usage counters, overage settings and every key. |
GET · POST /v1/keys | Session | List keys, or create one (name, mode). Up to 20 active. The secret is shown once. |
POST /v1/keys/{id}/roll | Session | Replace a key. With expire_in_hours (up to 168) the old one keeps working while you deploy. |
DELETE /v1/keys/{id} | Session | Revoke a key at once. |
PATCH /v1/account/settings | Session | Turn overage on or off. |
POST /v1/checkout | Session or live key | Start a subscription (plan, interval) through Stripe Checkout. |
POST /v1/subscription | Session or live key | Change plan. An upgrade applies at once, a downgrade at the end of the paid period. |
DELETE /v1/subscription | Session or live key | Cancel. The plan keeps working until the paid period ends, then the account returns to Free. |
POST /v1/portal | Session or live key | A link to the Stripe customer portal: card, invoices, cancellation. |
GET /v1/account/export | Session | Everything stored about the account, as JSON. |
DELETE /v1/account | Session | Delete the account with every key, after reporting any unbilled overage. |
Key management, export and deletion need a signed-in session, so a leaked API key can't mint new keys or delete the account. Writes made with the session send the csrftoken cookie's value as X-CSRFToken.
Your keys stay the same through every plan change: only the quota behind them moves. If a payment fails, the paid quota keeps working for 14 days while Stripe retries, then requests are served at the Free quota until an invoice is paid. For anything else, contact support and quote the request_id of the call in question.
More
OpenAPI & Postman
The API is plain HTTPS and JSON, so any HTTP client works: see the quickstarts for Python and JavaScript. To generate a typed client instead, use the OpenAPI document below.
The full contract is published as OpenAPI 3.1. Generate a client from it, or import the ready-made Postman collection. The generated schema browser lets you try every endpoint.
MCP server
The API ships with a Model Context Protocol server, so Claude and other assistants can compute charts directly. It calls this same HTTP API with your key, so quota and rate limits apply as usual.
- get_numerology_charttool
A Pythagorean chart, as readable text or as JSON.
- get_personal_cyclestool
Personal year, month and day for a date.
- get_compatibilitytool
The compatibility score for two people.
- get_account_statustool
The plan and remaining quota. Uses no quota.
- numerology://conventionsresource
The calculation conventions, so the assistant can explain a number correctly.
Errors reach the assistant as instructions rather than bare status codes. For example, a 402 tells it to point the user at pricing, and a 429 tells it how many seconds to wait.