Skip to content
RoxyAPI
Get API Key

Astrology report software for white-label PDFs

Generate a personalised natal chart, kundli, human design, BaZi or numerology report under your own brand with one API call. A print-ready PDF, a self-contained web page or Markdown, in the language of your client, on every plan.

A report is a finished document built from the same data the chart endpoints return: the wheel or the kundli drawn to its tradition, every placement in a table, and the reading for each one, laid out page by page with your name, logo, colours, font and footer. You send the birth details, you get the document back. This page is for developers generating reports in an app or a backend, and for sellers who want to know what the widget does underneath. Samples, the full catalogue and what each report contains are on white label astrology reports.

Sell reports without writing code

The report widget turns any report into a form on your page and hands your client the branded PDF. Pick a report, brand it and copy the code in the report builder. Step by step: how to sell astrology readings.

The report operations

Each report is one POST operation under the Reports tag, at /api/v2/reports/{id}, named generate{Report}Report.

ReportPathoperationId
Natal chart/reports/natalgenerateNatalReport
Synastry/reports/synastrygenerateSynastryReport
Kundli/reports/kundligenerateKundliReport
Kundli matching/reports/matchmakinggenerateMatchmakingReport
Tarot reading/reports/tarotgenerateTarotReport
Numerology/reports/numerologygenerateNumerologyReport
Human Design/reports/human-designgenerateHumanDesignReport
Yearly forecast/reports/yearly-forecastgenerateYearlyForecastReport
BaZi/reports/bazigenerateBaziReport

The spec is the live list, with the cost of each report beside it:

bash
curl -s https://roxyapi.com/api/v2/openapi.json \
  | jq -r '.paths | to_entries[] | select(.key | startswith("/reports/")) | "\(.key)  \(.value.post.operationId)  \(.value.post["x-request-cost"])"'

Every operation, with its request schema and a live console, is in the Reports API reference.

What the request carries

The body is the input of the chart the report is built on, plus four report fields. A natal report takes what POST /astrology/natal-chart takes, a kundli report what the Vedic birth chart takes, a synastry or matching report person1 and person2, a numerology report fullName, year, month and day. A tarot report needs nothing: send a question if your client has one.

FieldWhat it does
formatpdf (default), html or markdown. Picks which output field the response carries
brandingYour name, logo, colours, font and footer. Every field optional. See Branding
page.sizeA4 (default) or Letter, for the PDF
readingstrue (default) or false. false keeps the charts, tables and key figures and leaves out every written reading, for a chart-only report at the same cost
?lang=Query parameter. The language of the whole report: headings, labels and every reading

Birth places follow the same rule as every chart: resolve the city with GET /location/search and send its latitude, longitude and IANA timezone. Never ask your client for coordinates.

Generate a PDF

Get your API key, then request the report and decode the pdf field into a file.

bash
curl -s -X POST "https://roxyapi.com/api/v2/reports/natal" \
  -H "X-API-Key: $ROXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "1990-07-15",
    "time": "14:30:00",
    "latitude": 40.7128,
    "longitude": -74.006,
    "timezone": "America/New_York",
    "format": "pdf"
  }' | jq -r .pdf | base64 --decode > natal-report.pdf

The JavaScript call above returns a Spanish natal report titled Informe de carta natal, saved under that name.

The response

A JSON object with the document in one field, chosen by format.

FieldWhat it holds
templateThe report id, such as natal
langThe language the report is written in
formatpdf, html or markdown: which of the three fields below is present
titleThe report title in the report language, ready for a file name, an email subject or a heading
pagesPage count. Present for a PDF
pdfThe PDF, base64 encoded. Decode it and save it as a .pdf file
htmlOne self-contained HTML document: styles and charts inline, ready to serve
markdownThe report as CommonMark, for your own layout or a CMS

Branding

Send branding with every request. Every field is optional, and anything left out keeps the theme value. The document carries your brand alone, on every plan.

