Daymaster API
White-label access to our Bazi + ZWDS chart engines, chart-grounded AI chat, daily and pair analysis, and chart-contextualised Tarot. Build your own UI, use our data. Pay per successful call, billed monthly.
Authentication
Every request requires a Bearer API key in the Authorization header. Request a key from your account manager — we mint one for you in the admin portal and share it exactly once. Keep it out of source control and client-side bundles.
Optionally pass X-End-User-Id as an opaque string identifying the end user on your side — we never map it to one of our auth users, but it shows up on usage events so you can correlate billing to specific customers.
Generate a chart
POST /api/v1/readings/generate runs the Bazi engine (and optionally ZWDS) on a birth profile and persists the chart to our database for later reference. No LLM call — this is cheap and fast.
POST /api/v1/readings/generate HTTP/1.1
Host: daymaster.ai
Authorization: Bearer dm_live_xxxxxxxxxxxxxxxxxxxxxxxx
X-End-User-Id: your_user_42
Content-Type: application/json
{
"birth_datetime": "1990-05-15T08:00:00+08:00",
"longitude": 121.47,
"latitude": 31.23,
"gender": "male",
"include_zwds": true,
"language": "en"
}Draw tarot
POST /api/v1/tarot performs a seeded shuffle for the chosen spread and returns the drawn cards plus an LLM-generated narrative woven through the user's chart (when areading_id is passed). Set skip_llm: true for deterministic cards only. Seven spreads: daily, past_present_future, situation_action_outcome, celtic_cross, year_ahead, and two that read each card against the chart and therefore need a reading_id: five_elements and dayun_crossroads.
POST /api/v1/tarot HTTP/1.1
Host: daymaster.ai
Authorization: Bearer dm_live_xxxxxxxxxxxxxxxxxxxxxxxx
X-End-User-Id: your_user_42
Content-Type: application/json
{
"spread_id": "past_present_future",
"question": "Should I take the new job offer?",
"reading_id": "uuid-of-previously-generated-chart",
"lang": "en"
}Chat about a chart
POST /api/v1/opening returns a short snapshot of a chart plus suggested first questions; POST /api/v1/chat answers one message about it. Both answer from the chart itself, so they need only a chart from /readings/generate. You keep the conversation and send the earlier turns as history; we store none of it. An optional voice object sets the persona name, tone, style, length, emoji and format.
POST /api/v1/chat HTTP/1.1
Host: daymaster.ai
Authorization: Bearer dm_live_xxxxxxxxxxxxxxxxxxxxxxxx
X-End-User-Id: your_user_42
Content-Type: application/json
{
"reading_id": "uuid-of-previously-generated-chart",
"message": "Is this a good year to change jobs?",
"history": [],
"language": "en"
}Response shape
Every successful call returns a usage block with the billed module_id, per-call cost frozen at event time, and your month-to-date revenue so you can budget client-side without a second round trip.
HTTP/1.1 200 OK
Content-Type: application/json
{
"chart": {
"bazi": { "dayMaster": "甲", "year": { ... }, "luckPillars": [...] },
"zwds": { "palaces": [...], "daxians": [...] }
},
"reading_id": "abc-123-def",
"engine_versions": { "pillar": 23, "stellar": 13 },
"usage": {
"event_id": 42,
"module_id": "bazi_chart",
"unit_cost_usd": 0.10,
"mtd_revenue_usd": 127.50
}
}Modules
You opt into modules explicitly. New Daymaster features never auto-appear in your offering.
| Module | Endpoint | Typical price |
|---|---|---|
| bazi_chart (incl. ZWDS) Deterministic engine output, no model call. | POST /api/v1/readings/generate POST /api/v1/chart POST /api/v1/profile POST /api/v1/annual POST /api/v1/signals POST /api/v1/rhythm POST /api/v1/rectify | $0.10 / call |
| daily_guidance Structured day facts, no model call. | POST /api/v1/daily POST /api/v1/daily/batch POST /api/v1/daily/range | on request |
| compatibility Structured pair facts; no composite score by design. | POST /api/v1/relationship POST /api/v1/relationship/daily | $0.80 / call |
| chat One model call per answer, grounded on the chart. | POST /api/v1/opening POST /api/v1/chat | $0.02 / answer |
| tarot | POST /api/v1/tarot | $0.30 / call |
| ai_reading Cannot return a NEW reading yet: generation takes about 15 minutes. See /status. | POST /api/v1/readings/narrate | $0.50 / call |
| ai_reading_editor Re-runs the editor pass on a reading that is already generated. | POST /api/v1/readings/narrate/editor | $0.10 / call |
Errors
Standard HTTP status codes:
400— bad request (missing or invalid body field)401— missing or invalid API key403— key revoked, tenant paused, module not enabled, or thereading_idbelongs to another tenant404—reading_idnot found409— a precondition is missing (chart_missing,master_missing) or an idempotency key was reused with a different body (idempotency_conflict)422— chart could not be computed (invalid birth inputs)502— every model provider in the fallback chain failed, or a generated reading came back with sections missing (generation_incomplete); nothing is billed503— database temporarily unavailable
Only a successful response is billed. Errors come back as JSON: { "error": "<code>", "message": "<text>" }.
Timing
Measured on production partner traffic, May to September 2026 (median, then 90th percentile):
- Chart endpoints (
/readings/generate,/chart,/profile,/daily): about 1 to 2 seconds /chat: 26 s, 42 s./opening: about 15 s/tarot: not yet measured on partner traffic. Each call can take up to 300 s, because it falls back through up to three models of 90 s each./readings/narrate: a new reading is generated in the background. The call answers202at once; pollGET /api/v1/readings/narrate?reading_id=…(free) or take thereading.completed/reading.failedwebhook
Set your HTTP client timeout to at least 300 seconds for the model-backed endpoints.
Versioning
The base path /api/v1/* is stable. New features ship as new endpoints within v1 or as/api/v2/* when breaking changes are necessary. We never change the response shape of an existing endpoint without a version bump.