Skip to content

Reference

The partner API, endpoint by endpoint.

Base URL https://api.localastro.com/v1/partner. Requests and responses are JSON. Call it from your server, never from a page or an app a visitor can open.

Authentication

One key per request.

Send your key in the Authorization header as a bearer token, or in X-API-Key. Keys begin with la_live_. A revoked key is refused exactly like a key that never existed. You create and revoke keys yourself on the dashboard; if a key leaks, revoke it there and create a new one. Questions go to info@localastro.com.

Authorization: Bearer la_live_YOUR_KEY

Allowance

A running total, agreed with us.

Your account holds an allowance of calls, for example 5,000. It is a running total, not a monthly reset: it lasts until it is spent, and we add more when you ask.

  • Every answered call to /lines, /reading, /places or /archetypes spends one.
  • A request we reject as malformed, or fail to answer, is handed back and not counted.
  • Checking /usage is free.
  • When the allowance is spent, every call answers 429 with call_limit_reached until we add calls. Refused calls are counted separately so we can see when you reach the limit. A new workspace starts with 500 free calls for testing; ask for more from the dashboard once you have integrated, and they are arranged and invoiced by hand.
  • A suspended account answers 403 with partner_suspended.

Every spent call carries three headers:

X-Call-Limit: 5000
X-Calls-Used: 1288
X-Calls-Remaining: 3712

Separately from the allowance, one key may make up to 300 requests a minute. Past that the answer is 429 with rate_limited; wait and retry.

Errors

Every refusal says why.

An error is a status code and a body with a code you can branch on and a sentence you can show.

{ "error": "call_limit_reached", "message": "Your call allowance is used up (5000 of 5000). ..." }
errorStatusWhen
missing_api_key401No key was sent.
invalid_api_key401The key is not one we issued, or it has been revoked.
bad_request400The body or a parameter is missing or malformed. The message says which.
birth_time_required422confidenceTier 3: without the hour no line can be placed.
partner_suspended403Your partner account is paused. Write to us.
call_limit_reached429Your allowance is spent. Nothing more is answered until we add calls.
rate_limited429More than 300 requests in a minute on one key. Slow down and retry.
not_found404No such endpoint.
internal_error500Our fault. The call is not counted; retry with backoff.

Input

The birth moment.

/lines and /reading take the same four fields.

FieldTypeMeaning
birthUtcstringThe birth moment as an ISO 8601 instant in UTC, for example 1991-03-12T14:30:00Z. Convert the local clock time using the birth place’s IANA time zone, which /places returns. Years 1800 to 2200.
latitudenumberBirth place latitude, -90 to 90, north positive.
longitudenumberBirth place longitude, -180 to 180, east positive.
confidenceTier1 | 2 | 31: the time is exact. 2: approximate, within about half an hour, so lines are widened into bands. 3: the hour is unknown, refused with 422 because no line can be placed. Defaults to 1.

Four minutes of birth time move a line about a hundred kilometres, so the tier matters. An approximate time is answered honestly as a wider band, never as a sharper line.

POST /lines

All forty lines.

Every planet on every angle, as a GeoJSON FeatureCollection of MultiLineString features in longitude, latitude order. Lines are cut where they cross the date line and stop where the body never rises or sets, so a line in several pieces is the sky, not a fault. label is the line’s meaning in one or two words; key matches /archetypes.

Request
curl https://api.localastro.com/v1/partner/lines \
  -H "Authorization: Bearer la_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"birthUtc":"1991-03-12T14:30:00Z","latitude":41.15,"longitude":-8.61,"confidenceTier":1}'
Response
{
  "confidenceTier": 1,
  "maxOrbDegrees": 2,
  "lineCount": 40,
  "lines": {
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "geometry": {
          "type": "MultiLineString",
          "coordinates": [[[-21.42, -80], [-21.42, 80]]]
        },
        "properties": {
          "planet": "Sun",
          "angle": "MC",
          "key": "SUN_MC",
          "label": "Recognition"
        }
      },
      ...
    ]
  }
}

POST /reading

What one place asks.

The birth fields, plus place with the latitude and longitude of the place to read. The answer names the lines that reach it, nearest first, with what the place tends to give, what it asks, what pulls both ways, what to do if you stay and a gentle ceiling on staying in days (null when there is none). scores rate the place from 0 to 1 for revenue, focus, sanctuary and sprint.

