API
Changelog
Last updated 23 October 2026
Every change to the public API, newest first. Breaking changes ship as a new
dated API version, chosen per request with the Numerology-Version header.
Deprecated endpoints answer with Deprecation and Sunset headers at least
six months before they are removed.
Unreleased
Removed — interpretations
The API no longer returns meaning text. Chart, batch, cycles and
compatibility requests no longer take expand or lang, and a request that
sends either now answers 422 parameter_invalid, like any unknown field.
Responses no longer carry interpretations, and Accept-Language is ignored.
The numbers themselves are unchanged in every API version.
- The Python and JavaScript SDKs (2.0.0) drop the
expandandlangarguments, and the TypeScript types dropinterpretations. - The MCP server's
get_numerology_chartandget_personal_cyclestools no longer takeinterpretationsorlanguage.
Changed — rate limits per second, by plan
The rate limit on the chart, batch, cycles and compatibility endpoints was 60
requests a minute on every plan. It is now counted per second, over a sliding
window, and set by the plan: 5 a second on Free, 25 on Starter and 100 on
Pro. Batch work and backfills no longer hit 429 after a minute's worth of
calls, and a loop gone wrong is stopped within a second. A batch still counts
as one request.
Every paid response now carries RateLimit-Limit (requests per second on your
plan), RateLimit-Remaining and RateLimit-Reset (seconds until the window
has room), and a 429 rate_limited still carries Retry-After. GET
/v1/plans lists each plan's requests_per_second.
Removed — Authorization: Bearer for API keys
API keys are accepted only in the X-API-Key header. A request that sends
its key as Authorization: Bearer nk_live_… is now treated as having no key
and answers 401 api_key_missing. The official SDKs and the MCP server
already send X-API-Key, so they need no change. A 401 from the API now
challenges with WWW-Authenticate: X-API-Key realm="numerology".
Removed — test mode, and version 2026-10-26
Test-mode keys are gone: every key is an nk_live_… key and spends the plan's
monthly quota. Test keys that existed are revoked and answer 401
api_key_invalid; their test-mode usage history is deleted. Give each
environment its own key instead, so one can be rolled or revoked alone.
- New version
2026-10-26, now the current one. Chart, batch, cycles and compatibility responses no longer carrylivemode. Versions2026-10-22and2026-09-26still do, alwaystrue. PinNumerology-Version: 2026-10-22to keep the field while you update. GET /v1/accountno longer returnslivemode,test_quotaortest_quota_remaining, andGET /v1/plansno longer returnstest_quota.POST /v1/keysno longer takesmode, and keys no longer have one.GET /v1/medropstest_usageand renameslive_usagetousage.- Billing endpoints (
/v1/checkout,/v1/subscription,/v1/portal) accept any API key, and thelivemode_key_requirederror no longer exists. - The JavaScript SDK (1.1.0) types
livemodeas optional.
Changed — compressed chart responses
/v1/charts/pythagorean, /v1/charts/batch, /v1/cycles, /v1/compatibility
and /v1/demo answer with Content-Encoding: gzip when the request sends
Accept-Encoding: gzip, and with Vary: Accept-Encoding. A batch of 100
charts arrives about ten times smaller. Requests without that header get the
same uncompressed JSON as before. The Python SDK (1.1.0) asks for compression
and keeps its connection open between calls.
Removed — sign-up and sign-in endpoints
Accounts now sign up with GitHub, Google, or an email and a password at /accounts/signup/. The
address is confirmed with an emailed code, and the pages under /accounts/
handle signing in, password resets and sessions. These endpoints are gone:
POST /v1/signup, POST /v1/auth/login, POST /v1/auth/verify,
POST /v1/auth/logout and POST /v1/auth/logout-all, along with the
token_invalid error. The first API key is no longer issued when the address
is confirmed: create keys from the dashboard (POST /v1/keys). Accounts
created with emailed links have no password yet, so set one with "Forgot your
password?" on the sign-in page, or sign in with GitHub or Google using the same
address. Signing up with GitHub or Google needs no code. GET /v1/account/export
now also lists open sessions, with the IP address and browser of each, and any
connected GitHub or Google account.
New — pay without leaving the site
POST /v1/checkout takes an optional ui_mode. The default, hosted, works
as before and answers the checkout_url to redirect to. elements answers a
client_secret instead (and checkout_url: null), with which Stripe.js draws
the payment form (the Payment Element) in your own page. Both responses now
carry both fields. The account page uses it, so paying no longer leaves the
site.
Changed — downgrades wait for the end of the period
POST /v1/subscription to a smaller plan, or from annual to monthly billing,
no longer applies at once with a credit for the unused time. The current plan
keeps working until the end of the period already paid for, and the next
period is billed at the new one. Until then the response's plan and
interval are the current ones, and the new scheduled_plan and
scheduled_interval fields (also in GET /v1/me) say what comes next. Posting
the current plan undoes the downgrade, and an upgrade or a cancellation
replaces it. Upgrades are unchanged: prorated and charged at once.
New — cancel and resume a subscription
DELETE /v1/subscription stops a subscription renewing. The plan keeps
working until the end of the period already paid for, then the account returns
to Free with the same keys. Posting the current plan to POST /v1/subscription
undoes the cancellation, and choosing another plan undoes it too. Both
responses, and GET /v1/me, carry the new cancel_at field: when the
subscription ends, or null while it renews. GET /v1/me also gains
has_billing_portal: whether POST /v1/portal opens, which stays true after a
subscription ends so its invoices remain reachable.
Changed — usage carries over a plan change
Changing plan within a billing period no longer resets the requests used: a customer who has used 9,000 on Starter and moves to Pro has 91,000 left, not 100,000. Usage still resets when a new billing period starts: a renewal, a first subscription, or a change between monthly and annual billing.
Changed — plan changes are paid before they apply
POST /v1/subscription now invoices and charges the prorated difference at
once, instead of adding it to the next renewal, and the new plan applies only
once that payment succeeds. If it fails or needs the customer to confirm it,
the response keeps the current plan and interval and gives the invoice to
pay in the new pending_payment_url field (otherwise null). Paying it applies
the change; an unpaid change lapses after 23 hours.
Changed — the demo is for the website only
POST /v1/demo now needs a captcha_token from the home page's Cloudflare
Turnstile widget, and is limited to 15 charts an hour per IP address instead
of 30 a minute. A missing token answers 422 parameter_invalid, a rejected
one 403 captcha_failed, and 503 captcha_unavailable means Cloudflare
couldn't be reached. To call the API from code or a terminal, use a free key.
API version 2026-10-22 — the chart is grouped
Charts from /v1/charts/pythagorean, /v1/charts/batch and the demo group
related fields instead of listing them flat. The numbers themselves do not
change, and requests with Numerology-Version: 2026-09-26 get the flat chart
exactly as before.
first_name,middle_name,last_nameandbirthdatemove intoperson.physical_plane…intuitive_planebecomeplanes_of_expression, with the keysphysical,mental,emotionalandintuitive.life_path_expression_bridgeandsoul_urge_personality_bridgebecomebridges.life_path_expressionandbridges.soul_urge_personality.first_pinnacle…fourth_pinnacle,first_challenge…fourth_challengeandfirst_life_cycle…third_life_cyclebecome the arrayspinnacles,challengesandlife_cycles. Each stage is{stage, number, from_age, to_age}, like the cycles endpoint'scurrent_pinnacle; the last stage'sto_ageisnull.pinnacle_challenge_age_rangesis removed: the stages carry their ages.full_name_number_countsis a list of{number, count}for the digits 1 to 9, in order and zeros included, instead of an object keyed by the digits as strings.chart_textis removed. Build display text from the fields, or pin2026-09-26to keep receiving it.- With
expand: ["interpretations"],interpretations.challengesis an array of{stage, number, summary}instead of an object keyed byfirst_challenge…fourth_challenge.
Changed — the service now runs on Django
Charts, cycles and compatibility are computed exactly as before, the endpoints and the error envelope are unchanged, and existing API keys keep working. What a client can notice:
- Request ids in
X-Request-Idanderror.request_idare now UUIDs (32 hex characters) instead ofreq_…. A caller's ownX-Request-Idis honoured when it is a UUID. - Timestamps in account and key responses use the ISO 8601 form
2026-10-21T13:25:01.123456Z. - Rate limits:
429responses still carryRetry-After; theX-RateLimit-LimitandX-RateLimit-Remainingheaders, and the demo'sX-Demo-*headers, are no longer sent. Live and test keys share one burst limit per account. - API versions are chosen per request with
Numerology-Version; requests without it use the current version. Accounts are no longer pinned. - The dashboard (
/v1/me,/v1/keys, …) protects session writes with a CSRF token (X-CSRFToken, from thecsrftokencookie) instead of checkingOrigin; a refused write is403 forbidden. POST /v1/portalno longer reads anapi_keyfrom the body; send the key in theX-API-Keyheader.- Sign-in links carry the
nextstep in the link itself. - The OpenAPI document is generated by drf-spectacular (still OpenAPI 3.1).
Removed
POST /numerology, the chart route from before/v1, deprecated in2026-09-26. UsePOST /v1/charts/pythagorean: the same body, and the same 47 fields plusobject,system,api_version,livemodeandconventions. Errors use the standard envelope.
New
- Cyrillic names are valued with the Russian numerology table: the
33-letter alphabet in order, 1–9 in repeating rows. Ё is its own letter (7),
Ъ and Ь count (1 and 3), Й is a consonant. Planes of expression and
intensity points are
nullfor names containing Cyrillic, since both are defined over the Latin alphabet. options.transliteration: "latin"rewrites Latin letters with no A–Z base — ø, ł, ß, æ, œ, đ, ð, þ, ı — before computing. Opt-in: the default ("none") and every existing Latin chart are unchanged. Cyrillic is never transliterated.computed_nameon every chart: the letters the chart was actually computed from ("Søren" →srenby default,sorenwith transliteration).conventions.transliterationis echoed on charts and compatibility results.
Changed
- Cyrillic first and last names, previously refused, are now accepted and valued. A Cyrillic middle name, previously ignored without warning, now counts — charts for such requests change, because they were computed from the Latin letters alone.
- Letters from Cyrillic alphabets other than Russian (Ukrainian Ї, Є, Ґ; Serbian
Ј; …) are refused with
422instead of being silently skipped. physical_plane,mental_plane,emotional_plane,intuitive_planeandintensity_pointsare now nullable in the schema (null only for Cyrillic).
2026-09-26 — API version 2026-09-26
The first dated API version. Accounts that existed before today are pinned to it, so nothing they call changes behaviour.
New
POST /v1/charts/pythagorean— the chart endpoint under/v1, returning the same 47 fields plusobject,system,api_version,livemodeand theconventionsthat produced it.- Opt-in conventions —
options.y_rule(consonant·vowel·both·contextual) andoptions.name_reduction(whole_name·per_name). The defaults are unchanged and frozen. POST /v1/charts/batch— up to 100 charts per request, charged all-or-nothing.POST /v1/cycles— personal and universal year, month and day, and the Pinnacle, Challenge and Life Cycle in force on a date.POST /v1/compatibility— a documented, weighted comparison of two people's core numbers.- Interpretations —
expand: ["interpretations"]adds meaning text, in English or Spanish (lang, orAccept-Language). - Test-mode keys (
nk_test_…) with their own allowance, andlivemodeon every response. - Several keys per account: create, name, roll (optionally keeping the old
key alive for up to 7 days) and revoke — from the dashboard or
/v1/keys. - Emailed sign-in — the dashboard signs in with a one-time link instead of
a pasted API key. A lost key is recovered by signing in and creating a new one.
nextalso acceptsadmin, which the admin's own sign-in link continues to. - Annual billing, plan changes (
POST /v1/subscription, prorated) and opt-in overage billing past the quota. - Quota emails at 80% and 100%, and notices for key changes, plan changes and failed payments.
- Account export and deletion (
GET /v1/account/export,DELETE /v1/account). Deletion bills overage already served: it is reported to the meter, and the subscription stops renewing and ends with its paid period, whose invoice bills that overage. If Stripe cannot take the report, deletion answers503 billing_unavailableand nothing is deleted. - Errors now share one shape:
{"error": {"type", "code", "message", "param", "doc_url", "request_id"}}. - Every response carries
X-Request-Id.
Changed
- Signup verifies the email address first.
POST /v1/signupanswers202and emails a link; the API key is issued when the link is opened. It no longer returns409for a known address — it emails a sign-in link instead. POST /v1/checkoutrequires a signed-in session or a live API key. It no longer creates an account from a bare email address, and refuses (409) for an account that already has a subscription.- Validation errors on
/v1routes use the new error shape. Status codes are unchanged. - Name fields are limited to 100 characters, and unknown request fields are rejected rather than ignored.
Deprecated
POST /numerology— usePOST /v1/charts/pythagorean. It still works, byte-for-byte as before, and answers withDeprecation,Sunset(31 March 2027) and aLinkto its successor.- The
api_keybody field onPOST /v1/portal— send the key as a header.