FieldWhat it does
nameBusiness or practitioner name on the cover and in the running header of every page
logoHTTPS URL of a PNG, JPEG, WebP or SVG under 1 MB, printed on the cover
footerA line at the foot of every page, such as a disclaimer or a booking note
websiteWebsite printed on the cover
emailContact email printed on the cover
colors.primaryHeadings and table headers, as six digit hex such as #3e2a2c
colors.accentRules and highlights, as six digit hex such as #914955
fontThe font pair for headings and text, the same pairs the widgets take: fraunces-jost, jost, geist or system
themeA design preset shared with the widgets: practitioner (Rosewater), eucalyptus, kiln, moonlit or celeste

The logo URL must answer with the image file itself. A page that only shows the image, a host that answers an error, or a file over the size limit returns a 400: see invalid_branding and logo_fetch_failed.

Languages

Add ?lang= and the whole report changes language: cover, headings, table labels and every reading. A Spanish natal report is POST /api/v2/reports/natal?lang=es. The supported codes are on the lang parameter of each operation in the API reference, and an unsupported code returns a 400 listing them.

HTML and Markdown

format: "html" returns the report as one HTML document with everything inline, so you can store it or serve it as a page without fetching anything else. format: "markdown" returns the text of the report as CommonMark for your own template; the charts are drawn in the PDF and HTML formats.

The report widget for browsers

Selling from a website? The report widget runs in the browser of your visitor with a publishable key, asks for the birth details the report needs, and hands back the PDF or shows the report on the page. Copy it from the report builder, which writes every setting for you:

html
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js" defer></script>
<div data-roxy-widget="report" data-publishable-key="pk_live_YOUR_KEY" data-report="natal" data-format="pdf" data-brand-name="Luna Rivera Astrology" data-brand-footer="Book a reading at lunarivera.com" data-brand-color="#3e2a2c" data-brand-accent="#914955" data-font="jost"></div>

data-report takes the report id from the table above and data-format takes pdf or html. Every option, the component tag form and the platform walkthroughs: widgets guide. The widget generates a report for anyone who reaches the page, so put it on the page your checkout unlocks; your own platform takes the payment.

What a report costs

Every data endpoint is one request. A report is a whole document built from many calculations and readings, so each report states its cost in requests up front: x-request-cost on its operation in the spec, the jq command above, and the cost table on /reports, which also shows how many of each report every plan covers a month. A report draws from the same monthly plan as every other call, with no separate packs and no tier gate. A request that fails on our side with a 5xx does not count.

What is never stored

A report is generated when you ask for it and handed straight back. The birth details, the branding, the logo and the finished file are never stored, so keep the response if you want to send it again. Branding travels with each request for the same reason.

Errors

A failure is { error, code, doc_url }, and a 400 adds issues[] naming every field at fault. The report-specific codes:

CodeStatusFix
invalid_branding400Point branding.logo at the image file itself
logo_fetch_failed400Host the logo on a public HTTPS URL under 1 MB
unsupported_character400Remove the character the error names from your text
reports_rate_limited429Wait Retry-After seconds, then send it again
reports_busy503Wait Retry-After seconds, then send it again unchanged
report_render_timeout503Send the same request again

FAQ

Can I sell RoxyAPI reports under my own brand?

Yes. Every plan includes white-label reports: your name, logo, colours, font and footer line on every page, and no mark of ours anywhere in the document.

Which formats does a report come in?

Three: a print-ready PDF returned as base64 in the pdf field, one self-contained HTML document in the html field, or CommonMark in the markdown field. Pick one with format in the request body.

How do I save the PDF from the response?

Decode the base64 pdf field and write the bytes to a .pdf file. On the command line that is jq -r .pdf | base64 --decode > report.pdf; in Node it is Buffer.from(report.pdf, 'base64').

Can a report be generated in another language?

Yes. Add ?lang= to the request, for example ?lang=hi or ?lang=es, and the cover, headings, labels and every reading arrive in that language.

How many requests does one report use?

Each report states its cost in requests: x-request-cost on its operation in the OpenAPI spec, and the cost table on the reports page. It draws from your normal monthly plan.

Can I let visitors generate reports on my website?

Yes. The report widget takes a publishable key, asks the visitor for their birth details and hands back the branded PDF or shows the report in place. Build it in the report builder and paste it on the page your checkout unlocks.

Next steps