You have hit the N2YO hourly cap

N2YO caps each endpoint separately, per hour: around 1,000 calls for element sets or positions, and 100 for pass predictions. Pass prediction is the one people hit, because it is the one worth calling. There is no published price list to upgrade against, only an invitation to contact them if you need more traffic, so for most projects the answer is to call it less, by moving the parts of the job that are not really pass prediction somewhere else.

The limits

  • Roughly 1,000 calls an hour for element sets, and the same for positions.
  • Roughly 100 calls an hour for visual pass and radio pass predictions, and the same for the "above" endpoint that lists what is overhead right now.
  • The caps are per endpoint, not shared, so exhausting passes does not stop you fetching elements.
  • A free account and a licence key are required for all of them.
  • There is no published price list. N2YO asks you to contact them if you need more traffic, and asks you not to spread the load over multiple licence keys, which is asking to lose the ones you have.

Source: N2YO API documentation

Why 100 an hour runs out so fast

A pass prediction is per satellite and per observer. One user asking "what is visible from my garden tonight" across a modest watchlist of forty satellites is forty calls. Three users doing it in the same hour is over the cap, and you have not launched yet.

The arithmetic does not improve with caching alone, because the answer depends on the observer’s location. What does improve it is noticing that most of the work is not pass prediction at all.

Split the job in two

Almost every application that hits this limit is doing two different things through one endpoint. The first is catalog work: which satellites exist, what they are called, who runs them, which ones carry a transmitter, which are still active. That work is identical for every user and every location, and it does not need a pass-prediction call.

The second is the genuinely per-observer part: given these elements and this location, when does it come over. That is the part worth spending your hundred calls on, and it is also the part you can compute yourself from element sets with an SGP4 library, which is what N2YO is doing on your behalf.

  • Take the catalog and the element sets from a source with a higher limit, and cache them: upstream regenerates them every 2 hours, not per request.
  • Filter down to the handful of objects a given user could actually see before you ask anything per-observer.
  • Compute passes locally with an SGP4 implementation if the volume justifies it. python-sgp4 and satellite.js both take the element sets directly.
  • Reserve the N2YO calls for what only N2YO gives you.

What the catalog side looks like here

Reads need no key at all, at 50 requests a day per IP address, and a free key raises that to 1,000 requests a day across every endpoint, with 429 and a retry hint when you exceed it. There is a paid tier if the volume grows, which mainly matters because it means the free tier is not a bait: it is the small end of a product, not a trial that will be withdrawn.

When you should use N2YO instead of us

When you want to know where a satellite is right now, or when it will pass over a location. This catalog describes objects; it does not predict passes, and N2YO’s position and visual-pass endpoints do that job directly and well. If pass prediction is the product, N2YO is the right dependency and the hourly cap is the price. Use this catalog for the part underneath it: bulk access, operator attribution for every operator with a known payload in orbit, and a record of which upstream source each field came from.

Source: N2YO API documentation

Try this catalog in thirty seconds

curl
# Reads work with no key at 50 requests a day per IP. A free key raises it to 1,000.
curl -s 'https://www.orbitalwiki.com/api/v1/satellites/25544'

# Current orbital elements, as CCSDS OMM JSON
curl -s 'https://www.orbitalwiki.com/api/v1/satellites/25544/omm'

# Or as a two-line element set
curl -s 'https://www.orbitalwiki.com/api/v1/satellites/25544/tle?format=tle'
Python
import os
import requests

BASE = "https://www.orbitalwiki.com/api/v1"
# Optional. Without it you get 50 requests a day per IP; with it, 1,000 a day.
KEY = os.environ.get("ORBITALWIKI_API_KEY")
headers = {"Authorization": f"Bearer {KEY}"} if KEY else {}

r = requests.get(f"{BASE}/satellites", params={"limit": 100}, headers=headers, timeout=30)
r.raise_for_status()
page = r.json()

print(page["meta"]["total"], "objects in the catalog")
for sat in page["data"][:5]:
    print(sat["norad_cat_id"], sat["name"], sat["operator"])

# Paginate with the cursor the response hands you, rather than guessing offsets.
# The whole catalog is far more than 50 requests, so a keyless run meets its
# limit part way through. Check every response, and stop when told to.
while page["meta"]["has_more"]:
    r = requests.get(page["meta"]["next"], headers=headers, timeout=30)
    if r.status_code == 429:
        print("rate limited, retry in", r.headers.get("Retry-After"), "seconds")
        break
    r.raise_for_status()
    page = r.json()

Reads work without a key at 50 requests a day per IP address. A free key raises that to 1,000 requests a day, and going over returns 429 with a retry hint.

Checked against each provider’s own documentation on 2026-08-05. If a figure here is out of date, tell us at hello@orbitalwiki.com and we will correct it.