# Radiant Drift API

Documentation for api.radiantdrift.com

## Introduction

Welcome to the Radiant Drift API! You can use our API to access Radiant Drift API endpoints, to obtain various astronomical data pertaining the Sun, Moon and Galactic Center.

The API is available as a web service accessed via RESTful HTTP requests. You can view example requests using CURL in the dark area to the right.

Javascript examples are given using the popular [axios](https://www.npmjs.com/package/axios) library. Alternatively, the `curl` shell command is also available.

Site documentation remains under active development - if you have any questions, please get in touch at <support@radiantdrift.com>.

#### About Radiant Drift

Learn more about Radiant Drift at [our website](https://www.radiantdrift.com).

#### Getting Support

You can contact us via email at <support@radiantdrift.com>, or use the Help widget on [our website](https://www.radiantdrift.com).

### Beta APIs

Certain API endpoints are available in public beta where noted. We hope you'll try them out and let us know how you find them.&#x20;

Additionally, we're always keen to receive any feedback or suggestions you have, particularly regarding:

* Available end points
* Call structure and parameters
* Response structures
* Data accuracy and usability

Please send your feedback to <support@radiantdrift.com>.


# Subscription Plans

Details of our subscription plans

We offer tiered subscription plans to serve customers with different requirements and traffic volumes. Current plans include

* **Free:** low traffic plan for non-commercial projects
* **Starter**: low traffic plan for commercial projects, with a much higher monthly usage allowance
* **Pro**: moderate traffic volumes with access to further additional API end points and security tools
* **Enterprise**: for users with high traffic volumes

You can view available plans on our [Pricing](https://www.radiantdrift.com/pricing) page. Free trials are available for all plans.

{% hint style="info" %}
Plan details are subject to change - please check our [website](https://www.radiantdrift.com) for current information.
{% endhint %}

### Free

### Premium APIs

Use of certain APIs require a paid subscription plan. Plan requirements are noted on the respective API documentation pages and also in our [OpenAPI](/getting-started/openapi-specification) documentation.


# Educational Use and Research

Access to premium APIs for educational and research purposes

Some of our APIs require a paid subscription for access. Requests made using an API key created under a Free plan will be rejected in these cases. Premium endpoints include:

* Az Alt Search
* Geodesic
* Elevation
* Solar Eclipse Paths and Local Circumstances
* Lunar Limb Profiles
* Estimated Daily and Monthly Insolation

If you are working in an educational capacity or as an academic researcher, we will be happy to provide access at no charge to these APIs upon request. Please write to <support@radiantdrift.com> with details of your request.

Usage will still be subject to normal Free plan limits by default, but please let us know if you would like to discuss a higher limit.

If your research project is in the process of commercialization, we ask that you purchase a paid plan. We're happy to discuss extended trials, depending on your circumstances.


# API End Points

What's available and what's coming

We've focussed on documenting the following API end points initially:

* [Julian](/julian-day) to Date; Date to Julian Day
* [Delta T](/delta-t) for Date
* [Rise/Transit/Set](/rise-transit-set-times) (Sun, Moon, Galactic Center)
* [Body Position](/body-position) (Sun, Moon, Galactic Center, or for an arbitrary right ascension and declination)
* [Solar Eclipses](/solar-eclipses)
* [The Moon](/the-moon) (libration and lunar limb profile)
* [Geodesic](/geospatial/geodesic) - calculate points along the great circle between any two points
* [Elevation](/geospatial/elevation) - elevation at one or more latitude/longitudes, and elevation profiles along an arbitrary great circle

We have a number of other API endpoints just waiting to be documented (you may find them already in our [OpenAPI](/getting-started/openapi-specification) spec). You can expect to see the following added soon:

* Az/Alt Search - search for a times when a body is at a given azimuth/altitude, or in a certain range of az/alt values
* Celestial Events - Moon phases, solstices, equinoxes, lunar eclipses, solar eclipse general circumstances
* Meteor Showers
* Solar Irradiation - solar intensity, instantaneous irradiation, and daily and monthly clear sky insolation estimates for modules at an arbitrary tilt/azimuth

If you have other APIs you'd like to see, let us know.


# Getting Started

Creating an account and API Key

To get started using our APIs, you'll first need to create a free account.

### Creating an account

1. Visit our main website at [radiantdrift.com](https://www.radiantdrift.com) and click the **Sign Up** link at the top right
2. Complete the required fields (first and last name, email address and password), and review and accept the terms of use
3. You can optionally sign up to our mailing list to receive product news and updates
4. We'll send you an email to verify your address. You'll need to click the link to verify your email before continuing

### Sign in to your account

1. Click [sign in](https://www.radiantdrift.com/signin) on our main website
2. Enter your account details and sign in
3. If you're unable to sign in, click 'Forgot password' to receive a password reset link
4. After signing in, you'll be redirected to the [Developer Console](https://www.radiantdrift.com/console)

{% hint style="info" %}
You can update your account details by visiting the [Account](https://www.radiantdrift.com/account) page, where you can change your name, email address, or password or delete your account.
{% endhint %}

### Creating your first API key

Before you can call a Radiant Drift API end-point, you'll need to create an API key.

1. From the [Developer Console](https://www.radiantdrift.com/console), click [API Keys](https://www.radiantdrift.com/api-keys)
2. On the API Keys page, click **Create API Key** to generate a new API key associated with your account
3. For security reasons, the full API key is not displayed, but you can click the 'copy to clipboard'  button ![Copy to clipboard icon](https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FUckBSXIFBrqU6c9UwGd0%2Fclipboard-document.png?alt=media\&token=db4e7270-6478-485a-82ba-27f2b9adcfb6) to copy it to your operating system clipboard
4. The new API key is enabled and active by default
5. We recommend you edit the key to set a meaningful description (e.g. 'For use in Production environment')
6. You may optionally disable the key temporarily to prevent its use - however, we recommend deleting any API keys you no longer plan to use

You can now use your API key to authenticate your API requests.


# About your account

Managing your user account

You can manage your account by [logging in](https://www.radiantdrif.com/signin) to our website.&#x20;

Click on your user name at the top right of the page to manage your account details, such as name, email address, password, or to delete your account.

You can manage your account API keys via the [console](https://www.radiantdrift.com/console).

### Unsubscribe from account related emails

To stop receiving account related emails (e.g. for email address verification, password resets, suspicious login attempts, etc.), please delete your account via our website.

These messages are necessary in order to maintain your account, but if you would like to stop receiving them, you can do so by deleting your account.


# Request Authentication

How to authenticate your API requests

## Creating an API key

To create an API key, see the instructions [here](/getting-started).

## Available methods

Almost all endpoints require authorization for access. You can authorize either be providing a static API key in your request, or by using an access token (JWT).

{% hint style="info" %}
Unless specifically indicated, all endpoints require use of one of the available authentication methods.
{% endhint %}

### Using API Keys

To authorize using an API key, include a query string parameter named `apiKey` in your request:

```javascript
axios({
	"method": "GET",
	"url": "[API_ENDPOINT]",
	"params": {
		"apiKey": "[YOUR_API_KEY]"
	}
})
```

```shell
curl "[API_ENDPOINT]?apiKey=[YOUR_API_KEY]"
```

{% hint style="info" %}
Make sure to replace `YOUR_API_KEY`with your API key.
{% endhint %}

You can use an API key to access the API. You can create a new API key in our [developer console](https://www.radiantdrift.com/console) (see [instructions](/getting-started)).

Radiant Drift accepts valid API keys included as a URL parameter in an request, as shown:

`...?apiKey=[YOUR_API_KEY]`

You must replace `YOUR_API_KEY` with your personal API key.Be sure to keep your API keys secure. Rotate them appropriately and configure appropriate restrictions to ensure they cannot be abused.

### Using Access Tokens

For additional security, you can obtain an access token in the form of a [JSON web token](https://en.wikipedia.org/wiki/JSON_Web_Token) using your account ID and an API key. The JWT so obtained can then be used to authorize multiple requests. This avoids the need to include the actual API key in every request. It also avoids an additional lookup on the server to fetch your API key details, which may result in marginally improved response times.

Use of the access token is subject to the same restrictions as those of the API key used to obtain it (i.e. allowed IP addresses and allowed origins).

### Obtaining an access token

{% hint style="info" %}
In our [OpenAPI spec](/getting-started/openapi-specification), this security scheme is named `radiantDriftAuth`. It is only used in conjunction with obtaining an access token (JWT)
{% endhint %}

{% openapi src="<https://api.radiantdrift.com/openapi/0.18.3.json>" path="/auth/access-token" method="get" %}
<https://api.radiantdrift.com/openapi/0.18.3.json>
{% endopenapi %}

To obtain an access token, make the following request:

{% code lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "http://api.radiantdrift.com/auth/access-token",
	"headers": {
		"Authorization": "RadiantDriftAuth [YOUR_ACCOUNT_ID]:[YOUR_API_KEY]"
	}
})
```

{% endcode %}

{% code lineNumbers="true" %}

```shell
curl "https://api.radiantdrift.com/auth/access-token" \
     -H 'Authorization: RadiantDriftAuth [YOUR_ACCOUNT_ID]:[YOUR_API_KEY]' 
```

{% endcode %}

Response:

{% code lineNumbers="true" %}

```json
// The token is returned as a field in the response body
{
  "success": true,
  "token": "[YOUR_ACCESS_TOKEN]"
}
```

{% endcode %}

{% hint style="info" %}
Make sure to replace `YOUR_ACCOUNT_ID` with your account ID and `YOUR_API_KEY` with your API key.
{% endhint %}

To obtain an access token, send a request to the access token end point, including an authorization header constructed from your account ID and API key.

Access tokens are valid for 15 minutes from the time of issue and can be used for multiple subsequent requests.

### Making a request with an access token

To authorize a request using an access token, include it shown:

{% code lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/[API_ENDPOINT]",
	"headers": {
		"Authorization": "RadiantDriftAuth [YOUR_ACCESS_TOKEN]"
	}
})
```

{% endcode %}

{% code lineNumbers="true" %}

```shell
curl "https://api.radiantdrift.com/[API_ENDPOINT]" \
     -H 'Authorization: RadiantDriftAuth [YOUR_ACCESS_TOKEN]'
```

{% endcode %}

Response:

```json_doc
// Response varies based on the selected end point - see below
```

Make sure to replace `YOUR_ACCESS_TOKEN` with the response received to a successful access token request (see 'Obtaining an access token').

To make an authorized request using an access token, include it in the request Authorization header as shown:

```
Authorization: RadiantDriftAuth [YOUR_ACCESS_TOKEN]
```

### Authentication Failures

If your authentication is invalid (e.g. bad API key, expired JWT, JWT cannot be validated), you will receive a `401 Not Authorized` error. The response body may contain additional information as to why the request failed.


# Managing API Keys

How to manage API keys via the developer console

It is important to safeguard your API keys. Please read this guide on API Key management for tips on how to  manage them effectively.

### Nickname

You can configure a short alphanumeric nickname for each API key you create. We recommend you set  this to something meaningful that helps you identify the purpose of the API key, e.g. 'my-app-prod'.

We use the nickname when measuring usage and in the future you will be able to identify usage per api key using this field.

### Description

The API key description can be used to provide additional details about how the key is used in your projects.

### Disabling an API Key

You may disable a key temporarily via the developer console. Keys that wish to retain, e.g. for occasional testing, but which aren't in regular use should be **disabled** to prevent misuse.

### Deleting an API Key

You may delete an API Key via the console. For improved security of your account, we recommend you rotate API keys from time to time by creating a new key and then deleting its predecessor once the new key has been provisioned in your project.

### &#x20;Test your API Key

You can test your API key by clicking the test button:

![](https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FqAjNCkux8JrXDz5aG9x2%2Fbeaker.png?alt=media\&token=df8fe0b1-c4cf-4ece-a0b9-f84a31a88d58)

This will send a request to for the current [Julian Day](/julian-day) and display the result in your browser. This is a quick way to check that the key is working.

{% hint style="info" %}
Note: the request may be rejected if you have allowed origin or IP rules configured.
{% endhint %}

### Entitlements

Each API key may have zero or more entitlements associated with it. On a Free plan, you will see no entitlements for your API key. Generally, on paid plans, the entitlement should match your plan level, e.g. for a Starter plan, you should see the `starter` entitlement provisioned for your API keys.

API key entitlement provisioning is handled automatically by our systems, for example, on purchasing a subscription or on creating a new API key via the developer console. However, we show the entitlements here so you can visually confirm that everything is configured correctly.

Additionally, some users may see additional entitlements for their keys, such as `research` for education and research use.

### Allowed Origin Rules

{% hint style="info" %}
This feature is available with the **PRO** plan or higher.
{% endhint %}

You may optionally configure one or more allowed origin rules for each API key. This is done in the [developer console](https://www.radiantdrift.com/console). Edit the API key to add or remove allowed origin rules:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FLyECr8ERiirf9vzghaeB%2FCleanShot%202024-06-04%20at%2009.31.39%402x.png?alt=media&amp;token=2e8750a7-cb4a-48ca-8f30-4f2ab92975f2" alt=""><figcaption><p>Specify Allowed Origins in the API Edit Form</p></figcaption></figure>

For example, you may specify `example.com` to allow requests only with that `Origin` host, as provided in the request headers. You can also write rules that include a single wildcard, placed anywhere in the string, e.g.:

* `*.example.com`
* `api.*.example.com`
* `example.*`

Upon updating the key, any configured origins are shown on the API key page.

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FEScaq97VWFkQYnIGOLDg%2FCleanShot%202024-06-04%20at%2009.31.23%402x.png?alt=media&amp;token=6fdc1ba8-a994-4899-b1a8-9abac79c6a7a" alt=""><figcaption><p>API Key showing configured Allowed Origins</p></figcaption></figure>

{% hint style="warning" %}
If you leave the Allowed Origins field empty, requests are allowed from **any** origin.
{% endhint %}

{% hint style="info" %}
If you configure one or more origin rules, then any request that does not include an `Origin` header will be rejected with a 401 response.
{% endhint %}

Multiple rules may be specified, separated by a semicolon. You may also specify IP addresses, but be aware that these rules apply to the origin header only and not to the requesting IP address.

We recommend specifying as few rules as possible to avoid any performance impacts (although these are likely to be minimal in most cases). You may wish to consider creating additional API keys to avoid the need to specify multiple rules.

Requests that do not pass allowed origin rules a rejected with a `403 Forbidden`response.

### Allowed IP Rules

{% hint style="info" %}
This feature is available with the **PRO** plan or higher.
{% endhint %}

You may optionally configure one or more allowed IP rules for each API key. This is done in the [developer console](https://www.radiantdrift.com/console). Edit the API key to add or remove allowed IP rules:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2Fn7gyM8rx63vi3MUKajMJ%2FCleanShot%202024-06-04%20at%2010.28.00%402x.png?alt=media&amp;token=ba620b9a-3d99-4b4e-b1cc-fcdd3cf93fee" alt=""><figcaption><p>Edit Allowed IP rules in the developer console</p></figcaption></figure>

You can specify a single IP, a list of IPs, or a block of addresses in CIDR format. Any configured Allowed IPs are shown in the console:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2Fs4xWmH98qLxqB9iHM31u%2FCleanShot%202024-06-04%20at%2010.30.01%402x.png?alt=media&amp;token=f68e06c6-59c0-4623-801f-663006eb7c19" alt=""><figcaption><p>Allowed IP Addresses</p></figcaption></figure>

{% hint style="warning" %}
If you leave the Allowed IP Addresses field empty, requests are allowed from **any** IP.
{% endhint %}

We check the requesting IP address and if any rules are present, evaluate whether it is allowed or not. Rejected requests receive a `403 Forbidden` response.

{% hint style="info" %}
If you configure a rule with your local IP address, but see that your requests are rejected, you may need to configure both IPv4 and IPv6 addresses as allowed, depending on how your requests are sent over the network.

For example, a request made in a browser may be sent over IPv6, whereas a request made via an application running on your computer may be made over IPv4.
{% endhint %}


# OpenAPI Specification

We are in the process of building out our OpenAPI documentation. We reference the OpenAPI specification here in our documentation for end points that are finished or mostly complete.

### Latest Version

An [OpenAPI](https://www.openapis.org) specification is available at <https://api.radiantdrift.com/openapi/latest.json>

### Specific Version

Additionally, versioned copies of the OpenAPI spec are available, for example, v0.18.2 is available at <https://api.radiantdrift.com/openapi/0.18.2.json>

The application current version of the API is obtainable by making a GET request to <https://api.radiantdrift.com>

Only the latest version is available in our production environment at any given time. Historic versions are provided for reference purposes.


# Date/Time Format

Date/time values are found both as inputs and outputs in multiple places in the API.

## Output

We use [ISO 8601 format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) including milliseconds for all output values. Here's an example showing standard date/time output formatting:

{% code lineNumbers="true" %}

```json
{
  "query": {
    "name": "body-position",
    "start-date": "2023-06-25T17:04:02.000Z",
    "end-date": "2023-06-25T17:04:03.000Z",
    //...
  }
}
```

{% endcode %}

## Input

When a date/time is required as an input to an API endpoint, you may use a variety of formats.

`[DATE_TIME]` must be a string value representing a date, parsed and interpreted using the same algorithm implemented by Javascript's [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse)

Examples include:

ISO 8601, no milliseconds:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/body-position/2023-06-25T17:04:02Z/[...]
```

{% endcode %}

ISO 8601, with milliseconds:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/body-position/2023-06-25T17:04:02.555Z/[...]
```

{% endcode %}

Date string:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/body-position/01%20Jan%201970%2000:00:00%20GMT/[...]
```

{% endcode %}

See [date time string format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format) for caveats on using different formats.


# Validity, Accuracy, and Precision

Under construction 🚧

We plan to add information regarding validity of end points, particularly with respect to date ranges, and also expected accuracy.

Generally, calculated astronomical values are presented to 8 decimal places, which may exceed the expected accuracy in some cases. Calculated coordinates (e.g. latitude, longitudes in eclipse paths) are normally given to 6 decimal places.

It's been our experience that having precision match or exceed expected accuracy is often advantageous - not in a scientific context but in that of day-to-day software development, where comparability of results is usually most helpful and the ability to detect changes in outputs can often signify an unintended or unexpected change in inputs, assumptions, algorithms or behaviors, even if the digits that changed are not in themselves practically significant.


# Usage Guidelines

Guidelines on use of Radiant Drift APIs

{% hint style="info" %}
We've put these usage guidelines together to try to ensure we can keep developing the API and run it without breaking the bank.

If there's anything that appears to be roadblock for your use case, then please [let us know](mailto:support@radiantdrift.com). We're happy to discuss and see if we can accommodate your requirements.
{% endhint %}

Please review the guidelines in this section as you familiarize yourself with the API:

* [Attribution](/usage-guidelines/attribution)
* [Acceptable Use Policy](/usage-guidelines/acceptable-use-policy)
* [Rate Limits](/usage-guidelines/rate-limits)
* [Usage Credits](/usage-guidelines/usage-credits-and-call-costs)


# Acceptable Use Policy

How to use our APIs

This page is intended as an easy-to-read summary of a subset of our [Terms of Use](https://www.radiantdrift.com/terms-of-use). It does not replace the Terms of Use, which always take precedence.

### No scraping

Don't systematically scrape the APIs and store the results. Examples of the things that we would consider scraping:&#x20;

* Requesting all available eclipse paths
* Request data for a grid of coordinates at high frequency using an automated script

With scraping, we apply the duck test:

> If it looks like a duck, swims like a duck, and quacks like a duck, then it probably *is* a duck.

If your intended usage may appear as scraping, please contact us with details to avoid unexpected interruptions to service.

### No redistribution

By all means, use our API data to power your user interfaces, or to derive your own data to power your own sites or applications, but don't grab it from our APIs and redistribute it in substantiallly similar form.

For example, when showing a GeoJSON file on a digital map, the file should be sourced by your app, web page, or other software directly from our API URLs by each end user. Don't store the file on your own server and distribute it from there.

### No hacking or digital spelunking

Follow our published methods for accessing the APIs. Don't try to subvert security mechanisms or dig around in dark corners for undocumented end points or parameters.

### Respect cache headers

Respect the [cache headers](https://datatracker.ietf.org/doc/html/rfc7234) included in our API responses. If a response includes `Cache-Control: private` don't store that in your own shared cache. If your use case warrants a different approach, talk to us about it.&#x20;

Note, there's unlikely to be a performance-related reason to attempt your own caching: our API runs on CloudFlare and responses are automatically served from locations close to users.

### Don't share API keys

Keep control of your own API keys and do not share them with others. If you think your API keys are compromised, disable or delete them, and let us know.

### No API key stuffing

Don't encourage or provide means for end users of your software or service to sign up for their own accounts and enter their own API keys. We've seen some apps do this over the years to avoid paying for services - it's a bad look.

### Follow attribution requirements

Be sure to follow any [attribution requirements](/usage-guidelines/attribution) posted on this site.

### Rate limits

Be aware that [rate limits](/usage-guidelines/rate-limits) apply to API usage on platform, account and individual end-point levels. Adjust your usage or plan to avoid regularly blowing through them.


# Usage Credits and Call Costs

How we calculate usage credits

### Usage Credits

Your account plan includes a monthly allowance of usage credits.

Usage credits are consumed as you make calls to our service during a calendar month and your allowance is replenished at midnight UTC at the start of the following calendar month.

Each API call to our platform incurs a cost in usage credits, detailed below.

### Monitoring Usage

We offer a `/usage` end point by which you can query actual usage credits and call volume for your account.

Additionally, you can view usage charts by signing into your account on our [website](https://www.radiantdrift.com).

### Usage Alerts

If you exceed 100% of your usage credits, your API keys may stop functioning until such time as you upgrade your plan or until the start of the next calendar month.

{% hint style="info" %}
If you exceed your usage allowance, we'll contact you at your account email address to let you know prior to taking any action against your account (except where the rate of usage is such that it adversely affects our ability to operate the platform and/or our operating costs, in which circumstances we may limit your ability to make calls to the service without prior notice).
{% endhint %}

{% hint style="info" %}
🚧 We plan to add the option to receive alerts via email when your monthly usage reaches one or more thresholds (e.g. 50%, 80%, 90%).
{% endhint %}

### Call Costs

Each API end point has an associated base 'cost', which may be modified by the parameters used for the call (e.g. requesting 100 Moon positions is more expensive than requesting just 10).

Additionally, for calls which generate a JSON response (excluding GeoJSON), the actual cost of the call is generally included in the response.

The following table sets out the base cost by end point, together with additional cost factors.

<table><thead><tr><th>Endpoint</th><th width="117">Base Cost</th><th>Cost Factors</th></tr></thead><tbody><tr><td>/version</td><td>0</td><td></td></tr><tr><td>/usage</td><td>3</td><td></td></tr><tr><td>/julian-day</td><td>0.5</td><td></td></tr><tr><td>/date</td><td>0.5</td><td></td></tr><tr><td>/delta-t</td><td>0.5</td><td></td></tr><tr><td>/rise-transit-set</td><td>3</td><td>Days, Bodies</td></tr><tr><td>/az-alt-search</td><td>5</td><td>Days, Bodies</td></tr><tr><td>/celestial-events</td><td>10</td><td>Bodies, Circumstances (×1.5), Overflow (×1.2)</td></tr><tr><td>/meteor-showers</td><td>1</td><td>Meteor Showers</td></tr><tr><td>/body-position</td><td>1</td><td>Bodies, Days, Interval (points per day)</td></tr><tr><td>/geodesic</td><td>1</td><td>Points, Elevation (×2)</td></tr><tr><td>/elevation</td><td>1</td><td>Points</td></tr><tr><td>/bounding-tiles</td><td>1</td><td></td></tr><tr><td>/sightline</td><td>3</td><td>Points</td></tr><tr><td>/lunar-libration</td><td>1</td><td></td></tr><tr><td>/lunar-limb</td><td>10</td><td></td></tr><tr><td>/solar-eclipse/catalog</td><td>1 TBC</td><td></td></tr><tr><td>/solar-eclipse/elements</td><td>1 TBC</td><td></td></tr><tr><td>/solar-eclipse/path</td><td>10 TBC</td><td>Points</td></tr><tr><td>/solar-eclipse/local-circumstances</td><td>20 TBC</td><td></td></tr><tr><td>/insolation/solar-intensity</td><td>1</td><td></td></tr><tr><td>/insolation/irradiance</td><td>2</td><td>Days, Interval (points per day)</td></tr><tr><td>/insolation/daily</td><td>3</td><td>Days, Interval (points per day)</td></tr><tr><td>/insolation/monthly</td><td>3</td><td>Days, Interval (points per day)</td></tr></tbody></table>

### Determining the Cost of Call

For any Radiant Drift API, you can determine the cost of a call without consuming any usage credits by appending the `cost=1` query parameter to the URL.

### Examples

#### Body Position

* A call for just the Sun at a single time will cost 1 usage credit
* A call for Sun and Moon at a single time will cost 2 usage credits
* A call for the Sun and Moon for a period of an hour with points for every minute will cost 118 credits (2 \* 60)


# Attribution

Attribution display requirements

### Free or Starter Plans

When using our APIs, we ask that you display attribution as follows:

* For use in software or online (e.g. web pages), on the same page(s) or screen(s) where data obtained or derived from the API is displayed, include:
  * a link to <https://www.radiantdrift.com>
  * with the text 'radiantdrift.com', at a legible font size and with appropriate contrast
* In addition, you may optionally display our logo (versions suitable for display on either light or dark backgrounds are provided); logos should be displayed with a minimum size of 20px square and not subject to any change in aspect ratio (1:1)

When displaying GeoJSON data on a map, include the above attribution in the credits shown on the map (typically displayed at the lower right of the map).

{% file src="/files/UYckbHS1GPEK5Xle2xsO" %}
Logo suitable for display on light backgrounds
{% endfile %}

{% file src="/files/SYJ8u0Ve3smgnO13zQSz" %}
Logo suitable for display on dark backgrounds
{% endfile %}

### Pro and Enterprise Plans

You are welcome to display attribution as outlined above, but this is in your discretion.


# Rate Limits

Standard and Premium Rate Limits

We offer two rate limits, **standard** and **premium**.

* Standard: 10 requests per second per IP
* Premium: 25 requests per second per IP

Users on **Free** or **Starter** can utilize the standard rate limit via our default host `api.radiantdrift.com`.

Users on **Pro** or **Enterprise** plans can choose between the standard rate limit by sending requests to `api.radiantdrift.com` or the premium rate limit by using `premium.api.radiantdrift.com` instead.

Requests to `premium.api.radiantdrift.com` made using API keys without either `pro` or `enterprise` [entitlements](/getting-started/managing-api-keys#entitlements) are rejected with a `403 Forbidden` response.

### Rate Limit Enforcement

Rate limits are measured over 10 second periods, i.e. for the standard rate limit, you may in fact send 100 requests in 10 seconds. Once the rate limit is exceeded, further requests will receive a `429 Too Many Requests` response for a back off period depending on the applicable limit, as follows:

* Standard: 1 minute
* Premium: 10 seconds

### Requesting a Higher Rate Limit

If your use case warrants a higher rate limit than those posted above, please get in touch to discuss your requirements. We're happy to see if we can support them.


# Julian Day

Convert a Gregorian calendar date/time to a Julian Day or vice versa.

{% hint style="info" %}
**All** input dates are assumed to be in the Gregorian calendar. Even if you provide a date earlier than the first adoption of the Gregorian calendar, it is taken as is and is **not** assumed to be a Julian calendar date.
{% endhint %}

### Calculate Julian Day

{% openapi src="<https://api.radiantdrift.com/openapi/0.18.3.json>" path="/julian-day/{date}" method="get" %}
<https://api.radiantdrift.com/openapi/0.18.3.json>
{% endopenapi %}

### Calculate Gregorian Date/Time

{% openapi src="<https://api.radiantdrift.com/openapi/0.18.3.json>" path="/date/{julian-day}" method="get" %}
<https://api.radiantdrift.com/openapi/0.18.3.json>
{% endopenapi %}


# Delta-T

The Delta-T end point obtains an estimated Delta-T value in seconds for the given date.

The returned values are from the following sources:

* Up to year 2004:  Meeus, Astronomical Algorithms, 2nd Ed. p.79 Table 10.A.
* 2006 - 2024:  [source](http://maia.usno.navy.mil/ser7/deltat.data)
* 2024 - 2034: [source](http://maia.usno.navy.mil/ser7/deltat.preds)
* After 2034: we implement [these](https://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html) expressions

&#x20;For further context, see [Delta T](https://eclipse.gsfc.nasa.gov/LEcat5/deltat.html).

{% openapi src="<https://api.radiantdrift.com/openapi/0.18.3.json>" path="/delta-t/{date}" method="get" %}
<https://api.radiantdrift.com/openapi/0.18.3.json>
{% endopenapi %}


# Rise, Transit, Set Times

This end point calculates rising, meridian transit and setting times for the given body and observer location from start to end dates.

Optionally, an observer height above the horizon may be given in meters.

{% openapi src="<https://api.radiantdrift.com/openapi/latest.json>" path="/rise-transit-set/{start-date}/{end-date}" method="get" %}
<https://api.radiantdrift.com/openapi/latest.json>
{% endopenapi %}


# Body Position

Calculating the position of the Sun, Moon, and stars

The `body-position` end point calculates the position of one or more bodies (e.g. the Sun, and/or Moon) at a given time, or over a given time range and interval.

The general form of a call to this end point is as follows:

{% code lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/body-position/DATE_TIME_FROM",
 	"params": {
		"body": "[BODIES]"
	},
})
```

{% endcode %}

{% code overflow="wrap" %}

```bash
curl "https://api.radiantdrift.com/body-position/DATE_TIME_FROM/?body=BODIES"
```

{% endcode %}

Specific examples are given in the following sections.

### Supported Bodies

The following values are accepted for the `body` parameter:

* `sun`
* `moon`
* `gc` (the Galactic Center)


# Request Parameters

URL structure and parameters

Requests to the `body-position` end point are made as follows:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/body-position/[DATE_TIME_FROM][/DATE_TIME_TO]/?[body=BODIES|ra-decl=RA_DECL][&obs=OBSERVER][&alg=ALGORITHM][&extras=EXTRAS][&interval=INTERVAL]
```

{% endcode %}

### Request Parameters

<table><thead><tr><th width="198">Parameter</th><th width="121">Default</th><th>Description</th></tr></thead><tbody><tr><td>DATE_TIME_FROM</td><td>none</td><td>The desired start date/time in Universal Time, or the desired instant if DATE_TIME_TO is omitted</td></tr><tr><td>DATE_TIME_TO</td><td>none</td><td>The desired end date/time in Universal Time</td></tr><tr><td>BODIES</td><td>none</td><td>A comma-separated list of bodies. Allowed values are <code>sun</code>, <code>moon</code>, <code>gc</code>, where <code>gc</code> denotes the <a href="https://en.wikipedia.org/wiki/Galactic_Center">Galactic Centre</a>. Required if <code>ra_decl</code> is omitted.</td></tr><tr><td>RA_DECL</td><td>none</td><td>Comma-separated values for right ascension and declination in decimal degrees. Required if <code>bodies</code> is omitted.</td></tr><tr><td>OBSERVER</td><td>none</td><td>Comma-separated values for latitude, longitude (negative west), and elevation above mean sea level in meters; latitude/longitude values are in decimal degrees. Optional - if provided, local horizontal coordinates are included in the response</td></tr><tr><td>ALGORITHM</td><td><code>standard</code></td><td>Algorithm used to calculate positions. Allowed values are <code>standard</code>, <code>vsop-87a-tr</code> (truncated <a href="https://en.wikipedia.org/wiki/VSOP_model">VSOP87</a>, applicable only to the Sun, other bodies always use <code>standard</code>). <code>vsop-87a-tr</code> provides higher accuracy.</td></tr><tr><td>EXTRAS</td><td>none</td><td>Comma-separated list of optional extras to include in response. Allowed values are <code>distance-to-earth</code> or <code>d</code> (Sun and Moon), <code>illuminated-fraction</code> or <code>ill</code> (Moon only), <code>waxing</code> or <code>w</code> (Moon), or <code>all</code>. Either the verbose or abbreviated extra name may be used. Calculating this values may result in a (small) increase in call response time.</td></tr><tr><td>INTERVAL</td><td>60s</td><td>Interval in seconds (optional). When both <code>DATE_TIME_FROM</code> and <code>DATE_TIME_TO</code> are given, the interval determines the interval time in seconds for which positions are calculated. The minimum value is 1s.</td></tr></tbody></table>


# Position at a given time

Use the body position end point to obtain the position (and related values) of the Sun, Moon, and/or the Galactic Center in a variety of astronomical coordinate systems.

{% code lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/body-position/DATE_TIME_FROM",
 	"params": {
		"body": "[BODIES]"
	},
})
```

{% endcode %}

{% code lineNumbers="true" %}

```shell
curl "https://api.radiantdrift.com/body-position/DATE_TIME_FROM/?body=BODIES"
```

{% endcode %}

**Example**

Here is the response for the query:

{% code overflow="wrap" fullWidth="false" %}

```
GET https://api.radiantdrift.com/body-position/2023-06-25T17:04:02Z/?body=sun,moon
```

{% endcode %}

```json
{
  "query": {
    "name": "body-position",
    "start-date": "2023-06-25T17:04:02.000Z",
    "obs": null,
    "alg": "default",
    "high-accuracy": false,
    "body": [
      "sun",
      "moon"
    ],
    "ra-decl": null,
    "extras": [],
    "interval": 60
  },
  "response": {
    "2023-06-25T17:04:02.000Z": {
      "sun": {
        "dateTD": "2023-06-25T17:05:11.157Z",
        "jde": 2460121.2119346876,
        "eclipticCoordinates": {
          "λ": 93.89663542937978,
          "β": 0
        },
        "apparentCoordinates": {
          "decl": 23.38102409695048,
          "ra": 94.24584067466517
        },
        "apparentLongitude": 93.89663542937978,
        "radiusVector": 1.0164662084675626,
        "obliquityOfEcliptic": 23.436237679727896,
        "equatorialHorizontalParallax": 0.0024032060860899635
      },
      "moon": {
        "dateTD": "2023-06-25T17:05:11.157Z",
        "jde": 2460121.2119346876,
        "eclipticCoordinates": {
          "λ": 177.04245513872277,
          "β": 2.9084870004880736
        },
        "geocentricSphericalCoordinates": {
          "λ": 177.04245513872277,
          "β": 2.9084870004880736,
          "Δ": 400430.97518737416
        },
        "apparentCoordinates": {
          "ra": 178.4417120295634,
          "decl": 3.8455405824505817
        },
        "apparentLongitude": 177.04009669930034,
        "obliquityOfEcliptic": 23.43829458272879,
        "radiusVector": 15430.415187374168,
        "nutationInLongitude": -0.002358439422450305,
        "nutationInObliquity": 0.0020565238968814482,
        "equatorialHorizontalParallax": 0.912656133327504,
        "meanElongation": 88.29813566282974,
        "meanAnomalySun": 170.24599990349998,
        "meanAnomalyMoon": 223.11234450782652,
        "argOfLatitude": 150.98331171029713
      }
    }
  }
}
```

This endpoint calculates coordinates and related values for the Sun, Moon, and/or Galactic Center for the given `[DATE_TIME]` parameter.


# Positions for a time range

Get body positions at intervals between two dates

Use the `body-position` end point to obtain the position (and related values) of the Sun, Moon, and/or the Galactic Center in a variety of astronomical coordinate systems.

If both `DATE_TIME_FROM` and `DATE_TIME_TO` are specified, the API returns values for the given time range at a default time interval of 60 seconds.

You can override the default interval by supplying your own value for the `interval`query parameter.

The following example calculates the position of Sun every five minutes from 12pm UTC to 1pm UTC on Sep 1 2023:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/body-position/2023-09-01T12:00:00Z/2023-09-01T13:00:00Z/?body=sun&interval=300
```

{% endcode %}

The `response` property is a dictionary of calculated body positions at the request times/intervals.  An excerpt of the response is:

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "query": {
    "name": "body-position",
    "start-date": "2023-09-01T12:00:00.000Z",
    "end-date": "2023-09-01T13:00:00.000Z",
    "obs": null,
    "alg": "standard",
    "high-accuracy": false,
    "body": [
      "sun"
    ],
    "ra-decl": null,
    "extras": [],
    "interval": 300
  },
  "response": {
    "2023-09-01T12:00:00.000Z": {
      "sun": {
        "dateTD": "2023-09-01T12:01:09.140Z",
        "jde": 2460189.00080023,
        "eclipticCoordinates": {
          "λ": 158.80751482,
          "β": 0
        },
        "apparentCoordinates": {
          "decl": 8.26737356,
          "ra": 160.41792175
        },
        "apparentLongitude": 158.80751482,
        "radiusVector": 1.00927514,
        "obliquityOfEcliptic": 23.43621354,
        "equatorialHorizontalParallax": 0.00242033
      }
    },
    "2023-09-01T12:05:00.000Z": {
      "sun": {
        "dateTD": "2023-09-01T12:06:09.140Z",
        "jde": 2460189.00427245,
        "eclipticCoordinates": {
          "λ": 158.81087415,
          "β": 0
        },
        "apparentCoordinates": {
          "decl": 8.26611461,
          "ra": 160.42106895
        },
        "apparentLongitude": 158.81087415,
        "radiusVector": 1.00927432,
        "obliquityOfEcliptic": 23.43621354,
        "equatorialHorizontalParallax": 0.00242033
      }
    },
    "2023-09-01T12:10:00.000Z": {
      "sun": {
        "dateTD": "2023-09-01T12:11:09.140Z",
        "jde": 2460189.00774468,
        ...
```

{% endcode %}


# Observer location

Calculating local horizontal coordinates with respect to an observer

To calculate local horizontal coordinates (topocentric) for an observer located at an arbitrary location on (or above) the Earth's surface, include a suitable value for the `obs` query parameter:

{% code lineNumbers="true" %}

```javascript
 axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/body-position/DATE_TIME_FROM",
 	"params": {
		"body": "[BODIES]",
		"obs": "LAT,LNG,HEIGHT"
	},
})
```

{% endcode %}

{% code overflow="wrap" lineNumbers="true" %}

```shell
curl "https://api.radiantdrift.com/body-position/DATE_TIME_FROM/?obs=LAT,LNG,HEIGHT&body=BODIES"
```

{% endcode %}

`LAT` is the observer latitude in decimal degrees and `LNG` is the longitude (negative west). HEIGHT is the observer elevation above mean sea level, given in meters. If no elevation value is available, use zero (0m).

**Example**

The following query calculates the position of the Moon for March 21 2025 at 13:04:30 UTC as observed in Boulder, Colorado, USA:

{% code overflow="wrap" fullWidth="false" %}

```
GET https://api.radiantdrift.com/body-position/2025-03-21T13:04:30Z/?obs=40.009728,-105.237709,1612&body=moon
```

{% endcode %}

A `localHorizontal` object is included in the response, giving true and apparent azimuth/altitude coordinates for the observer, together with parallax and the effect of estimated refraction.

```json
{
  "query": {
    "name": "body-position",
    "start-date": "2025-03-21T13:04:30.000Z",
    "obs": {
      "lat": 40.009728,
      "lng": -105.237709,
      "height": 1612
    },
    "alg": "standard",
    "high-accuracy": false,
    "body": [
      "moon"
    ],
    "ra-decl": null,
    "extras": [],
    "interval": 60
  },
  "response": {
    "2025-03-21T13:04:30.000Z": {
      "moon": {
        "dateTD": "2025-03-21T13:05:39.073Z",
        "jde": 2460756.04559112,
        "eclipticCoordinates": {
          "λ": 260.52729877,
          "β": -5.25429849
        },
        "geocentricSphericalCoordinates": {
          "λ": 260.52729877,
          "β": -5.25429849,
          "Δ": 398136.53563773
        },
        "apparentCoordinates": {
          "ra": -100.73114387,
          "decl": -28.34079256
        },
        "apparentLongitude": 260.52750373,
        "obliquityOfEcliptic": 23.43866925,
        "radiusVector": 13135.97563773,
        "nutationInLongitude": 0.00020496,
        "nutationInObliquity": 0.00265718,
        "equatorialHorizontalParallax": 0.91791617,
        "meanElongation": 267.39595465,
        "meanAnomalySun": 75.93822925,
        "meanAnomalyMoon": 237.2096644,
        "argOfLatitude": 269.42006603,
        "localHorizontal": {
          "true": {
            "azimuth": 190.28208172,
            "altitude": 20.04241573
          },
          "apparent": {
            "azimuth": 190.28208172,
            "altitude": 20.08140602
          },
          "parallax": {
            "azimuth": 0,
            "altitude": 0.85634116
          },
          "refraction": 0.0389903
        }
      }
    }
  }
}
```

The effect of atmospheric refraction is generally to increase the altitude of the body for the observer, as seen in the example above. The effect is more pronounced near the horizon.


# Solar Eclipses

Local circumstances, Besselian elements, eclipse paths

### End points

We support a variety of end points related to solar eclipses. The following are currently available:

* Besselian elements
* Local circumstances
* Eclipse paths (JSON or [GeoJSON](https://geojson.org) format) - BETA

### Availability

The end points support all solar eclipses occurring between the years 1500 and 2500.


# Embeddable Web Widgets

Eclipse maps and simulators

The following widgets can be embedded in your own web page:

* [Interactive eclipse map](/solar-eclipses/embeddable-web-widgets/eclipse-map)
* [Eclipse simulator](/solar-eclipses/embeddable-web-widgets/eclipse-simulator)

The web widgets are easily configured by URL parameters. Please see the relevant page for full details.


# Eclipse Map

Interactive, customizable eclipse maps for your website

### Embed an eclipse map on your own page

You can embed an interactive eclipse map directly on your website:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FAL6Z7CFyPmiKIGY5ywSx%2Feclipse-path-widget.png?alt=media&amp;token=86ce4171-1e2c-4115-b01d-51af74598314" alt=""><figcaption><p>Screenshot showing embeddable eclipse path widget</p></figcaption></figure>

There are a number of advantages to this approach, compared to other methods:

* Your visitors can explore the map without leaving your page (map can be zoomed and panned)
* You can highlight exactly the area of interest to your audience (e.g. your county or state) without needing to obtain a custom map
* The map marker can be positioned to show your exact location, along with customizable title and subtitle
* There's no need to lookup and transcribe the local circumstances of the eclipse (times, magnitude, duration) - they are calculated and displayed automatically
* Supports any solar eclipse between the years 1500 and 2500.

### Embedding the eclipse map widget

The eclipse map can be included either via a simple `iframe` or `embed` tag on your web page. No JavaScript is required, and configuration is simple, via a handful of URL parameters:

{% code title="" overflow="wrap" lineNumbers="true" %}

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Radiant Drift Eclipse Widgets</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <div>
        <h1>Interactive Eclipse Map</h1>
        <p>Customizable, with pan and zoom</p>
        <iframe
          id="path"
          title="Eclipse Path"
          height="350"
                src="https://widget.radiantdrift.com/eclipse-path?center=31.5,-101&z=6&apiKey=[YOUR_API_KEY]&map=osm&date=2023-10-14&ll=31.9974,-102.0779&title=Midland, Texas&subtitle=Just north of the central path"
        >
        </iframe>
      </div>
    </div>
  </body>
</html>

```

{% endcode %}

Try it now - edit the the following example on CodePen, replacing `YOUR_API_KEY` with (you guessed it...) your own API key:

{% embed url="<https://codepen.io/stephent/pen/MWZQLpx>" %}
Codepen example showing embeddable eclispe map
{% endembed %}

### Configuation options

The eclipse map can be configured using the following URL search parameters:

<table><thead><tr><th width="155">Parameter</th><th width="100">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>apiKey</code></td><td>none</td><td>Required. A valid API key</td></tr><tr><td><code>obs</code></td><td>none</td><td>Optional. Two comma-separated values, representing the latitude and longitude (negative west). When supplied, a map marker is shown at the given location.</td></tr><tr><td><code>title</code></td><td>none</td><td>Optional. Title string to be displayed in the map marker popover. This parameter has no effect if <code>obs</code> is omitted.</td></tr><tr><td><code>subtitle</code></td><td>none</td><td>Optional. Subtitle text (string) to be displayed in the map marker popover. This parameter has no effect if <code>obs</code> is omitted.</td></tr><tr><td><code>center</code></td><td>0,0</td><td>Optional (but recommended). Two comma-separated values representing the latitude and longitude (negative west) on which the map should be centered.</td></tr><tr><td><code>z</code></td><td>13</td><td>Optional. Zoom level (integer) at which the map should be displayed. Supported values vary by selected map type, but are typically in the range 0 to 19. Higher values represent higher zoom levels (i.e. smaller map area displayed)</td></tr><tr><td><code>map</code></td><td>osm</td><td>Optional. String value to select the displayed map type. Supported values are 'osm' (Open Street Map), 'ocm' (Open Cycle Map), 'top' (TopPlusOpen) (more coming soon).</td></tr><tr><td><code>date</code></td><td>None</td><td>Required. The date of the eclipse event to be displayed. Must be midnight UTC of the desired day. Format must be a value or dateString accepted by the JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date">Date constructor</a>. We recommend using <code>YYYY-MM-DD</code> for simplicity, e.g. 2024-04-08 for the Apr 8 2024 eclipse. (The time zone of your location does not matter - the value must be midnight UTC.)</td></tr><tr><td><code>tzid</code></td><td>None</td><td>Optional. A <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">TZ identifier</a> (time zone ID) to be used to format times displayed in the widget, e.g. Europe/Berlin or America/Denver. When omitted, the user's operating system time zone is used.</td></tr></tbody></table>


# Eclipse Simulator

A customizable, interactive eclipse simulator for your website

### Embed an eclipse simulator on your own page

You can embed an interactive eclipse simulator directly on your website, allowing your visitors to understand what they can observe during an eclipse.

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2F6Z40OGuXKJiubqphzsKx%2Feclipse-simulator-screenshot.png?alt=media&amp;token=a7295a04-a19b-41fc-85f3-c89a3479fe83" alt="Eclipse simulator showing Apr 8 2024 eclipse at Torreon, Mexico"><figcaption></figcaption></figure>

A live demo of the eclipse simulator is available at [demo.radiantdrift.com](https://demo.radiantdrift.com).

There are a number of advantages to the embedding approach, compared to other methods:

* Your visitors can view and interact with the simulation without leaving your page
* You can show a simulation for the exact point of interest for your audience (e.g. your organization's physical location) without needing to use an approximate nearby location such as another town or county
* There's no need to lookup and transcribe the local circumstances of the eclipse (times, magnitude, duration) - they are calculated and displayed automatically
* Supports any solar eclipse between the years 1500 and 2500.

### Features

* Graphical display for all eclipse types (partial, total, annular)
* Animated playback with user selectable speed (x1, x5, x100)
* Clickable contact controls to quickly select a moment of the eclipse
* Time slider for manual control/scrubbing
* Shows instantaneous eclipse magnitude and obscuration (% cover)
* Shows time to next contact. For example, clicking 'C2' will show the duration of totality or annularity
* Displays warning triangle when eye protection is required (all times other than totality)

### Embedding the eclipse simulator widget

The eclipse simulator can be included either via a simple `iframe` or `embed` tag on your web page. No JavaScript is required, and configuration is simple, using a handful of URL parameters:

{% code title="" overflow="wrap" lineNumbers="true" %}

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Radiant Drift Eclipse Widgets</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app">
      <div>
        <h1>Interactive Eclipse Simulator</h1>
        <p>Replace 'YOUR_API_KEY' with a valid API key.</p>
        <iframe
          id="simulator"
          title="Eclipse Simulator"
          height="350"
                src="https://widget.radiantdrift.com/eclipse-sim?date=2024-04-08&obs=25.5427,-103.4105&tzid=America/Monterrey&apiKey=YOUR_API_KEY"
        >
        </iframe>
      </div>
    </div>
  </body>
</html>

```

{% endcode %}

Try it now - edit the the following example on CodePen, replacing `YOUR_API_KEY` with (you guessed it...) your own API key:

{% embed url="<https://codepen.io/stephent/pen/LYMdOYy>" %}

### Configuation options

The eclipse map can be configured using the following URL search parameters:

<table><thead><tr><th width="155">Parameter</th><th width="100">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>apiKey</code></td><td>none</td><td>Required. A valid API key</td></tr><tr><td><code>date</code></td><td>None</td><td>Required. The date of the eclipse event to be displayed. Must be midnight UTC of the desired day. Format must be a value or dateString accepted by the JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date">Date constructor</a>. We recommend using <code>YYYY-MM-DD</code> for simplicity, e.g. 2024-04-08 for the Apr 8 2024 eclipse. (The time zone of your location does not matter - the value must be midnight UTC.)</td></tr><tr><td><code>tzid</code></td><td>None</td><td>Optional. A <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">TZ identifier</a> (time zone ID) to be used to format times displayed in the widget, e.g. Europe/Berlin or America/Denver. When omitted, the user's operating system time zone is used.</td></tr></tbody></table>


# Besselian Elements

Returns Besselian elements as raw data or a structured response

[Besselian elements](https://en.wikipedia.org/wiki/Besselian_elements) are used to calculate data related to the circumstances and observation of solar eclipses. They are represented by a set of numeric values which can be used in conjunction with standard methods developed by Bessel, Chauvenet, Comrie, Meeus and others to perform a variety of eclipse related computations.

If you are performing your own eclipse calculations, the Besselian elements are almost certainly a required input.

For an explanation of the astronomical significance of the numbers included in the Besselian elements, please consult one of the standard sources, such as the *Explanatory Supplement to the Astronomical Almanac*.

{% hint style="info" %}
Acknowledgement:&#x20;

* Eclipse Predictions by Fred Espenak, NASA's GSFC, [NASA/Goddard Space Flight Center](https://support.photoephemeris.com/hc/en-us/articles/eclipse.gsfc.nasa.gov)
  {% endhint %}

### Availability

Besselian elements are available for all solar eclipses occurring between the years 1500 and 2500

### Delta T Predictions

For eclipses occurring in within the coming 12 months, the Delta T values included in the Besselian elements are periodically updated from values predicted by [IERS Bulletin-A](https://datacenter.iers.org/data/latestVersion/bulletinA.txt).&#x20;

As an eclipse  approaches, the predicted value of Delta T may be subject to (typically) minor revisions of the order of a fraction of a second. Such changes, applied to eclipse calculations, change local circumstances timings, position angles, and the location of paths - however, such changes are usually relatively minor.&#x20;

### Request format

Given the midnight UTC on the date of the eclipse, converted to a Julian Day, the request is made as shown:

{% tabs %}
{% tab title="JavaScript" %}
{% code overflow="wrap" lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/solar-eclipse/elements/[JULIAN_DAY",
	"params": {
		"apiKey": [YOUR_API_KEY]
	},
	"headers": {
		"Accept-Encoding": "deflate, gzip, br"
	}
})
```

{% endcode %}
{% endtab %}

{% tab title="cURL" %}
{% code overflow="wrap" lineNumbers="true" %}

```bash
curl "https://api.radiantdrift.com/solar-eclipse/elements/[JULIAN_DAY]?apiKey=[YOUR_API_KEY]" \
     -H 'Accept-Encoding: deflate, gzip, br'
```

{% endcode %}
{% endtab %}
{% endtabs %}

If no elements are available for the given `JULIAN_DAY`, a `404 Not Found` response is given.

### Example

The following request returns the Besselian elements for the total solar eclipse of Apr 20 2023:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/solar-eclipse/elements/2460054.5
```

{% endcode %}

The expected response is as follows:

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "query": {
    "name": "solar-eclipse/elements",
    "jd": 2460054.5,
    "credit": "Eclipse Predictions by Fred Espenak, NASA/Goddard Space Flight Center Emeritus, http://eclipse.gsfc.nasa.gov/"
  },
  "response": {
    "tMax": 2460054.67912,
    "t0": 4,
    "dT": 69.2,
    "x": [
      0.02685,
      0.49501821,
      0.0000135,
      -0.00000706
    ],
    "y": [
      -0.42736599,
      0.2441992,
      -0.0000494,
      -0.00000368
    ],
    "d": [
      11.41178989,
      0.013741,
      -0.000003,
      0
    ],
    "l1": [
      0.54680401,
      0.0001216,
      -0.0000116,
      0
    ],
    "l2": [
      0.000663,
      0.000121,
      -0.0000115,
      0
    ],
    "mu": [
      240.24293518,
      15.00341988,
      0,
      0
    ],
    "tanF1": 0.004655,
    "tanF2": 0.0046318,
    "latGreatestEclipse": -9.6,
    "lngGreatestEclipse": 125.8
  }
}
```

{% endcode %}

### Raw data

By including the query parameter `raw=1` in the request, the API will return raw data. For example for the request

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/solar-eclipse/elements/2460231.5?raw=1
```

{% endcode %}

the expected response is:

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "query": {
    "name": "solar-eclipse/elements",
    "jd": 2460231.5,
    "credit": "Eclipse Predictions by Fred Espenak, NASA/Goddard Space Flight Center Emeritus, http://eclipse.gsfc.nasa.gov/"
  },
  "response": [
    2460232.25047,
    18,
    69.1,
    [
      0.16965801,
      0.45855331,
      0.0000278,
      -0.00000543
    ],
    [
      0.33485901,
      -0.2413671,
      0.000024,
      0.00000303
    ],
    [
      -8.24419022,
      -0.014888,
      0.000002,
      0
    ],
    [
      0.56431103,
      -0.0000891,
      -0.0000103,
      0
    ],
    [
      0.018083,
      -0.0000886,
      -0.0000103,
      0
    ],
    [
      93.50173187,
      15.00352955,
      0,
      0
    ],
    0.0046882,
    0.0046648,
    11.4,
    -83.1
  ]
}
```

{% endcode %}

In this case, the array included in the `response` property conforms to the following Typescript type:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
export type BesselianElementsRaw = [
  number,
  number,
  number,
  [number, number, number, number],
  [number, number, number, number],
  [number, number, number, number],
  [number, number, number, number],
  [number, number, number, number],
  [number, number, number, number],
  number,
  number,
  number,
  number,
];
```

{% endcode %}

This, in turn can be mapped to the following type as follows:

```typescript
export type Degrees = number;

export type BesselianElements = {
  tMax: number;
  t0: number;
  dT: number;
  x: Array<number>;
  y: Array<number>;
  d: Array<number>;
  l1: Array<number>;
  l2: Array<number>;
  mu: Array<number>;
  tanF1: number;
  tanF2: number;
  latGreatestEclipse: Degrees;
  lngGreatestEclipse: Degrees;
};

function createElements(rawElements: BesselianElementsRaw): BesselianElements | null {

  try {

    const result: BesselianElements = {
      tMax: rawElements[0],
      t0: rawElements[1],
      dT: rawElements[2],
      x: rawElements[3],
      y: rawElements[4],
      d: rawElements[5],
      l1: rawElements[6],
      l2: rawElements[7],
      mu: rawElements[8],
      tanF1: rawElements[9],
      tanF2: rawElements[10],
      latGreatestEclipse: rawElements[11],
      lngGreatestEclipse: rawElements[12],
    }

    return result;
  } catch (error: any) {
    console.log('createElements: %s', (error as Error)?.message);
  }

  return null;
}
```

You can request whichever format (raw or structured) is most suitable for your application and adapt the example code above to convert from raw to your own typed language implementation.


# Local Circumstances

Calculate the local circumstances of an eclipse for an observer

{% hint style="info" %}
This API is available on the **Starter** plan or higher
{% endhint %}

The timing and characteristics of the key events (contact times) varies based on an observer's location. The 'local circumstances' represent what an observer at a given location will (weather permitting) be able to observe.

The `local-circumstances` end point calculates:

* C1: First contact, the start of the partial eclipse phase
* C2: Second contact, the start of the total eclipse (or annularity in the case of annular eclipses)
* Max eclipse: the instant of greatest eclipse
* C3: Third contact, the end of totality or annularity
* C4: Fourth contact, the end of the partial eclipse

{% hint style="info" %}
C2 and C3 do not occur for partial eclipses. Not all observers will observe all events.
{% endhint %}

{% hint style="info" %}
C2 and C3 contact times are **not** adjusted for the effects of the lunar limb. Uneveness in the profile of the Moon's limb can result in changes in standard contact times of a few seconds or even tens of second in some circumstances (e.g. for locations near the edge of the path of totality/annularity).
{% endhint %}

### Request format

Given the midnight UTC on the date of the eclipse, converted to a Julian Day, the request is made as shown:

{% code overflow="wrap" lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/solar-eclipse/local-circumstances/details/[JULIAN_DAY]",
	"params": {
		"apiKey": [YOUR_API_KEY],
		"obs": "[LAT,LNG,HEIGHT]"
	},
	"headers": {
		"Accept-Encoding": "deflate, gzip, br"
	}
})
```

{% endcode %}

Or, using `curl`:

{% code overflow="wrap" lineNumbers="true" %}

```bash
curl "https://api.radiantdrift.com/solar-eclipse/local-circumstances/details/[JULIAN_DAY]?apiKey=[YOUR_API_KEY]y&obs=[LAT,LNG,HEIGHT]" \
     -H 'Accept-Encoding: deflate, gzip, br'
```

{% endcode %}

If no elements are available for the given `JULIAN_DAY`, a `404 Not Found` response is given.

### Example request

The following request obtains the local circumstances of the eclipse of Apr 8 2024 for an observer located in Mazatlan, Mexico, in the path of totality:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/solar-eclipse/local-circumstances/details/2460408.5?apiKey=[YOUR_API_KEY]&obs=23.2494,-106.4111,6
```

{% endcode %}

The expected response is as follows:

{% code overflow="wrap" lineNumbers="true" %}

```json5
{
  "query": {
    "name": "solar-eclipse/local-circumstances/details",
    "jd": 2460408.5,
    "obs": {
      "lat": 23.2494,
      "lng": -106.4111,
      "height": 6
    },
    "elements": {
      "tMax": 2460409.26284,
      "t0": 18,
      "dT": 69.1,
      "x": [
        -0.31824401,
        0.5117116,
        0.0000326,
        -0.00000842
      ],
      "y": [
        0.21976399,
        0.2709589,
        -0.0000595,
        -0.00000466
      ],
      "d": [
        7.58620024,
        0.014844,
        -0.000002,
        0
      ],
      "l1": [
        0.53581399,
        0.0000618,
        -0.0000128,
        0
      ],
      "l2": [
        -0.010272,
        0.0000615,
        -0.0000127,
        0
      ],
      "mu": [
        89.59121704,
        15.00407982,
        0,
        0
      ],
      "tanF1": 0.0046683,
      "tanF2": 0.004645,
      "latGreatestEclipse": 25.3,
      "lngGreatestEclipse": -104.1
    }
  },
  "response": {
    "type": 8,
    "magnitude": 1.02094111,
    "contacts": [
      {
        "contact": 1,
        "key": "solar_eclipse_first_contact",
        "circumstances": {
          "t": -1.12283699,
          "x": -0.8927597,
          "xʹ": 0.51160654,
          "y": -0.0845471,
          "yʹ": 0.27107489,
          "d": 7.56953033,
          "sinD": 0.13172925,
          "cosD": 0.99128573,
          "dʹ": 0.01484849,
          "μ": 72.74408127,
          "μʹ": 15.00407982,
          "l1": 0.53572846,
          "l2": -0.01035707,
          "θ": -33.95572368,
          "θrad": -0.59263918,
          "cosθ": 0.82946945,
          "ξ": -0.5134634,
          "η": 0.28843316,
          "ζ": 0.8075434,
          "ξʹ": 0.19967925,
          "ηʹ": -0.01792172,
          "u": -0.3792963,
          "v": -0.37298026,
          "uʹ": 0.31192729,
          "vʹ": 0.28899661,
          "m": 0.53195861,
          "n": 0.42522662,
          "L1": 0.53195861,
          "L2": -0.01410811,
          "D": -0.2261029,
          "Δ": 0.01582068,
          "ψ1": 0.02974483,
          "ψ2": null,
          "f1": 0.00466827,
          "f2": 0.00464497,
          "ΔTcorrection": 0.00503885,
          "ρcosΦʹ": 0.91927577,
          "ρsinΦʹ": 0.39229676,
          "contact": 1
        },
        "observational": {
          "magnitude": 0,
          "obscuration": 0,
          "angularSeparation": 0.54705233,
          "sunAzAlt": {
            "azimuth": 110.18555172,
            "altitude": 53.84977956
          },
          "moonAzAlt": {
            "azimuth": 111.08044948,
            "altitude": 53.99663169
          },
          "sunSemidiameter": 0.26617147,
          "moonSemidiameter": 0.28088085,
          "moonDistance": 354503.87833613,
          "P": 225.48103852,
          "C": 299.54650213,
          "V": 74.06546362
        },
        "date": "2024-04-08T16:51:28.736Z"
      },
      {
        "contact": 2,
        "key": "solar_eclipse_second_contact",
        "circumstances": {
          "t": 0.14453601,
          "x": -0.2442826,
          "xʹ": 0.5117205,
          "y": 0.25892605,
          "yʹ": 0.27094141,
          "d": 7.58834569,
          "sinD": 0.13205477,
          "cosD": 0.99124242,
          "dʹ": 0.01484342,
          "μ": 91.75984683,
          "μʹ": 15.00407982,
          "l1": 0.53582265,
          "l2": -0.01026338,
          "θ": -14.93995812,
          "θrad": -0.26075146,
          "cosθ": 0.96619652,
          "ξ": -0.23699544,
          "η": 0.27157,
          "ζ": 0.93222722,
          "ξʹ": 0.23259374,
          "ηʹ": -0.00843711,
          "u": -0.00728717,
          "v": -0.01264395,
          "uʹ": 0.27912676,
          "vʹ": 0.27937852,
          "m": 0.01459357,
          "n": 0.39492291,
          "L1": 0.53147074,
          "L2": -0.01459357,
          "D": -0.00556649,
          "Δ": 0.00378147,
          "ψ1": 0.00711516,
          "ψ2": -0.26210965,
          "f1": 0.00466827,
          "f2": 0.00464497,
          "ΔTcorrection": 0.00503885,
          "ρcosΦʹ": 0.91927577,
          "ρsinΦʹ": 0.39229676,
          "contact": 2
        },
        "observational": {
          "magnitude": 1,
          "obscuration": 1,
          "angularSeparation": 0.01503645,
          "sunAzAlt": {
            "azimuth": 135.13101636,
            "altitude": 68.76281369
          },
          "moonAzAlt": {
            "azimuth": 135.17020821,
            "altitude": 68.75786285
          },
          "sunSemidiameter": 0.26617266,
          "moonSemidiameter": 0.28142289,
          "moonDistance": 353837.29855401,
          "P": 29.95639567,
          "C": 319.16166223,
          "V": 289.20526656
        },
        "date": "2024-04-08T18:07:31.279Z"
      },
      {
        "contact": 0,
        "key": "sun_max_eclipse_time_local",
        "circumstances": {
          "t": 0.18025921,
          "x": -0.22600227,
          "xʹ": 0.51172253,
          "y": 0.26860487,
          "yʹ": 0.27093699,
          "d": 7.58887594,
          "sinD": 0.13206394,
          "cosD": 0.9912412,
          "dʹ": 0.01484328,
          "μ": 92.29584058,
          "μʹ": 15.00407982,
          "l1": 0.53582471,
          "l2": -0.01026133,
          "θ": -14.40396437,
          "θrad": -0.2513966,
          "cosθ": 0.96856595,
          "ξ": -0.2286762,
          "η": 0.27127372,
          "ζ": 0.93438882,
          "ξʹ": 0.23316413,
          "ηʹ": -0.00815053,
          "u": 0.00267392,
          "v": -0.00266885,
          "uʹ": 0.2785584,
          "vʹ": 0.27908752,
          "m": 0.00377792,
          "n": 0.39431539,
          "L1": 0.53146271,
          "L2": -0.01460156,
          "D": 0,
          "Δ": 0.00377792,
          "ψ1": 0.00710858,
          "ψ2": -0.26171099,
          "f1": 0.00466827,
          "f2": 0.00464497,
          "ΔTcorrection": 0.00503885,
          "ρcosΦʹ": 0.91927577,
          "ρsinΦʹ": 0.39229676,
          "contact": 0
        },
        "observational": {
          "magnitude": 1.02094111,
          "obscuration": 1,
          "angularSeparation": 0.00389269,
          "sunAzAlt": {
            "azimuth": 136.25653606,
            "altitude": 69.10721832
          },
          "moonAzAlt": {
            "azimuth": 136.25554776,
            "altitude": 69.10334163
          },
          "sunSemidiameter": 0.26617268,
          "moonSemidiameter": 0.28143163,
          "moonDistance": 353826.32547418,
          "P": 134.94563484,
          "C": 320.14128192,
          "V": 185.19564708
        },
        "date": "2024-04-08T18:09:39.883Z"
      },
      {
        "contact": 3,
        "key": "solar_eclipse_third_contact",
        "circumstances": {
          "t": 0.21607801,
          "x": -0.20767295,
          "xʹ": 0.51172451,
          "y": 0.27830942,
          "yʹ": 0.27093253,
          "d": 7.58940761,
          "sinD": 0.13207314,
          "cosD": 0.99123997,
          "dʹ": 0.01484314,
          "μ": 92.83326868,
          "μʹ": 15.00407982,
          "l1": 0.53582675,
          "l2": -0.0102593,
          "θ": -13.86653628,
          "θrad": -0.24201671,
          "cosθ": 0.97085662,
          "ξ": -0.2203146,
          "η": 0.27098694,
          "ζ": 0.93647865,
          "ξʹ": 0.23371557,
          "ηʹ": -0.00786242,
          "u": 0.01264165,
          "v": 0.00732249,
          "uʹ": 0.27800894,
          "vʹ": 0.27879496,
          "m": 0.01460925,
          "n": 0.3937202,
          "L1": 0.53145498,
          "L2": -0.01460925,
          "D": 0.00555596,
          "Δ": 0.00378114,
          "ψ1": 0.00711475,
          "ψ2": -0.26179848,
          "f1": 0.00466827,
          "f2": 0.00464497,
          "ΔTcorrection": 0.00503885,
          "ρcosΦʹ": 0.91927577,
          "ρsinΦʹ": 0.39229676,
          "contact": 3
        },
        "observational": {
          "magnitude": 1,
          "obscuration": 1,
          "angularSeparation": 0.01505352,
          "sunAzAlt": {
            "azimuth": 137.41964248,
            "altitude": 69.44542616
          },
          "moonAzAlt": {
            "azimuth": 137.37727188,
            "altitude": 69.44312819
          },
          "sunSemidiameter": 0.2661727,
          "moonSemidiameter": 0.28144002,
          "moonDistance": 353815.7729215,
          "P": 239.91906605,
          "C": 321.15825633,
          "V": 81.23919028
        },
        "date": "2024-04-08T18:11:48.830Z"
      },
      {
        "contact": 4,
        "key": "solar_eclipse_fourth_contact",
        "circumstances": {
          "t": 1.55597623,
          "x": 0.47801428,
          "xʹ": 0.51175189,
          "y": 0.64120799,
          "yʹ": 0.27073989,
          "d": 7.60929231,
          "sinD": 0.13241715,
          "cosD": 0.99119408,
          "dʹ": 0.01483778,
          "μ": 112.93720862,
          "μʹ": 15.00407982,
          "l1": 0.53587916,
          "l2": -0.01020705,
          "θ": 6.23740366,
          "θrad": 0.10886323,
          "cosθ": 0.99408025,
          "ξ": 0.09987778,
          "η": 0.26783495,
          "ζ": 0.95773356,
          "ξʹ": 0.23930622,
          "ηʹ": 0.00321536,
          "u": 0.37813651,
          "v": 0.37337304,
          "uʹ": 0.27244567,
          "vʹ": 0.26752454,
          "m": 0.53140817,
          "n": 0.38183245,
          "L1": 0.53140817,
          "L2": -0.01465573,
          "D": 0.2029081,
          "Δ": -0.00147466,
          "ψ1": -0.00277502,
          "ψ2": 0.10079094,
          "f1": 0.00466827,
          "f2": 0.00464497,
          "ΔTcorrection": 0.00503885,
          "ρcosΦʹ": 0.91927577,
          "ρsinΦʹ": 0.39229676,
          "contact": 4
        },
        "observational": {
          "magnitude": 0,
          "obscuration": 0,
          "angularSeparation": 0.5476507,
          "sunAzAlt": {
            "azimuth": 201.94357928,
            "altitude": 73.25347858
          },
          "moonAzAlt": {
            "azimuth": 201.11359596,
            "altitude": 73.74781739
          },
          "sunSemidiameter": 0.26617281,
          "moonSemidiameter": 0.28147788,
          "moonDistance": 353751.88377885,
          "P": 45.36316599,
          "C": 20.26891699,
          "V": 334.90575101
        },
        "date": "2024-04-08T19:32:12.464Z"
      }
    ]
  }
}
```

{% endcode %}

The `query` object includes all parameters used for the calculation, including a copy of the Besselian elements, which may be useful for reference and comparison with results from other sources.

The `response` object includes some general properties of the eclipse, including its type and greatest magnitude (see below), and an array of contacts.

### Response fields

#### Type

The `type` field is a numeric `enum` value that characterizes the eclipse. This value is applicable to the global circumstances of the eclipse, rather than specific to the local observer.

Values are defined as:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
/**
 * See https://en.wikipedia.org/wiki/Solar_eclipse - Terminology for central eclipse
 * See https://eclipse.gsfc.nasa.gov/SEhelp/SEglossary.html - particularly for non-central eclipses
 * SolarNonCentral may represent a Non-central total, annular or hybrid eclipse 
 * @enum {number} EclipseType 
 */
export enum EclipseType {
  None = 0,
  LunarPenumbral,
  LunarPartial,
  LunarTotal,
  SolarPartial,
  SolarNonCentral,
  SolarCentralAnnular,
  SolarCentralHybrid,
  SolarCentralTotal
}
```

{% endcode %}

#### Magnitude

The `magnitude` is the ratio to the Sun's diameter of the straight line segment passing through the centers of the discs of the Sun and Moon and having the Sun's limb that is nearest to the Moon's center and the Moon's limb that is nearest to the Sun's center as its endpoints.

* For a partial eclipse, magnitude is > 0.0 and < 1.0
* For a total eclipse, at C2 and C3, magnitude = 1.0 and at the time of greatest eclipse, magnitude is > 1.0
* For an annular eclipse, magnitude is always < 1.0

#### Contacts

The `contacts`field contains an array of 0 to 4 objects representing the contact times calculated for the event and observer.

* If no eclipse is visible, there will be no contacts given
* For a partial only eclipse, only C1, greatest eclipse, and C4 will be returned
* For a total, annular, or hybrid (e.g. annular-total, or annular-total-annular, total-annular) eclipse, all contacts C1, C2, C3, C4 and the details of greatest eclipse (which occurs between C2 and C3) will be returned

Each contact is classified using a numeric enum value in the `contact` property, where the values are as follows:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
enum SolarEclipseContact {
  Greatest,  // 0
  C1,        // 1
  C2,        // 2
  C3,        // 3
  C4         // 4
}
```

{% endcode %}

{% hint style="info" %}
While the moment 'greatest eclipse' does not strictly speaking represent a 'contact' (i.e. a limb of the Moon tangent to a limb of the Sun), it is convenient to consider this instant in the same context as the formal contact times.
{% endhint %}

Additionally, a descriptive `key` string property identifies each entry in the `contacts` array, e.g. `solar_eclipse_fourth_contact`.

#### Date

The `date` field contains the time at which the contact is calculated to occur for the observer. Remember that these are **local circumstances** - if you repeat the call for a different latitude or longitude, you'll get different answers. (If you keep the same latitude or longitude, but vary only the observer height above sea level, you'll get very slightly different answers.)

#### Circumstances

The `circumstances`field contains a number of numerical quantities used during the course of calculation. These can be used to verify calculation steps or to derive additional results.

{% hint style="info" %}
Many of these values will be familiar to those who have performed their own eclipse calculations. We hope to document these more fully in the future. Please contact us if you have any specific questions.
{% endhint %}

#### Observational

The `observational` field contains a number of values that more fully describe the observational circumstances of the contact for the observer. For example, these values can be used to construct a simple graphical visualization of the local circumstances of the eclipse at key moments.

The sub-fields are as shown:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
type Degrees = number;
type AzimuthFromNorth = Degrees;

interface LocalHorizontalCoordinates {
  azimuth: AzimuthFromNorth;
  altitude: Degrees;
}

type ObservationalCircumstances = {
  magnitude: number; // unitless, instantaneous magnitude (see definition above)
  obscuration: number; // unitless, fractional area of the Sun's disc that is obscured by the Moon
  angularSeparation: Degrees; // angular separation between the centers of Sun and Moon
  sunAzAlt: LocalHorizontalCoordinates;
  moonAzAlt: LocalHorizontalCoordinates;
  sunSemidiameter: Degrees;
  moonSemidiameter: Degrees;
  moonDistance: number; // in kilometres
  P: Degrees; // position angle of a point of contact, measured eastwards from north point of the solar limb
  C: Degrees; // parallactic angle,
  V: Degrees; // position angle of a point of contact, measured eastwards from the vertex of the solar limb (where the vertex point of the solar limb lies on a great circle arc drawn from the zenith to the center of the solar disk - i.e. the "top" of the sun for the viewer)
}
```

{% endcode %}


# Eclipse Paths

Eclipse paths suitable for use on digital maps

{% hint style="info" %}
This API is available on the **Pro** plan or higher
{% endhint %}

{% hint style="warning" %}
Please note that solar eclipse path functionality is currently in **beta**. Please read Known Issues prior to use. These affect some paths which cross extreme latitudes and/or the anti-meridian.
{% endhint %}

The `solar-eclipse/path` end point returns [GeoJSON](https://geojson.org) representing the path of a solar eclipse. This data is suitable for display on digital maps or to derive your own geographic representations.

GeoJSON is a simple data format, somewhat similar to KML, used to represent geographic data structures. It is widely supported by map SDKs, including Leaflet and Google Maps.

### Request format

Given the midnight UTC on the date of the eclipse, converted to a Julian Day, the request is made as shown:

{% code overflow="wrap" lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/solar-eclipse/path/[JULIAN_DAY]",
	"params": {
		"apiKey": "[YOUR_API_KEY]",
		["spacingFactor": "[SPACING_FACTOR]",]
		["paths": "[PATH_OPTIONS]",]
		["eqm": "[LINES_OF_EQUAL_MAG",]
		["minAlt": "[MIN_SUN_ALT]",]
		["poly": "[POLY_OPTIONS]"]
	},
	"headers": {
		"Accept-Encoding": "deflate, gzip, br"
	}
})
```

{% endcode %}

{% code overflow="wrap" lineNumbers="true" %}

```bash
curl "https://api.radiantdrift.com/solar-eclipse/path/2460408.5?apiKey=[YOUR_API_KEY][&spacingFactor=[SPACING_FACTOR][&paths=[PATH_OPTIONS]][&eqm=[LINES_OF_EQUAL_MAG]][&minAlt=[MIN_SUN_ALT]][&poly=[POLY_OPTIONS]]" \
     -H 'Accept-Encoding: deflate, gzip, br'
```

{% endcode %}

All arguments are optional, with the exception of `JULIAN_DAY(`plus a valid Authorization method).

#### Request options

<table><thead><tr><th width="229">Parameter</th><th width="135">Default value</th><th>Description</th></tr></thead><tbody><tr><td><code>JULIAN_DAY</code></td><td>None</td><td><strong>Required</strong>. Midnight UTC of the date of the eclipse, expressed as a Julian Day.</td></tr><tr><td><code>SPACING_FACTOR</code></td><td>1</td><td><em>Optional</em>. Controls the  longitudinal spacing of path points. Max = 40. For example, SPACING_FACTOR=10 results in points spaced every 0.1°. 1 or even values are recommended.</td></tr><tr><td><code>PATH_OPTIONS</code></td><td><code>c</code></td><td><p><em>Optional</em>. A comma separated list of eclipse path line types. Supported values are:</p><ul><li><code>c</code>: central path</li><li><code>tn</code>: northern limit of total eclipse</li><li><code>ts</code>: southern limit of total eclipse</li><li><code>pn</code>: northern limit of partial eclipse</li><li><code>ps</code>: southern limit of partial eclipse</li><li><code>eqn</code>: northern lines of equal magnitude</li><li><code>eqs</code>: southern lines of equal magnitude</li></ul><p>e.g. <code>c,tn,ts,pn,ps</code>denotes the central path, northern limit of totality, southern limit of totality, northern limit of partial eclipse, southern limit of partial eclipse.</p></td></tr><tr><td><code>LINES_OF_EQUAL_MAG</code></td><td>0</td><td><em>Optional</em>. If <code>PATH_OPTIONS</code> includes <code>eqn</code> and/or <code>eqs</code> this value controls how many lines of equal magnitude are calculated. For example, <code>PATH_OPTIONS='eqn'</code> and <code>LINES_OF_EQUAL_MAG=1</code>, the returned path will return the northern limit of equal magnitude, for mag = 0.5.</td></tr><tr><td><code>MIN_SUN_ALT</code></td><td>0°</td><td><p><em>Optional</em>. The minimum true altitude of the Sun relative to the horizon for which path points will be included. The standard is zero degrees, but it may be advantageous to use a small negative value, particularly with lower <code>SPACING_FACTOR</code> values.<br><br>If the observer is high above the surrounding terrain (e.g. in an aircraft) such that there is a positive <a href="https://aty.sdsu.edu/explain/atmos_refr/dip.html">dip of the horizon</a>, a negative value may be used to extend the eclipse path for observations near sunrise or sunset, adjusted for elevation above the horizon.</p><p></p><p>Note: results may be unpredictable due to lack of convergence of the underlying interpolation logic.</p></td></tr><tr><td><code>POLY_OPTIONS</code></td><td>None</td><td><em>Optional.</em> A comma-separated list of three  <code>PATH_OPTION</code> values representing the northern, central and southern limits of a polygon to be returned in the GeoJSON output. Typical usage is to show the area of the path of totality/annularity, e.g. <code>tn,c,ts</code>. The end points of the second (central) path are used together with the north/south limits to determine the bounds of the calculated polygon</td></tr></tbody></table>

### Example request

The following request generates GeoJSON for the path of the Apr 20 2023, including the central path, limits of totality, limits of partial eclipse, and lines of equal eclipse magnitude (for mag=0.2, 0.4, 0.6, 0.8):

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/solar-eclipse/path/2460054.5?spacingFactor=10&paths=c,tn,ts,pn,ps,eqn,eqs&eqm=4&minAlt=-0.27&poly=tn,c,ts
```

{% endcode %}

When displayed on a map the output appears as shown:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FV4tMXeGg6WbjE6AModJp%2Ftse2023-geojson.jpg?alt=media&amp;token=6850aafe-0d7f-4b7c-86d2-1b25aef6bae7" alt=""><figcaption><p>The Total Eclipse of Apr 20 2023, displayed using <a href="https://geojson.io/#map=2.5/-7.49/128.63">geojson.io</a></p></figcaption></figure>

GeoJSON can generally be styled as desired by setting properties either directly in tools such as geojson.io, or using the styling capabilities of mapping SDKs. For example, this screenshot shows a close up of the path of totality as it crosses Exmouth, Western Australia, with the central path shown in green and the polygon representing the path of totality in pink:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FuIT07OwlrgNwtgLDh1RB%2Ftse2023-exmouth.jpg?alt=media&amp;token=54b08c8e-e9c0-4c3d-b1c0-2e3ce5c0935c" alt=""><figcaption><p>Path of totality corssing the Exmouth peninsula in Western Australia. April 20 2023.</p></figcaption></figure>

### Known Issues

{% hint style="info" %}
There are **no known issues** affecting the central path and path of totality for the upcoming Oct 14 2023 and Apr 8 2024 eclipses.
{% endhint %}

Known issues for eclipse paths include:

* Northern or southern limits of partial eclipses, or lines of equal magnitude may be incomplete at extreme latitudes
* Eclipses where one or more lines cross the anti-meridian may exhibit inconsistent or incorrect anti-meridian crossing behavior
* Rarely, an eclipse path may include one or more 'rogue' points, arising from two sources:
  * Bad results of mathematical iteration (i.e. the underlying algorithm converges to an incorrect value under rare conditions) - these typically show up as single stray points that appear as a discontinuity in latitude
  * Zig-zagging due to incorrect merging of separate path segments between moderate and high latitudes
* Straight line segments, due to failure of the underlying algorithm to converge as expected. For example north of Siberia for the Aug 12 2026 eclipse.

This endpoint remains in beta while we work to resolve these issues. If you run into anything not mentioned above, please [let us know](mailto:support@radiantdrift.com).


# Five Millennium Canon of Solar Eclipses

Key data from NASA's solar eclipse catalog queryable as JSON

NASA's Five Millennium Canon of Solar Eclipses provides details of all solar eclipses occurring over the period -1999 to +3000 (2000 BCE to 3000 CE). This public domain data is available at [5MCSE](https://eclipse.gsfc.nasa.gov/SEpubs/5MCSE.html).

An extract of this data - specifically the summary data for each solar eclipse - is available via a web service.

Acknowledgement:&#x20;

{% hint style="info" %}

* Eclipse Predictions by Fred Espenak, NASA's GSFC, [NASA/Goddard Space Flight Center](https://support.photoephemeris.com/hc/en-us/articles/eclipse.gsfc.nasa.gov)
  {% endhint %}

### Request format

Request eclipses between a start and end year as follows:

{% tabs %}
{% tab title="JavaScript" %}
{% code overflow="wrap" lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/solar-eclipse/catalog/[YEAR_FROM]/[YEAR_TO]",
	"params": {
		"apiKey": [YOUR_API_KEY],
		["saros": [SAROS_CYCLE],]
		["primaryType": [ECLIPSE_TYPE]]
	},
	"headers": {
		"Accept-Encoding": "deflate, gzip, br",
		"Cache-Control": "max-age=86400"
	}
})
```

{% endcode %}
{% endtab %}

{% tab title="cURL" %}
{% code overflow="wrap" lineNumbers="true" %}

```bash
curl "https://api.radiantdrift.com/solar-eclipse/catalog/1000/2500?apiKey=[YOUR_API_KEY][&saros=[SAROS_CYCLE]][&primaryType=[ECLIPSE_TYPE]]" \
     -H 'Accept-Encoding: deflate, gzip, br' \
     -H 'Cache-Control: max-age=86400'
```

{% endcode %}
{% endtab %}
{% endtabs %}

You can optionally specify a [Saros cycle](https://eclipse.gsfc.nasa.gov/SEsaros/SEsaroscat.html) number and/or an eclipse type, where valid eclipse types are:

* `P` Partial Eclipse
* `A` Annular Eclipse
* `T` Total Eclipse
* `H` Hybrid or Annular/Total Eclipse

### Example

The following request returns the Hybrid eclipses in Saros cycle 137 between the years 1000 and 2500:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/solar-eclipse/catalog/1000/2500?saros=137&primaryType=H
```

{% endcode %}

The expected response is as follows (abbreviated for length):

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "query": {
    "name": "solar-eclipse/catalog/1000/2500",
    "yearFrom": 1000,
    "yearTo": 2500,
    "credit": "Eclipse Predictions by Fred Espenak, NASA's GSFC",
    "eclipseType": "H",
    "saros": "137"
  },
  "response": [
    {
      "catalog": 8821,
      "year": 1713,
      "month": "Dec",
      "day": 17,
      "greatestTD": 0.669675926,
      "deltaT": 9,
      "lunation": -3538,
      "saros": 137,
      "eclipseType": "H",
      "qle": "p-",
      "gamma": 0.7249,
      "mag": 1.0094,
      "sLat": "23N",
      "sLng": "65W",
      "sunAlt": 43,
      "pathWidthKM": "47",
      "sCentralDuration": "00m56s",
      "lat": 23,
      "lng": -65,
      "centraDurationSec": 56,
      "isoDate": "1713-12-17T00:00:00Z",
      "eclipseTypeQualifier": null,
      "eclipseTypePrimary": "H",
      "countryISO": null,
      "mrgID": 1912,
      "tzID": "Etc/GMT+4"
    },
    {
      "catalog": 8867,
      "year": 1731,
      "month": "Dec",
      "day": 29,
      "greatestTD": 0.03255787,
      "deltaT": 11,
      "lunation": -3315,
      "saros": 137,
      "eclipseType": "H",
...
  ]
}
```

{% endcode %}

In this case, the array included in the `response` property conforms to the following Typescript type:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
export type FiveMCSERecord = {
  catalog: number;
  year: number;
  month: string;
  day: number;
  greatestTD: number;
  deltaT: number;
  lunation: number;
  saros: number;
  eclipseType: string;
  qle: string;
  gamma: number;
  mag: number;
  sLat: string;
  sLng: string;
  sunAlt: number;
  pathWidthKM: string | null;
  sCentralDuration: string | null;
  lat: number;
  lng: number;
  centraDurationSec: number;
  isoDate: string;
  eclipseTypeQualifier: string | null;
  eclipseTypePrimary: string;
  countryISO: string | null;
  mrgID: number | null;
  tzID: string;
}
```

{% endcode %}

### Fields

Except as noted below, the fields returned in the response correspond directly to the source NASA data, except that field names are camel-cased. Please refer to the [Key to Catalog of Solar Eclipses](https://eclipse.gsfc.nasa.gov/SEcat5/SEcatkey.html) for details.

| Field                  | Type           | Comments                                                                                                                                                                                                                                                                                                                                                    |
| ---------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sLat`                 | string         | NASA's `Lat.` field in text form                                                                                                                                                                                                                                                                                                                            |
| `sLng`                 | string         | NASA's `Long.` field in text form                                                                                                                                                                                                                                                                                                                           |
| `sCentralDuration`     | string         | NASA's `Central Dur.` field in text form                                                                                                                                                                                                                                                                                                                    |
| `lat`                  | number         | Latitude of greatest eclipse in degrees, positive north, to nearest whole degree                                                                                                                                                                                                                                                                            |
| `lng`                  | number         | Longitude of greatest eclipse in degrees, positive east, to nearest whole degree                                                                                                                                                                                                                                                                            |
| `centraDurationSec`    | number         | Duration of totality or annularity at location of greatest eclipse, in seconds                                                                                                                                                                                                                                                                              |
| `isoDate`              | string         | Midnight of date of eclipse in ISO Date format. Gregorian Calendar is used for dates after 1582 Oct 15. Julian Calendar is used for dates before 1582 Oct 04.                                                                                                                                                                                               |
| `eclipseTypeQualifier` | string \| null | The second character of NASA's `Ecl. Type` field.                                                                                                                                                                                                                                                                                                           |
| `eclipseTypePrimary`   | string         | The first character of NASA's `Ecl. Type` field. These are broken out separately for indexing and data querying efficiency reasons.                                                                                                                                                                                                                         |
| `countryISO`           | string \| null | 2-letter ISO country code corresponding the modern day country at the lat/lng of the point of greatest eclipse. Null if point does not lie within a country.                                                                                                                                                                                                |
| `mrgID`                | number \| null | <p><a href="https://www.marineregions.org">Marine Resources</a> numeric ID corresponding to the sea or ocean at the lat/lng of the point of greatest eclipse. Null if the point lies over land.<br><br>This field and the <code>countryISO</code> field are useful for general characterization of the location of greatest eclipse in user interfaces.</p> |
| `tzID`                 | string         | The modern Time Zone ID corresponding to the point of greatest eclipse.                                                                                                                                                                                                                                                                                     |


# The Moon

Lunar libration and lunar limb profiles

You can calculate the position of the Moon in a variety of common coordinate systems using the [Body Position](/body-position) end point and its rise, transit, and setting time using the [Rise, Transit, Set](/rise-transit-set-times) end point.

Additionally, the Body Position end point can optionally return other Moon specific information, such as the illuminated fraction of the Moon's disc, waxing/waning state, and geocentric distance.

There are however some more specialized end points available which relate solely to the Moon: libration and the lunar limb profile. API end points are available to calculate both geocentric and topocentric lunar libration. For use specifically with solar eclipse calculations, a limited set of lunar limb profile data is available.


# Lunar Libration

Geocentric and Topocentric libration

Use the `lunar-libration` end point to obtain either geocentric or topocentric [lunar libration](https://en.wikipedia.org/wiki/Libration) values.&#x20;

### Request format

The `lunar-libration`end point requires a date, and optionally accepts an observer latitude and longitude:

{% code overflow="wrap" lineNumbers="true" %}

```javascript
axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/lunar-libration/[DATE_TIME]",
	"params": {
		["obs": "[LAT,LNG]"]
	}
})
```

{% endcode %}

{% code overflow="wrap" lineNumbers="true" %}

```bash
curl "https://api.radiantdrift.com/lunar-libration/[DATE_TIME][?obs=[LAT,LNG]]
```

{% endcode %}

### Example 1: without observer location

The following request returns the lunar libration for March 20 2015 at 10:11:57.7 UTC:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/lunar-libration/2015-03-20T10:11:57.7Z
```

{% endcode %}

The expected response is:

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "query": {
    "name": "lunar-libration",
    "date": "2015-03-20T10:11:57.700Z"
  },
  "response": {
    "physicalObservations": {
      "physicalLibration": {
        "lat": 0.03829045,
        "lng": -0.03277045
      },
      "opticalLibration": {
        "lat": -1.22533368,
        "lng": 1.2851531
      },
      "totalLibration": {
        "lat": -1.18704323,
        "lng": 1.25238265
      },
      "selenographicPosition": {
        "lat": 0.26167655,
        "lng": 180.87616357
      },
      "selenographicColongitude": 269.12383643,
      "positionAngle": 335.07160049
    }
  }
}
```

{% endcode %}

### Example 2: with observer location

If the observer location is given, the end point additionally calculates the total topocentric lunar libration. For example, in Svalbard in March 2015 for the total solar eclipse:

{% code overflow="wrap" %}

```
GET https://api.radiantdrift.com/lunar-libration/2015-03-20T10:11:57.7Z?obs=78.222133,15.650467
```

{% endcode %}

Expected response:

```
{
  "query": {
    "name": "lunar-libration",
    "date": "2015-03-20T10:11:57.700Z",
    "observer": {
      "lat": 78.222133,
      "lng": 15.650467
    }
  },
  "response": {
    "physicalObservations": {
      "physicalLibration": {
        "lat": 0.03829045,
        "lng": -0.03277045
      },
      "opticalLibration": {
        "lat": -1.22533368,
        "lng": 1.2851531
      },
      "totalLibration": {
        "lat": -1.18704323,
        "lng": 1.25238265
      },
      "selenographicPosition": {
        "lat": 0.26167655,
        "lng": 180.87616357
      },
      "selenographicColongitude": 269.12383643,
      "positionAngle": 335.07160049
    },
    "topocentricLibration": {
      "libration": {
        "lat": -0.25992041,
        "lng": 0.87406513
      },
      "positionAngle": 335.07397418
    }
  }
}
```

The topocentric libration is typically required for the purposes of simulating the appearance of the Moon at a given time/place, and for determining the effect of the lunar limb on solar eclipse circumstances.


# Lunar Limb Profile

Lunar limb profile data for solar eclipse calculations

{% hint style="info" %}
This API is available on the **Pro** plan or higher
{% endhint %}

The `lunar-limb` end point returns a limited set of data related to the lunar limb profile. This is commonly used in making advanced solar eclipse calculations (specifically to find adjusted times and position angles of the second and third contacts), and to aid in simulating the appearance of [Baily's Beads](https://en.wikipedia.org/wiki/Baily%27s_beads).

{% hint style="info" %}
Credit:

The data returned by this API is from data derived from the [Kaguya](https://en.wikipedia.org/wiki/SELENE) mission by **David Herald**. Please review the ReadMe.txt file linked below for additional information.
{% endhint %}

{% file src="/files/TEyRcQ4INbUr9Skvy2Ju" %}
Kaguya for Eclipses ReadMe.txt, courtesy of David Herald.
{% endfile %}

{% hint style="warning" %}
Lunar limb profiles are available only for a limited range of libration values:

* `l`, libration in longitude: +9.0° to -9.0°
* `b`, libration in latitude: +1.6° to -1.6°
* Resolution: 0.2° intervals

These libration values cover the ranges which occur during solar eclipses (when the Moon is always near one of its nodes). The resolution of 0.2° is sufficient for the purposes of establishing the effects of variation in the lunar limb on solar eclipse observations.
{% endhint %}

The API will return JSON data containing limb data for a given lunar libration. The desired lunar libration can be given directly, or alternatively it will be calculated from a given date. Additionally, the data can be requested in SVG form for graphical display, with a desired vertical exaggeration factor.

### Request format

<pre class="language-javascript" data-overflow="wrap" data-line-numbers><code class="lang-javascript">axios({
	"method": "GET",
	"url": "https://api.radiantdrift.com/lunar-limb/[DATE_TIME]",
<strong>	"params": {
</strong>		["obs": "[LAT,LNG]",]
		["l": "[LIBRATION_IN_LNG]",]
		["b": "[LIBRATION_IN_LAT]",]
		["format": [FORMAT],]
		["xf": [EXAGGERATION_FACTOR],]
		["size": [SIZE]]
	}
})
</code></pre>

### Request parameters

<table><thead><tr><th width="245">Parameter</th><th width="149">Default value</th><th>Description</th></tr></thead><tbody><tr><td><code>DATE_TIME</code></td><td>None</td><td><em>Optional</em>. The date/time for which the limb profile is desired. <strong>Required</strong> if <code>LIBRATION_IN_LNG</code> and <code>LIBRATION_IN_LAT</code>are omitted.</td></tr><tr><td><code>LAT,LNG</code></td><td>None</td><td><em>Optional</em>. The observer's latitude and longitude (geodetic). <strong>Required</strong> if <code>LIBRATION_IN_LNG</code> and <code>LIBRATION_IN_LAT</code>are omitted.</td></tr><tr><td><code>LIBRATION_IN_LNG</code>, <code>LIBRATION_IN_LAT</code></td><td>None</td><td><em>Optional.</em> Libration values to be used. Ignored if observer <code>LAT,LNG</code> and <code>DATE_TIME</code> are given. <strong>Required</strong> otherwise. See above note on supported range of values.</td></tr><tr><td><code>FORMAT</code></td><td><code>json</code></td><td><em>Optional</em>. If omitted, API returns a JSON response. Supported values: <code>json</code> (default) or <code>svg</code> (scalable vector graphics).</td></tr><tr><td><code>EXAGGERATION_FACTOR</code></td><td>20</td><td><em>Optional</em>. Ignored unless <code>FORMAT</code> is <code>svg</code>. Applies a vertical exaggeration factor to the lunar limb data when requesting SVG format. Larger values </td></tr><tr><td><code>SIZE</code></td><td>1000</td><td><em>Optional</em>. Ignored unless <code>FORMAT</code> is <code>svg</code>. Sets height and width of returned SVG object. Valid range: 1.0 to 10000.0.</td></tr></tbody></table>

If the observer latitude and longitude are given, the API will calculate the topocentric libration values automatically. If observer location is omitted, you must supply valid values for libration in longitude and latitude within the ranges noted above.

If all cases, the given or inferred libration values are 'snapped' to the closest limb profile data set from the Kaguya/Herald source.

### Example 1: JSON format

This example returns the lunar limb profile for the 2015 total eclipse as observed in Svalbard at the time of greatest eclipse:

{% code overflow="wrap" %}

```
GET 'https://api.radiantdrift.com/lunar-limb/2015-03-20T10:11:57.7Z?obs=78.22213,15.65047
```

{% endcode %}

The (excerpted) response is:

```json
{
  "query": {
    "name": "lunar-limb",
    "date": "2015-03-20T10:11:57.700Z",
    "observer": {
      "lat": 78.22213,
      "lng": 15.65047
    },
    "l": 0.8740651392225147,
    "b": -0.25992041772556207,
    "P": 335.07397418464956,
    "filename": "0.8_-0.2_0.0_359.8_0.2.json"
  },
  "response": {
    "l": 0.8,
    "b": -0.2,
    "aa_from": 0,
    "aa_to": 359.8,
    "deg": 0.2,
    "data": [
      -0.28,
      -0.17,
      -0.21,
      -0.5,
      -0.57,
      -0.52,
      -0.49,
      -0.49,
      -0.12,
      -0.11,
      -0.32,
      -0.19,
      -0.09,
      -0.08,
      -0.09,
      -0.11,
      -0.12,
      -0.17,
      -0.29,
      -0.37,
      -0.3,
      -0.22,
      -0.21,
      -0.26,
      -0.11,
      …
```

The `query` object shows the parameters used to determine what limb profile data is required, including the topocentric libration values (`l` and `b`) and position angle (`P`) calculated for the given date and observer location.

The `response` object contains the rounded libration values used to select from the Kaguya/Herald dataset. `aa_from` and `aa_to` indicate the range of limb profile data point radial angles in degrees given in `data`. `deg` shows the resolution (always 0.2°).

The `data` property contains the array of raw limb offsets in arc seconds. E.g. the first value -0.28″ indicates that at the angle of 0° as measured from the center of mass of the Moon, the angular semi-diameter is reduced from the mean semi-diameter by -0.28″.&#x20;

{% hint style="warning" %}
Be sure to consult the ReadMe.txt file linked above to understand how to relate these values to the reference values used in preparation of the dataset.
{% endhint %}

### Example 2: SVG format

This example returns the lunar limb profile for the 2015 total eclipse as observed in Svalbard at the time of greatest eclipse in SVG format, with a vertical exaggeration factor of 15 and a size of 800:

{% code overflow="wrap" %}

```
GET 'https://api.radiantdrift.com/lunar-limb/2015-03-20T10:11:57.7Z?obs=78.22213,15.65047&format=svg&xf=15&size=800
```

{% endcode %}

The raw response is as follows (excerpt shown):

{% code overflow="wrap" %}

```xml
<svg height="800" width="800"><polygon points="483.90997,219.44624 483.42721,218.83305 482.74090,218.65999 481.72314,219.22229 480.99957,219.14363 480.43300,218.71497 479.83854,218.34697 479.20396,218.06939 479.03969,216.70113 478.41201,216.39676 477.50750,216.74632 477.02890,216.09118 476.50970,215.52629 475.87752,215.23059 475.21998,214.99665 474.54971,214.79489 473.89087,214.56568 473.18412,214.45850 472.39563,214.56374 471.65515,214.55220 471.08780,214.09289 470.52950,213.60520 469.88971,213.33001 469.18182,213.23801 468.69550,212.54462 468.20517,211.85235 467.67829,211.25207 467.02977,210.98666 466.39087,210.69312 465.61373,210.79683 464.97376,210.50810 464.55976,209.55131 463.89458,2…
```

{% endcode %}

The points returned at scaled based on the size parameter value and the position angle rotation (`P` in the JSON format example above) is already applied.

When displayed in graphical form, this SVG object appears like this - it has no styling included:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FJn3xLssp3gohCAdEc4x3%2Fimage.png?alt=media&amp;token=b02cf24f-9f12-438e-b417-bbf4f2829b5f" alt="Image of lunar limb SVG"><figcaption><p>SVG showing lunar limb with 15x vertical exaggeration factor</p></figcaption></figure>

The SVG object can be styled for display in your own app or website using tools such as [CSS](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/SVG_and_CSS) or other graphical editing tools. For example, with green border and light grey fill:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FGOSKUOtciM2kLyS29Ov2%2Flunar-limb-example-styled.svg?alt=media&amp;token=8a2b5f70-5de4-4803-8356-24099f6aee2e" alt="Styled SVG showing lunar limb"><figcaption><p>SVG with styling applied</p></figcaption></figure>

### Example 3: manually specified libration values

{% code overflow="wrap" %}

```
GET 'https://api.radiantdrift.com/lunar-limb/?l=7.2&b=-1.6&format=svg&xf=30&size=1000
```

{% endcode %}

The resulting SVG appears as shown:

<figure><img src="https://1001599322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbA8iUHgJsg3uY5Dn2s3E%2Fuploads%2FTkz3fKCIcV4C3iftHVNW%2Fimage.png?alt=media&amp;token=a0a43c07-65c3-4051-9cef-71e972ec77b8" alt="SVG of lunar limb with 30x vertical exaggeration"><figcaption><p>SVG for arbitrary libration values, 30x vertical exaggeration</p></figcaption></figure>


# Geospatial

Details of our geospatial API end points

We have a number of geospatial API end points available that are useful in conjunction with the astronomical APIs.

* [Geodesic](/geospatial/geodesic): calculates points along a great circle
* [Elevation](/geospatial/elevation): looks up elevation above sea level for one or more lat/lng coordinates


# Geodesic

Calculate points along an arbitrary great circle

{% hint style="info" %}
This API is available on the **Pro** plan or higher
{% endhint %}

The `/geodesic`end point calculates and returns points along the great circle connecting two points, start and end.

Two methods are available:

* `midpoint`: the points are calculated recursively, by finding the mid-point of the current coordinate pair, beginning with start and end, repeating the great circle calculation and then testing the difference in bearing. This is repeated until the difference is less than the specified `tolerance`, in degrees. A lower tolerance results in a greater number of points
* `uniform`: the distance is calculated from start to end and then divided to give the specific number of segments. A great circle calculation is performed from the start point along the initial bearing (also known as forward azimuth) to the end point for the calculated distance, and then repeated as necessary for each segment

The end point can return either an array of points or a valid geojson object. You may specify the desired ellipsoid to be used for the calculations

### Elevation

You can request that the API return the elevation at each calculated point along the geodesic using the  `with-el` parameter. For details of the elevation data source, see the [Elevation](/geospatial/elevation) end point documentation.

{% hint style="warning" %}
Requesting elevation values increases both the response time and call cost.
{% endhint %}

{% openapi src="<https://api.radiantdrift.com/openapi/0.18.4.json>" path="/geodesic/{start}/{end}" method="get" %}
<https://api.radiantdrift.com/openapi/0.18.4.json>
{% endopenapi %}


# Elevation

Determine the elevation above sea level for given coordinates

{% hint style="info" %}
This API is available on the **Pro** plan or higher
{% endhint %}

Query the elevation above sea level for a given coordinate or coordinates with the `/elevation` end point. Post an array of one or more lat/lng coordinates to obtain the elevation above sea level at the given point.

The end point can return three format response types, based on the `format` query parameter value:

* geojson: a valid GeoJSON document
* array: an array of elevations not including the corresponding lat/lng coordinate (array order is preserved in the response)
* topocentric-array: an array of \[lat, lng, elevation] values

### Data Source

Elevation data is obtained from the public [Terrain Tiles](https://registry.opendata.aws/terrain-tiles/) data set.&#x20;

{% openapi src="<https://api.radiantdrift.com/openapi/0.18.4.json>" path="/elevation" method="post" %}
<https://api.radiantdrift.com/openapi/0.18.4.json>
{% endopenapi %}

### Attribution

Elevation data courtesy of:

* ArcticDEM terrain data DEM(s) were created from DigitalGlobe, Inc., imagery and funded under National Science Foundation awards 1043681, 1559691, and 1542736;
* Australia terrain data © Commonwealth of Australia (Geoscience Australia) 2017;
* Austria terrain data © offene Daten Österreichs – Digitales Geländemodell (DGM) Österreich;
* Canada terrain data contains information licensed under the Open Government Licence – Canada;
* Europe terrain data produced using Copernicus data and information funded by the European Union - EU-DEM layers;
* Global ETOPO1 terrain data U.S. National Oceanic and Atmospheric Administration
* Mexico terrain data source: INEGI, Continental relief, 2016;
* New Zealand terrain data Copyright 2011 Crown copyright (c) Land Information New Zealand and the New Zealand Government (All rights reserved);
* Norway terrain data © Kartverket;
* United Kingdom terrain data © Environment Agency copyright and/or database right 2015. All rights reserved;
* United States 3DEP (formerly NED) and global GMTED2010 and SRTM terrain data courtesy of the U.S. Geological Survey.


# Reference

Under construction


# Definitions

Definitions of astronomical values returned in response fields

Response fields are defined here.

| Parameter                      | Units               | Description                                                                                                                                                                                                      |
| ------------------------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apparentCoordinates`          | degrees             | [equatorial](https://en.wikipedia.org/wiki/Equatorial_coordinate_system) right ascension (`ra`, α) and declination (`decl`, δ)                                                                                   |
| `apparentLongitude`            | degrees             | apparent geocentric [ecliptic](https://en.wikipedia.org/wiki/Ecliptic_coordinate_system) longitude (`λ`)                                                                                                         |
| `argOfLatitude`                | degrees             | Moon's argument of latitude: the mean distance of the Moon from its ascending node                                                                                                                               |
| `dateTD`                       | none                | Time stamp in dynamical time, i.e. adjusted for `deltaT`                                                                                                                                                         |
| `eclipticCoordinates`          | degrees             | geocentric [ecliptic](https://en.wikipedia.org/wiki/Ecliptic_coordinate_system) longitude (`λ`) and latitude (`β`) of the body referenced to the true equinox of date                                            |
| `equatorialHorizontalParallax` | degrees             | parallax that varies with the rotation of the Earth or with a difference in location on the Earth; typically only [significant for the Moon](https://en.wikipedia.org/wiki/Parallax_in_astronomy#Lunar_parallax) |
| `jde`                          | none                | Julian Ephemeris Day, i.e. Julian Day adjusted for `deltaT` expressed as fractional day                                                                                                                          |
| `meanAnomalyMoon`              | degrees             | [mean anomaly](https://en.wikipedia.org/wiki/Mean_anomaly) of the Moon                                                                                                                                           |
| `meanAnomalySun`               | degrees             | [mean anomaly](https://en.wikipedia.org/wiki/Mean_anomaly) of the Sun                                                                                                                                            |
| `meanElongation`               | degrees             | The Moon's [instantaneous angular distance](https://en.wikipedia.org/wiki/Orbit_of_the_Moon#Elongation) east of the Sun                                                                                          |
| `nutationInLongitude`          | degrees             | [nutation](https://en.wikipedia.org/wiki/Astronomical_nutation) in ecliptic longitude                                                                                                                            |
| `nutationInObliquity`          | degrees             | [nutation](https://en.wikipedia.org/wiki/Astronomical_nutation) in obliquity of the ecliptic                                                                                                                     |
| `obliquityOfEcliptic`          | degrees             | [obliquity of the ecliptic](https://en.wikipedia.org/wiki/Ecliptic#Obliquity_of_the_ecliptic): the inclination of Earth's equator with respect to the [ecliptic](https://en.wikipedia.org/wiki/Ecliptic)         |
| `radiusVector`                 | au (sun), km (moon) | distance from body to Earth, measured between centers                                                                                                                                                            |


# Errors

Under construction