Request
curl https://api.localastro.com/v1/partner/reading \
  -H "Authorization: Bearer la_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "birthUtc": "1991-03-12T14:30:00Z",
    "latitude": 41.15,
    "longitude": -8.61,
    "confidenceTier": 1,
    "place": { "latitude": 38.72, "longitude": -9.14 }
  }'
Response
{
  "confidenceTier": 1,
  "quiet": false,
  "reading": {
    "lines": [
      {
        "planet": "Mercury",
        "angle": "AC",
        "label": "Clear thinking",
        "distanceKm": 41,
        "orbDegrees": 0.37,
        "strength": "direct"
      }
    ],
    "additionalLines": 0,
    "summary": "Focus & Communication",
    "gives": ["...", "..."],
    "asks": ["..."],
    "pullsBothWays": [],
    "ifYouStay": ["..."],
    "maxStayDays": 180,
    "approximate": false
  },
  "scores": { "revenue": 0.2, "focus": 0.9, "sanctuary": 0.1, "sprint": 0.3 }
}

A quiet place is an answer

Most of the world is reached by no line, and that is the usual shape of a chart. Then quiet is true and reading is null. Show it at full weight: a product that finds meaning in every place is one nobody believes.

Response
{
  "confidenceTier": 1,
  "quiet": true,
  "notice": "No line reaches this place. It is quiet ground for this chart.",
  "reading": null,
  "scores": { "revenue": 0, "focus": 0, "sanctuary": 0, "sprint": 0 }
}

GET /places

Find a town.

q is a town name, at least two characters; add a country after a comma to narrow it (Paris, France). limit is 1 to 25, default 10. Results come from about 5,000 towns and cities, largest first, with the time zone to convert a local birth time.

Request
curl "https://api.localastro.com/v1/partner/places?q=Lisbon&limit=3" \
  -H "Authorization: Bearer la_live_YOUR_KEY"
Response
{
  "query": "Lisbon",
  "places": [
    {
      "name": "Lisbon",
      "region": "Lisbon",
      "country": "Portugal",
      "countryCode": "PT",
      "latitude": 38.72509,
      "longitude": -9.1498,
      "timezone": "Europe/Lisbon",
      "population": 517802
    }
  ]
}

GET /archetypes

The forty meanings.

Every line’s meaning in the words our own readings use. They change only when we rewrite them, so cache the answer on your side for a day or more.

Request
curl https://api.localastro.com/v1/partner/archetypes \
  -H "Authorization: Bearer la_live_YOUR_KEY"
Response
{
  "planets": ["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"],
  "angles": ["MC", "IC", "AC", "DC"],
  "archetypes": [
    {
      "key": "SUN_MC",
      "planet": "Sun",
      "angle": "MC",
      "slug": "sun-mc",
      "label": "Recognition",
      "tag": "Monetization & Public Reach",
      "summary": "This is the line where you are seen. ...",
      "gives": ["...", "...", "..."],
      "asks": ["...", "..."],
      "ifYouStay": "...",
      "maxStayDays": 180
    },
    ...
  ]
}

GET /usage

What you have used. Free.

Your allowance, what is spent and the last thirty days, by UTC day. The same numbers are on the usage page.

Request
curl https://api.localastro.com/v1/partner/usage \
  -H "Authorization: Bearer la_live_YOUR_KEY"
Response
{
  "partner": "Example Travel Co",
  "status": "active",
  "callLimit": 5000,
  "callsUsed": 1287,
  "callsRemaining": 3713,
  "lastCallAt": "2026-10-27T09:14:02.511Z",
  "days": [
    { "day": "2026-10-26", "calls": 212, "refused": 0 },
    { "day": "2026-10-27", "calls": 64, "refused": 0 }
  ]
}

Privacy

What happens to what you send.

The birth moments in your requests are used to answer that one request and then dropped. We do not store them, cache them or write them to a log. What we keep is a count of calls per day and per endpoint, for your allowance and your invoice.

You are responsible for having your users’ agreement to send us their birth details, and for what you show them. How a reading is worked out is written up on How we read a place.