API Errors
Every error the CycleCalcs v2 API can return, one entry per code. This page is what a client's type URL points at: the same catalog is published as data at /api/errors.json, and the two are generated from the same source, so they cannot disagree. 104 codes are registered; 87 of them can be returned by a live endpoint today, and the other 17 are not returned by any shipped endpoint (each of those says why on its own entry).
On this page
How errors are shaped
Every v2 error is application/problem+json (RFC 9457). The five standard members plus the CycleCalcs extension members appear in this fixed order:
| Member | Meaning |
|---|---|
type | Absolute URI, always this page: https://www.cyclecalcs.com/api/errors.html#<slug>. Never about:blank. |
title | Short human summary of the problem type. Identical for every occurrence of a code. |
status | The real HTTP status code, repeated in the body. |
detail | Human explanation of this occurrence. May quote the offending value. |
code | Stable SCREAMING_SNAKE_CASE identifier. This is the field a client switches on. |
parameter | The query parameter at fault, or null when the error is not tied to one. |
hint | One plain sentence on what to do. The default hint for each code is on its entry below; a live response may sharpen it with the exact values involved. |
example | A complete corrected request URL, when one is available, or null. |
supported | The full accepted list, for an enumeration failure. null for a numeric-range failure, since a range is not an enumeration. |
request_id | 16 lowercase hex characters, or null on every cacheable class (a cached body cannot carry one caller's identifier to every later caller). |
error_chain | null unless one input triggered a chain of causes. |
docs | The API reference: https://www.cyclecalcs.com/api/reference.html. |
A handful of codes carry one more, structured field after docs, because a plain sentence cannot hold the data a client actually needs to branch on:
| Field | Shape |
|---|---|
cap | { requested, minimum, maximum, unit }. minimum is omitted where the floor is zero or not meaningful. |
supported | array: the full list of values the named parameter accepts. |
unavailable | array of { name, reason }, one entry per target the API recognises the name of but will not compute. |
gap | { gap_start_local, gap_end_local, gap_seconds, instant_before_gap, instant_after_gap }, describing the spring-forward gap that swallowed the requested local time. |
candidates | array of { utc, utc_offset_seconds, utc_offset_iso, selected }, one entry per instant a repeated local time could mean. |
Each entry below names the parameter it points at (when it points at one) and which of these it can carry. Rate limiting, request caps and service-level status are covered on API Status and Limits, not repeated here; RATE_LIMITED and the budget codes below link there.
Dates and time zones
400 · BAD_DATE
The date could not be parsed
Use ISO 8601, for example 2026-08-12 or 2026-08-12T21:00:00Z
Parameter: at.
400 · DATE_OUT_OF_RANGE
The date is outside the supported range
Choose a date from 1700 to 2200; the vendored ephemeris is not reliable outside it
Parameter: at.
400 · BAD_TIMEZONE
The time zone was not recognized
Use an IANA zone name such as Europe/London; see the list in the reference
Parameter: tz.
400 · BAD_TIME_FORMAT
The time format was not recognized
Use time_format=iso or time_format=unix
Parameter: time_format. Also carries: supported.
400 · TIMEZONE_AUTO_UNSUPPORTED
The time zone cannot be inferred
Send an IANA zone name, or a place, whose stored zone becomes the default
Parameter: tz.
400 · NONEXISTENT_LOCAL_TIME
That local time did not exist
Choose a time outside the gap, or pass the instant in UTC with a Z suffix
Parameter: at. Also carries: gap.
409 · AMBIGUOUS_LOCAL_TIME
That local time occurred twice
Add ambiguous=first or ambiguous=last to choose an occurrence, or pass the instant in UTC
Parameter: at. Also carries: candidates.
400 · TIME_REQUIRED
This endpoint needs a time
Send at as an ISO 8601 date or date-time, for example at=2026-08-12T21:00:00Z
Parameter: at.
Not returned by any shipped endpoint: A route that takes the at parameter treats a request without it as a request for the current moment, so none refuses a request for leaving at out.
400 · CONFLICTING_TIME_INPUTS
Two time expressions conflict
Send exactly one time expression
Parameter: the second time parameter seen.
400 · TIMEZONE_REQUIRED
This request needs a time zone
Add tz, or a place whose stored zone supplies the default
Parameter: tz.
Ranges, steps and pagination
400 · INCOMPLETE_RANGE
The range is incomplete
Add start, or drop the range parameters
Parameter: start.
400 · BAD_RANGE
The range is invalid
Give both start and end with end strictly after start
Parameter: end.
400 · RANGE_TOO_LARGE
The range exceeds the limit for this endpoint
Read cap: its unit says what is capped and bound_by why. A days cap (a time span or a search window) is met only by a range of at most that many days, however it is sent (with end, or with count= where the endpoint takes it); a wider step never shortens a span. A rows cap can also be met by a wider step or by count= for the first rows, an events cap by a shorter window, a response_size bound by a shorter range, or by format=csv where the hint names it, and a list cap by fewer instants in at. Paging with limit and cursor never raises a cap. example, when present, is a legal first request. When bound_by is tier_range_cap and a paid plan serves the request unchanged, the hint names the smallest such plan
Parameter: end. Also carries: cap.
See also: API Status and Limits.
400 · BAD_STEP
The step could not be parsed
Write a number followed by min, h, d, w, mo or y. Endpoints narrow that grammar (a per-day endpoint takes whole days only), so a refusal names durations the endpoint it came from will accept
Parameter: step. Also carries: supported.
400 · BAD_COUNT
Count is out of range
Use a whole number inside the cap named in cap
Parameter: count. Also carries: cap.
400 · BAD_SEARCH_HORIZON
The search horizon is out of range
Shorten the horizon; the per-endpoint caps are published at /v2/conventions
Parameter: search_horizon. Also carries: cap.
400 · BAD_LIMIT
Limit is out of range
Use a whole number from 1 to the documented maximum
Parameter: limit. Also carries: cap.
400 · BAD_CURSOR
The cursor is not valid
Restart from the first page, or use links.next unchanged
Parameter: cursor.
Location
400 · INCOMPLETE_LOCATION
Latitude and longitude must be given together
Provide both lat and lon, or neither
Parameter: lat.
400 · BAD_LATITUDE
Latitude is not a number from -90 to 90
Use a signed decimal, for example lat=51.5 for north and lat=-51.5 for south. Do not append N or S
Parameter: lat.
400 · BAD_LONGITUDE
Longitude is not a number from -180 to 180
Give decimal degrees from -180 to 180, east positive
Parameter: lon.
400 · AMBIGUOUS_LONGITUDE_FORMAT
The longitude form is ambiguous
Use a signed decimal, east positive. Do not append E or W
Parameter: lon.
400 · BAD_ELEVATION
Elevation is not a number from -500 to 9000
Give metres above mean sea level from -500 to 9000
Parameter: elevation_m. Also carries: cap.
400 · LOCATION_REQUIRED
This endpoint needs a location
Add lat and lon query parameters, in decimal degrees, for example lat=51.5&lon=-0.12.
Parameter: lat.
400 · LATITUDE_AT_POLE
The latitude is exactly at a pole
Move at least 0.1 degrees off the pole
Parameter: lat.
400 · LATITUDE_TOO_EXTREME
The latitude is too close to a pole
Use a latitude below 89.9 degrees in absolute value
Parameter: lat.
400 · LONGITUDE_REQUIRED
This request needs a longitude
Add lon, or a place
Parameter: lon.
Place search
400 · BAD_PLACE
Place name not understood
Use place=<name>, place=<name>,<country>, place=<name>,<state> (such as Manalapan,NJ) or place=id:<place_id>. Search for a place at /v2/places?q=<name>.
Parameter: place.
404 · PLACE_NOT_FOUND
No matching place
Add a country, for example place=Cambridge,GB, search at /v2/places?q=<name> for the current index size and a stable place_id, or send lat and lon.
Parameter: place.
400 · AMBIGUOUS_PLACE
Place name is ambiguous
Re-send with place=id:<place_id>, or add a country, for example place=Cambridge,GB.
Parameter: place. Also carries: supported.
400 · QUERY_TOO_SHORT
Search text too short
Type more of the place name
Parameter: q.
Bodies and targets
400 · UNKNOWN_BODY
That body is not recognized
Use one of the listed bodies; see /v2/enums?set=bodies
Parameter: body. Also carries: supported.
400 · BODY_REQUIRED
This endpoint needs a body
Add body=sun, body=moon, a planet name, or a radec: target. The full list is at /v2/enums?set=bodies
Parameter: body.
400 · BODY_NOT_SUPPORTED_HERE
Body not supported by this endpoint
Use /v2/positions for the Sun, the Moon or Earth
Parameter: body. Also carries: supported.
400 · TOO_MANY_BODIES
Too many bodies requested
Request 20 or fewer bodies, or omit bodies for the default set
Parameter: bodies. Also carries: cap.
400 · BAD_RADEC
The radec target could not be parsed
Write radec:<ra>,<dec> in decimal hours and degrees, J2000
Parameter: body. Also carries: supported.
400 · STAR_SLOT_FAILED
The star slot could not be defined
Check the coordinates are in range and retry
Parameter: body.
503 · STAR_POOL_TIMEOUT
The catalog-object computation queue is busy
Retry in a moment, or query a Solar System body instead
Parameter: none (not tied to a single parameter).
404 · OBJECT_NOT_FOUND
No such catalog object
Check the identifier against the catalog objects a target may name, listed at /v2/enums?set=stars
Parameter: id.
Not returned by any shipped endpoint: The catalog-object routes need a reduced index that no generator has produced.
400 · BODY_NOT_GEOCENTRIC
That body has no geocentric position here
Pick a body from supported
Parameter: body.
Output shape and formatting
400 · BAD_PARAMETER_VALUE
A parameter value was not accepted
Correct the named parameter; the accepted values are listed in supported
Parameter: varies. Also carries: cap, supported.
400 · BAD_RANGE_VALUE
A numeric parameter is out of range
Send a value inside the range named in cap
Parameter: varies.
400 · BAD_FORMAT
That output format is not available here
Use one of the values in supported. Every endpoint lists the formats it serves at /v2, and /v2/enums?set=formats says which formats exist at all
Parameter: format. Also carries: supported.
406 · NOT_ACCEPTABLE
No acceptable representation
Send Accept: application/json or use the format query parameter
Parameter: none (not tied to a single parameter).
400 · BAD_FIELDS
A requested field does not exist
Remove the unknown name; the available fields are listed in supported
Parameter: fields.
400 · BAD_INCLUDE
An include token was not recognized
Use tokens from supported, or omit the parameter for the default set
Parameter: include. Also carries: supported.
400 · BAD_SIZE
The image size is out of range
Choose a size inside the range named in cap
Parameter: size.
Not returned by any shipped endpoint: The rendering surface (format=svg) is specified and not built.
400 · BAD_REFRACTION
The refraction mode was not recognized
Use refraction=normal or refraction=none
Parameter: refraction.
400 · BAD_BOOLEAN
A boolean parameter was not recognized
Send true or false
Parameter: varies. Also carries: supported.
400 · FIELD_NOT_COMPUTED
That field is refused by policy
Remove the field; see meta.not_computed
Parameter: fields.
Request shape and limits
400 · CONFLICTING_PARAMETERS
Two parameters conflict
Remove one of the two parameters named in detail
Parameter: the second parameter seen.
400 · BAD_CLIENT
The client identifier is invalid
Use up to 64 characters of letters, digits, dot, underscore or hyphen
Parameter: client.
400 · BUDGET_EXCEEDED
The request exceeds the computation budget
Split it into smaller ranges. The per-request budget is documented at /v2/conventions, and on /v2/conjunctions the hint states how many days fit at the stride and pairs you sent. The budget is the same on every plan
Parameter: none (not tied to a single parameter). Also carries: cap.
See also: API Status and Limits.
400 · PARAMETER_TOO_LONG
A parameter value is too long
Shorten the value
Parameter: varies.
400 · TOO_MANY_PARAMETERS
Too many distinct parameters
Send fewer parameters
Parameter: none (not tied to a single parameter). Also carries: cap.
See also: API Status and Limits.
414 · URI_TOO_LONG
The request URI is too long
Shorten the query string
Parameter: none (not tied to a single parameter).
400 · INVALID_CHARACTER
A value contains a control character
Remove the control character
Parameter: varies.
400 · HTML_ESCAPED_QUERY
The query string is HTML-escaped
Replace every "&" in the URL with a plain "&" and send it again
Parameter: none (not tied to a single parameter).
503 · COMPUTE_BUDGET_EXCEEDED
The computation budget was exhausted
Retry with a smaller request
Parameter: none (not tied to a single parameter).
See also: API Status and Limits.
413 · RESPONSE_TOO_LARGE
The response exceeds the hard size cap
Narrow the request with fields, verbosity=compact or a smaller range
Parameter: none (not tied to a single parameter).
See also: API Status and Limits.
Sun and twilight
400 · BAD_DEPRESSION
A depression angle is out of range
Give degrees below the horizon from 0 to 30
Parameter: depressions. Also carries: cap.
400 · TOO_MANY_DEPRESSIONS
Too many depression angles
Send 8 or fewer depression angles
Parameter: depressions. Also carries: cap.
Eclipses
400 · BAD_ECLIPSE_TYPE
Unknown eclipse type
Omit the parameter to receive both
Parameter: type.
400 · BAD_ECLIPSE_DIRECTION
Unknown eclipse direction
Use direction=range with start and end to list a period
Parameter: direction.
Cycles and lunar phases
400 · BAD_CYCLE_KEY
Unknown cycle key
The full key list is at /v2/enums?set=cycle_keys
Parameter: keys. Also carries: supported.
400 · BAD_PHASE_SELECTOR
Unknown phase selector
Accepted values: new_moon, first_quarter, full_moon, last_quarter
Parameter: phases. Also carries: supported.
400 · CLUSTER_PARAMETERS_REQUIRED
Cluster parameters are incomplete
Send the cluster parameters together, per the reference
Parameter: cluster_max_gap_deg.
Not returned by any shipped endpoint: The alignment cluster is Phase 2 and is not built yet.
Meteor showers
400 · UNKNOWN_SHOWER
Unknown meteor shower
Use an IAU three-letter code such as PER, or omit the parameter for every active shower
Parameter: shower.
Not returned by any shipped endpoint: Meteor-shower data is withheld pending its license review.
400 · TOO_MANY_SHOWERS
Too many showers
Omit the parameter to receive every qualifying shower
Parameter: shower.
Not returned by any shipped endpoint: Meteor-shower data is withheld pending its license review.
Pairs and conjunctions
400 · BAD_PAIR
The pair names one target twice
Name two different targets
Parameter: b.
400 · BAD_PAIRS
Malformed pair list
Write each pair as two body names joined by a hyphen, for example jupiter-saturn, and separate pairs with commas
Parameter: pairs.
400 · TOO_MANY_PAIRS
Too many pairs
Send fewer bodies, or list the pairs you want with pairs=
Parameter: pairs. Also carries: cap.
Retrogrades and lunar nodes
400 · BAD_MOTION
Unknown motion filter
Use one of the values in supported
Parameter: motion.
400 · BAD_HEMISPHERE
Unknown hemisphere
Use north or south
Parameter: hemisphere. Also carries: supported.
400 · BAD_NODE_MODEL
Unknown node model
Use one of the values in supported
Parameter: node_model.
Calendar export
400 · BAD_CALENDAR_SOURCE
Unknown calendar source
Use one of the values in supported; the event kinds are listed at /v2/enums?set=event_kinds
Parameter: sources.
Not returned by any shipped endpoint: The calendar surface (format=ics) is specified and not built.
400 · TOO_MANY_CALENDAR_SOURCES
Too many calendar sources
Send fewer sources
Parameter: sources.
Not returned by any shipped endpoint: The calendar surface (format=ics) is specified and not built.
400 · BAD_ALARM
Malformed alarm
Use a number and a unit, for example 30m, 2h or 1d, up to 7d. Send up to three, separated by commas
Parameter: alarm.
Not returned by any shipped endpoint: The calendar surface (format=ics) is specified and not built.
Sky quality and observing
400 · SKY_CLASS_REQUIRED
Sky darkness not stated
Send bortle=1 to 9, or nelm=<naked-eye limiting magnitude>. CycleCalcs will not assume a sky class for you
Parameter: bortle. Also carries: supported.
400 · BAD_BORTLE
Bad Bortle class
Use a whole Bortle class from 1 to 9
Parameter: bortle. Also carries: cap, supported.
400 · BAD_NELM
Bad limiting magnitude
Use a naked-eye limiting magnitude from 2.0 to 8.5
Parameter: nelm. Also carries: cap.
400 · BAD_APERTURE
Bad aperture
Give the aperture in millimetres, from 5 to 5000
Parameter: aperture_mm. Also carries: cap.
400 · BAD_LIMITING_MAGNITUDE
Limiting magnitude out of range
6.0 is a dark rural sky. 4.5 is a bright suburb
Parameter: limiting_magnitude.
Not returned by any shipped endpoint: The celestial-navigation surface (sight reduction, sextant corrections) is specified and not built.
Celestial navigation
400 · BAD_SEXTANT_ALTITUDE
Bad sextant altitude
Send the sextant reading as decimal degrees, or as DD:MM.M, for example 27:48.0
Parameter: hs.
Not returned by any shipped endpoint: The celestial-navigation surface (sight reduction, sextant corrections) is specified and not built.
400 · BAD_INDEX_ERROR
Bad index error
Positive is on the arc and is subtracted from the reading
Parameter: index_error_arcmin.
Not returned by any shipped endpoint: The celestial-navigation surface (sight reduction, sextant corrections) is specified and not built.
400 · BAD_HEIGHT_OF_EYE
Bad height of eye
Give the height of eye in metres, from 0 to 5000
Parameter: height_of_eye_m.
Not returned by any shipped endpoint: The celestial-navigation surface (sight reduction, sextant corrections) is specified and not built.
Dark-window search
400 · BAD_MOON_ALTITUDE
Bad Moon altitude threshold
Give an altitude in degrees from -90 to 90
Parameter: moon_altitude_max_deg.
Data and engine availability
400 · OUTSIDE_MODEL_RANGE
Outside the model's range
Varies by endpoint
Parameter: varies.
API keys
401 · INVALID_KEY
The API key is not valid
Remove the key to call anonymously; see /api/keys.html
Parameter: none (not tied to a single parameter).
Not returned by any shipped endpoint: These codes never fire: a key this deployment cannot verify is still served, at the anonymous tier with a warning.
401 · REVOKED_KEY
This API key has been revoked
See /api/keys.html
Parameter: none (not tied to a single parameter).
Not returned by any shipped endpoint: These codes never fire: a key this deployment cannot verify is still served, at the anonymous tier with a warning.
401 · EXPIRED_KEY
This API key has expired
See /api/keys.html
Parameter: none (not tied to a single parameter).
Not returned by any shipped endpoint: These codes never fire: a key this deployment cannot verify is still served, at the anonymous tier with a warning.
Platform and routing
404 · UNKNOWN_ENDPOINT
No such endpoint
Check the path against the endpoint list at /v2
Parameter: none (not tied to a single parameter). Also carries: supported.
405 · METHOD_NOT_ALLOWED
This endpoint accepts GET, HEAD and OPTIONS only
Use GET, HEAD or OPTIONS
Parameter: none (not tied to a single parameter).
410 · ENDPOINT_RETIRED
This endpoint has been retired
Use the replacement named in hint; see /api/versioning.html
Parameter: none (not tied to a single parameter).
503 · ENDPOINT_BLOCKED
This endpoint is not available yet
See /api/status.html
Parameter: none (not tied to a single parameter).
410 · ENDPOINT_WITHDRAWN
Endpoint withdrawn
See /methodology.html#data-sources for the current data provenance and the changelog for the withdrawal record
Parameter: none (not tied to a single parameter).
429 · RATE_LIMITED
Too many requests
Wait the number of seconds in Retry-After, cache the response, or use the range form to fetch many instants in one call
Parameter: none (not tied to a single parameter).
See also: API Status and Limits.
500 · INTERNAL_ERROR
Something went wrong computing this answer
Retry once; if it persists, report it with the request_id
Parameter: none (not tied to a single parameter).
See also: API Status and Limits.
500 · COMPUTATION_FAILED
The computation did not converge
Report it with the request_id; include the exact URL
Parameter: none (not tied to a single parameter).
See also: API Status and Limits.
All API documentation
- Developer hub: What to build and where every tool lives: API, MCP server, widgets.
- Overview and playground: What the API answers, the plans, and a live try-it panel.
- Endpoint reference: Every route, its parameters and a real captured response.
- Keys and plans: How to get a key, what each plan raises, and how quotas are counted.
- Error codes: The registered problem documents, one entry per code.
- Accuracy and residuals: Measured error against reference ephemerides, and the conventions every response states.
- Versioning policy: What is frozen, what may change, and how a change is announced.
- Status and limits: Rate windows, range caps and the current service position.
- MCP server: The same engine as tools an AI assistant can call directly.
- Version 1 (frozen): The original seven endpoints, still served and never changing shape.
- Terms of use: What you may do with the answers, including in commercial products.