- Docs
- Domain Guides
- Mesoamerican Astrology
Mayan Astrology API, what to build and how to call it
Ship a Mayan day sign calculator, a nawal birth chart, a Long Count converter or an Aztec tonalpohualli page in under 30 minutes. No epigraphy required.
Mesoamerican astrology is a full domain in the RoxyAPI catalog. 18 endpoints covering the Tzolkin day signs, the Haab year, the five position Long Count, the Calendar Round, the Lord of the Night, the Year Bearer, the five point Cruz Maya and the Aztec tonalpohualli. Every convention that makes two Mayan calculators disagree is a typed request field with a named default, and the resolved value comes back on the response, so a chart you save today can be reproduced or audited years later. Everything is the classical day count, computed rather than looked up, and available in 10+ languages on one key.
What you can build
- Mayan sign calculators (day sign, coefficient, trecena, and a composed nawal reading from one birth date)
- Nawal birth charts with the five point Cruz Maya, which is the shape Spanish language daykeeping sites publish
- Long Count converters in both directions, for museum, epigraphy, education and timeline software
- Daily energy pages for both calendars, deterministic and safe to schedule weeks ahead
- Month grid calendars showing the Tzolkin, Haab and Long Count for every civil day
- Nawal compatibility widgets, with every scoring component and its weight published on the response
- Reference catalogues: the twenty day signs, the twenty trecenas, the nineteen Haab periods
- Aztec tonalpohualli pages beside the Maya ones, on the same key and the same response shape
Prerequisites
- A RoxyAPI key from /account.
- For anything personal: a birth
dateinYYYY-MM-DD, and nothing else. No birth time, no coordinates, no timezone. A Mesoamerican day is an integer function of the elapsed day, so the whole domain takes the lightest input in the catalog. - Optionally, the conventions.
correlationon every Maya route,yearBearerSystemon the chart,directionSchemeon compatibility and the sign catalogue. Each has a named default, so you can ignore all three until a user asks why your number differs from another site. - Nothing else. There is no location lookup in this domain, so
GET /location/searchis not part of the flow.
Install
npm install @roxyapi/sdk
pip install roxy-sdk
composer require roxyapi/sdk
dotnet add package RoxyApi.Sdk
go get github.com/RoxyAPI/sdk-go
Call the endpoint
The #1 Mesoamerican call is the Tzolkin day sign: "what is my Mayan sign". One POST turns a birth date into the nawal, its coefficient, the trecena it sits in and a full composed reading. Verified operationId: calculateTzolkin.
curl -X POST https://roxyapi.com/api/v2/mesoamerican-astrology/mayan/tzolkin \
-H "X-API-Key: $ROXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"date": "1990-06-15"
}'
import { createRoxy } from '@roxyapi/sdk';
const roxy = createRoxy(process.env.ROXY_API_KEY!);
const { data: day } = await roxy.mesoamericanAstrology.calculateTzolkin({
body: { date: '1990-06-15' },
});
console.log(day.daySign); // "men" <- canonical id, never translated
console.log(day.daySignName); // "Men" <- standard Yucatec spelling
console.log(day.daySignClassic); // "Men" <- the form older reference tables print
console.log(day.daySignKiche); // "TZʼIKIN" <- the highland daykeeping name
console.log(day.number); // 8
console.log(day.trecena.number); // 20
console.log(day.trecena.rulingSignName); // "Lamat"
console.log(day.reading.keynote); // "The nawal Men, called TZʼIKIN in the ..."
console.log(day.conventions.correlation); // "gmt-584283"
import os
from roxy_sdk import create_roxy
roxy = create_roxy(os.environ['ROXY_API_KEY'])
day = roxy.mesoamerican_astrology.calculate_tzolkin(date='1990-06-15')
print(day['daySignName'], day['number'], day['daySignKiche'])
print(day['trecena']['number'], day['trecena']['rulingSignName'])
print(day['reading']['guidance'])
<?php
use function RoxyAPI\Sdk\createRoxy;
$roxy = createRoxy(getenv('ROXY_API_KEY'));
$day = $roxy->mesoamericanAstrology->calculateTzolkin(date: '1990-06-15');
echo $day['daySignName'], ' ', $day['number'], "\n";
echo $day['reading']['keynote'], "\n";
using RoxyApi;
using Microsoft.Kiota.Abstractions; // for the Date type
var roxy = new RoxyClient(Environment.GetEnvironmentVariable("ROXY_API_KEY")!);
var day = await roxy.MesoamericanAstrology.Mayan.Tzolkin.PostAsync(new()
{
Date = new Date(1990, 6, 15),
});
Console.WriteLine(day!.DaySignName); // "Men"
Console.WriteLine(day.Number); // 8
Console.WriteLine(day.Trecena!.Number); // 20
import (
"context"
"time"
roxyapi "github.com/RoxyAPI/sdk-go"
)
roxy, _ := roxyapi.NewRoxy("YOUR_API_KEY")
day, _ := roxy.MesoamericanAstrology.CalculateTzolkin(context.Background(), nil,
roxyapi.CalculateTzolkinJSONRequestBody{
Date: roxyapi.Date(1990, time.June, 15),
})
claude mcp add-json --scope user roxy-mesoamerican '{"type":"http","url":"https://roxyapi.com/mcp/mesoamerican-astrology","headers":{"X-API-Key":"YOUR_KEY"}}'
Then in any MCP client: "what is the Mayan day sign for 15 June 1990, and what does the trecena say about it?" The agent calls the Tzolkin tool and reads the composed reading straight off the response. Full setup for Cursor, Claude Desktop, Antigravity, and other clients: MCP guide.
The response for that call, in full:
{
"date": "1990-06-15",
"daySign": "men",
"daySignName": "Men",
"daySignClassic": "Men",
"daySignKiche": "TZʼIKIN",
"number": 8,
"trecena": {
"number": 20,
"dayOfTrecena": 8,
"rulingSign": "lamat",
"rulingSignName": "Lamat"
},
"reading": {
"keynote": "The nawal Men, called TZʼIKIN in the highland daykeeping tradition, is the eagle, the long view taken from far enough up to see the whole valley. The sign itself is read as eagle.",
"numberReading": "The coefficient 8 falls in the middle band, neither gentle nor violent. These are the days of ordinary recurring ritual rather than of crisis, which is where Men does its steadiest work.",
"numberBand": "indifferent",
"strengths": [
"Sees the shape of a situation while everyone else is inside it",
"Aims high without embarrassment and often reaches it"
],
"challenges": [
"Stays at altitude when the work is on the ground",
"Judges the valley by the map and misses what is actually growing"
],
"guidance": "Come down for one detail. A view that never lands is scenery, not knowledge."
},
"conventions": {
"correlation": "gmt-584283"
}
}
Read the response
| Field | What it is |
|---|---|
daySign | The canonical id, lowercase ASCII. Safe as a CSS class, a data attribute or a database key, in every language |
daySignName | The standard modern spelling, which is what to render to a user |
daySignClassic | The sixteenth century form, which is what printed reference tables and older books use |
daySignKiche | The name highland daykeepers use, uppercase as that tradition writes it |
number | The coefficient, 1 to 13 |
trecena | The thirteen day period: its number, the dayOfTrecena this day is, and the rulingSign it opened on |
reading | keynote, numberReading, strengths, challenges, guidance, plus numberBand when the coefficient has one |
conventions | The convention actually used. On this route, correlation |
Three namings, one machine id. Branch on daySign, render daySignName. The three name fields exist because a Mayan sign genuinely has three current spellings and your audience picks one: a Guatemalan daykeeping audience expects TZʼIKIN, a reference site expects the classic form, and a general audience expects the standard modern one. Nothing about them changes with ?lang=, because they are proper nouns carried as data.
numberBand is absent, not null, for four coefficients. Only nine of the thirteen have a character recorded in the literature. For 4, 5, 6 and 10 the field is simply not returned, and numberReading says so in a sentence instead of inventing a meaning. Use a truthiness check, because === null will not catch it.
const band = day.reading.numberBand ?? 'unbanded';
The conventions are the whole point
Three genuine school splits run through this domain. Every one of them is a typed request field with a named default, and the resolved value comes back under conventions. A calculator that does not say which convention it used cannot be checked against anything, and that is the single most common support question in this domain.
correlation moves every value in the response. It is the constant that ties the day count to a civil date, and the four published constants sit two to three days apart:
curl -X POST https://roxyapi.com/api/v2/mesoamerican-astrology/mayan/chart \
-H "X-API-Key: $ROXY_API_KEY" -H "Content-Type: application/json" \
-d '{"date":"2012-12-21","correlation":"martinez-hernando-584281"}'
correlation | Long Count for 2012-12-21 | Calendar Round |
|---|---|---|
gmt-584283 (default) | 13.0.0.0.0 | 4 Ajaw 3 Kʼankʼin |
martinez-hernando-584281 | 13.0.0.0.2 | 6 Ikʼ 5 Kʼankʼin |
astronomical-584285 | 12.19.19.17.18 | 2 Etzʼnabʼ 1 Kʼankʼin |
martin-skidmore-584286 | 12.19.19.17.17 | 1 Kabʼan 0 Kʼankʼin |
Use the default unless you have a reason not to. It is the commonly accepted constant, the one the major institutional converter runs on, and the one a highland daykeeper count agrees with. The other three are there because published inscription readings sometimes use them and a researcher has to reproduce a printed value.
yearBearerSystem decides which Haab day names the year, and the three bearer sets are disjoint, so no date exists on which two schools agree. On POST /mayan/chart for 2012-12-21: classic returns 1 Kabʼan, campeche returns 2 Etzʼnabʼ, colonial-yucatec returns 3 Kawak.
directionScheme decides the world direction and colour of a sign. The two published readings sit exactly one quarter turn apart on all twenty. imix is north and white under madrid-codex, east and red under landa.
Surface `conventions` in your UI
When a user says your sign disagrees with another site, echoing the correlation you used answers it in one line, without recomputing anything.
Ship the rest
The whole day in one call
POST /mesoamerican-astrology/mayan/chart (generateMayanChart) is the deepest call in the domain and the one to build a nawal birth chart on. It returns the Tzolkin block above plus the Haab date, the five position Long Count with its daysSinceEpoch and julianDayNumber, the calendarRound string, the lordOfNight, the yearBearer, the five point cross and a one paragraph summary.
curl -X POST https://roxyapi.com/api/v2/mesoamerican-astrology/mayan/chart \
-H "X-API-Key: $ROXY_API_KEY" -H "Content-Type: application/json" \
-d '{"date":"2012-12-21"}'
# => calendarRound "4 Ajaw 3 Kʼankʼin", longCount.formatted "13.0.0.0.0",
# lordOfNight.label "G9", yearBearer "1 Kabʼan", cross[5]
The cross is the Cruz Maya, five entries in a fixed order: center at the birth day, conception eight days before, destiny eight days after, left six days after and right six days before. Each carries its own sign, coefficient and a line on how it is read. It is a living daykeeper convention rather than an archaeological reconstruction, and the response says so on the field itself.
There is deliberately no separate Haab endpoint and no Lord of the Night endpoint. Both are inside this call, because one call should be one complete answer.
Long Count conversion, both directions
POST /mesoamerican-astrology/mayan/long-count/convert (convertLongCount) takes exactly one of date or longCount and returns the other, plus the day count, the Julian Day Number, the Calendar Round and the Lord of the Night.
curl -X POST https://roxyapi.com/api/v2/mesoamerican-astrology/mayan/long-count/convert \
-H "X-API-Key: $ROXY_API_KEY" -H "Content-Type: application/json" \
-d '{"longCount":"9.12.11.5.18"}'
# => date "0683-08-29", julianDayNumber 1970761, calendarRound "6 Etzʼnabʼ 11 Yax",
# lordOfNight "G1", plus a note that this date precedes the Gregorian reform
Sending both fields, or neither, returns 400. That is on purpose: the endpoint converts, so guessing a direction would be guessing at the caller intent. A date before 15 October 1582 comes back with a note field explaining the proleptic Gregorian reading, which is the one thing that makes this API look wrong beside a converter that switches to the Julian calendar there.
The day sign of the day
GET /mesoamerican-astrology/mayan/daily (getDailyMayanReading) is the same Tzolkin shape for today, plus an overview sentence that names the trecena the day sits in. It takes an optional date, so a content schedule can be built weeks ahead and will match what the endpoint serves on the day. GET /mesoamerican-astrology/aztec/daily (getDailyAztecReading) is the Aztec equivalent.
The month grid
GET /mesoamerican-astrology/mayan/calendar/monthly (getMonthlyTzolkinCalendar) returns every civil day of a year and month with its daySign, number, trecena, haab string and longCount. One call fills a whole calendar UI:
curl "https://roxyapi.com/api/v2/mesoamerican-astrology/mayan/calendar/monthly?year=2026&month=9" \
-H "X-API-Key: $ROXY_API_KEY"
# => days[0] { date "2026-09-01", daySignName "Ikʼ", number 1, trecena 18,
# haab "15 Mol", longCount "13.0.13.16.2" }
Nawal compatibility
POST /mesoamerican-astrology/mayan/compatibility (calculateMayanCompatibility) takes two dates and returns both days in full, daysApart in the 260 day count, five structural components each with holds and weight, a composite score, a verdict band and a summary.
curl -X POST https://roxyapi.com/api/v2/mesoamerican-astrology/mayan/compatibility \
-H "X-API-Key: $ROXY_API_KEY" -H "Content-Type: application/json" \
-d '{"personA":{"date":"1990-06-15"},"personB":{"date":"1991-03-02"}}'
# => daysApart 0, score 100, verdict "excellent",
# components holding: same-sign, same-trecena, same-number, shared-direction
The score is a RoxyAPI composite and is labelled as one. Nothing published rates a pair of Tzolkin days, so the five components are each sourced, the weights are ours, and both ship on every response rather than sitting behind a number. There is also a floor: two people who share nothing still score 45, because sharing nothing is the common case in a 260 day count rather than a bad result. Render the components array, not just the number, or your users will read 45 as a failing grade.
The catalogues
GET /mesoamerican-astrology/mayan/day-signs(listMayanDaySigns) and/{id}(getMayanDaySign) return the twenty signs. The list carriesposition, all three namings,gloss,glossAlternate,directionandcolor; the single-sign call adds the full reading, thedirectionReadingand the trecena the sign opens.GET /mesoamerican-astrology/mayan/trecenas(listTrecenas) and/{number}(getTrecena) return the twenty thirteen day periods, each composed from the sign it opens on.GET /mesoamerican-astrology/mayan/haab-months(listHaabMonths) and/{id}(getHaabMonth) return the nineteen Haab periods, eighteen of twenty days plus Wayebʼ of five.
All three lists are paginated with limit and offset and return total first, so a UI can page without holding the table itself.
The Aztec family
POST /mesoamerican-astrology/aztec/tonalpohualli (calculateTonalpohualli) is the Aztec 260 day count: the same thirteen coefficients against twenty signs, under Nahuatl names and a different anchor. It returns daySign, daySignName, gloss, direction, number, the trecena, a keynote, a guidance line and a scope sentence.
curl -X POST https://roxyapi.com/api/v2/mesoamerican-astrology/aztec/tonalpohualli \
-H "X-API-Key: $ROXY_API_KEY" -H "Content-Type: application/json" \
-d '{"date":"1990-06-15"}'
# => daySignName "Cuāuhtli", gloss "eagle", direction "west", number 8, trecena 20
GET /mesoamerican-astrology/aztec/day-signs (listAztecDaySigns), /{id} (getAztecDaySign), GET /mesoamerican-astrology/aztec/trecenas (listAztecTrecenas) and /{number} (getAztecTrecena) are the matching catalogues.
The scope field is a feature, not a disclaimer. The Aztec family returns no night lord, no solar year and no trecena patron, because for each of those the reference sources disagree and one guess would be indistinguishable from a fact. The response states which fields are missing and why, in the language you asked for.
See the full domain at the API Reference.
Reply in the user language
Every endpoint here accepts ?lang=, in 10+ languages. Spanish is the one to reach for first in this domain: the living daykeeping audience is in Guatemala and Mexico.
curl -X POST "https://roxyapi.com/api/v2/mesoamerican-astrology/mayan/tzolkin?lang=es" \
-H "X-API-Key: $ROXY_API_KEY" -H "Content-Type: application/json" \
-d '{"date":"1990-06-15"}'
What translates is the prose: keynote, numberReading, strengths, challenges, guidance, overview, summary, scope and every reading string. What never translates is the machine layer and the proper nouns: daySign stays "men", direction stays "west", numberBand stays "indifferent", verdict stays "excellent", and the three name fields stay Men, Men and TZʼIKIN in every language, because a nawal name is a name.
if (day.daySign === 'men') { /* always safe, in every language */ }
render(day.daySignName, day.reading.keynote); // the second one is translated
Branch on the canonical field, render the localized one. That is the same contract every RoxyAPI domain follows.
Gotchas
- Dates are proleptic Gregorian throughout, including before the 1582 reform. A converter that switches to the Julian calendar below the reform will differ from this API by ten or eleven days on the same input, and feeding it the Julian equivalent makes the two agree exactly. The conversion endpoint flags any such date with a
notefor this reason. - The classical count only, not Dreamspell or 13 Moon. Those are a separate modern system that freezes its count on 29 February, so it has drifted from the classical day count by a different amount at every date. See Coverage and scope for what that means for your users.
- Send exactly one of
dateorlongCountto the converter. Both, or neither, returns 400 with the accepted shape spelled out. numberBandis absent for coefficients 4, 5, 6 and 10. Absent, not null. Use a truthiness check.- The Aztec family takes no
correlationfield but echoes one. The Maya constant maps a civil date onto a day count; the tonalpohualli anchor is itself a civil date, so no constant enters the arithmetic. The echoed value names the anchor the count runs from, which is why it reads differently from the Maya one. - The arms of the Cruz Maya carry no gender. The signs are identical across sources but the masculine and feminine labels are flipped between them, so publishing either would publish one house style as a fact. Label them in your own UI if your audience expects it.
- A day sign has two glosses and they can disagree.
glossandglossAlternateare both published because the two reading traditions differ on six of the twenty, and the composed prose follows the glyph reading. That is why the prose for those six can look unrelated togloss. - Everything in this domain is cache-forever except the two daily calls. A birth chart, a conversion and a catalogue never change. The daily readings roll over at 00:00 UTC and are cached to exactly that boundary.
- The
?lang=value is validated. An unsupported code returns 400 with the accepted list, rather than silently falling back to English. - Every call bills at a flat 1 request. REST and Remote MCP are identical, with no per-domain fees.
Frequently asked questions
How do I find my Mayan day sign with an API?
Send a birth date to POST /mesoamerican-astrology/mayan/tzolkin and the day sign comes back with its coefficient, its trecena and a composed nawal reading in one response. The sign arrives in three namings at once, the standard Yucatec spelling, the sixteenth century form and the Kʼicheʼ name highland daykeepers use, so you can label it the way your audience expects.
Why do two Mayan calculators give different answers for one date?
Usually the correlation constant, the number that ties the day count to a civil date. Several are published, they sit a few days apart, and a calculator that does not name the one it used cannot be checked. Every response here echoes it under conventions. The other common cause is that the other tool runs the modern Dreamspell or 13 Moon count rather than the classical one.
What is the difference between the Tzolkin and the Haab?
The Tzolkin is the 260 day sacred round, thirteen coefficients running against twenty day signs. The Haab is the 365 day solar year, eighteen periods of twenty days plus the five days of Wayebʼ. POST /mesoamerican-astrology/mayan/chart returns both, plus the Calendar Round, which is the pair written together and repeats only every 18980 days.
Can I convert a Long Count date from an inscription?
Yes, in both directions. POST /mesoamerican-astrology/mayan/long-count/convert takes either a longCount such as 9.12.11.5.18 or a civil date and returns the other, along with the Julian Day Number, the day count and the Calendar Round, all under whichever correlation constant you name.
Does the Aztec calendar work the same way?
It is the same structure with different names and a different anchor. POST /mesoamerican-astrology/aztec/tonalpohualli returns the day sign, its coefficient and its trecena. It deliberately returns fewer fields than the Maya side, and every response says which ones and why: where the reference sources disagree, nothing ships rather than a guess.
Does it work for historical dates?
Yes, without losing accuracy, because a Mesoamerican day is a plain count of elapsed days rather than an astronomical lookup. Dates from year 1 to year 4000 are accepted and are read as proleptic Gregorian throughout, so a date in 683 costs exactly what today costs.
Ready-made starter
There is no Mesoamerican-only template yet. The flagship astrology-ai-chatbot template connects every domain over Remote MCP, so cloning it gives you a working nawal and Long Count chatbot with no wiring; browse the catalog at /starters. For a custom build, the Next.js integration guide is the fastest path.
What to build next
- Coverage and scope explains the Dreamspell and 13 Moon question in full, which is the one your support inbox will ask about.
- The Chinese astrology guide covers the other calendar-first domain: BaZi Four Pillars, the zodiac and the lunisolar calendar. Both domains answer "what day is this, in a system that is not the Gregorian one".
- The caching guide covers the cache-forever versus roll-over-daily split this domain has.
- The AI chatbot tutorial shows tool registration so users can ask "what is my nawal" in natural language.