SCO-LDC API Reference

API version 3.1 · Document version 2026-06-03

This document describes the HTTP/JSON API of sco-ldc, a web service that returns quadratic limb-darkening coefficients (u1, u2) by trilinear interpolation of published Claret coefficient tables, and that resolves exoplanet names to host-star stellar parameters from the NASA Exoplanet Archive (NEA) and ExoFOP-TESS.

This reference is language-neutral and intended for any HTTP client (Java, JavaScript, Python, curl, etc.). All requests are HTTPS GET. All response bodies are JSON. The API requires no authentication and accepts unauthenticated cross-origin requests (CORS allow-origin is *).



1Conventions

Base URL

All endpoints are served from https://sco-ldc.com. HTTPS is required; the service does not accept HTTP.

Authentication

None. sco-ldc’s API is open and does not require API keys, tokens, registration, or any other credential. Any HTTP client can call any endpoint at any time.

Methods

All endpoints accept GET requests only. There is no POST, PUT, or DELETE. This reflects the read-only nature of the service: sco-ldc retrieves data and computes from it but does not store or modify state on behalf of callers.

Parameters

All parameters are passed as URL query string parameters. There is no JSON request body. Parameter names are case-sensitive. Numeric parameters can be passed as integers (5778) or as decimals (5778.0); both are accepted. Filter codes are strings and case-sensitive.

Response format

All successful responses are JSON with HTTP status 200. The response Content-Type is application/json. All field names use snake_case (e.g., filter_code, not filterCode). Numeric fields are always JSON numbers (not strings); string fields are always JSON strings (not numbers).

URL encoding

Filter codes containing special characters (the SDSS codes use an asterisk; planet names typically contain spaces) must be URL-encoded in the request. Most HTTP client libraries handle this automatically when parameters are passed as a structured dictionary or map rather than concatenated into the URL string. If constructing URLs manually, ensure that asterisks become %2A and spaces become %20 or +.


2Stability & versioning

The API described here is treated as a stable contract. Once a caller integrates with sco-ldc, the following are guaranteed:

Additions are not considered breaking and may happen without coordination:

If breaking changes ever become necessary, they will be exposed through versioned URL paths (e.g., /api/v2/compute) rather than by modifying the existing endpoints. Callers can continue using the current endpoints on their own timeline and migrate when convenient.

3Endpoints overview

EndpointPurpose
GET /api/healthLiveness probe and cache freshness diagnostic
GET /api/filtersCatalog of supported filters and their model coverage
GET /api/resolveResolve an exoplanet name or TOI to host-star Teff/logg/[Fe/H]
GET /api/computeCompute (u1, u2) given Teff, logg, [Fe/H], filter, and model

Typical integration flow

  1. (Optional, at startup or once per session.) Call /api/filters once to discover what filters and models are available, with their grid ranges. Cache the result locally.
  2. (Optional, per target.) Call /api/resolve?planet=<NAME> to fetch host-star Teff/logg/[Fe/H] from a planet or TOI name.
  3. (Per LDC requested.) Call /api/compute?teff=…&logg=…&feh=…&filter=…&model=… to obtain u1 and u2.

4GET /api/health

GET/api/health

Returns a status snapshot. Useful for liveness checks and for verifying that the underlying data sources are fresh before relying on a lookup.

Required parameters: none. · Optional parameters: none.

Response (HTTP 200)

{
  "status": "ok",
  "version": "3.1.0",
  "freshness": "ok",
  "tables": {
    "tableab.dat": 179645,
    "table5.dat": 574,
    "CBBQUADRATIC.txt": 7695
  },
  "filter_count": 26,
  "nea_cache":    { "count": 6287, "refreshed_utc": "2026-06-03 17:00 UTC" },
  "exofop_cache": { "count": 7934, "refreshed_utc": "2026-06-03 17:00 UTC" }
}

Field semantics

FieldTypeNotes
statusstringAlways ‘ok’ if the response was generated at all
versionstringServer-side application version identifier
freshnessstring‘ok’ if both planet caches refreshed within 48 h; else ‘stale’
tablesobjectRow counts per source file. Keys are file names; values are integers
filter_countintegerNumber of distinct filters loaded (currently 26)
nea_cache.countintegerRows currently held in the NEA planet cache
nea_cache.refreshed_utcstringLast successful live refresh; null if never refreshed
exofop_cache.countintegerRows in the ExoFOP TOI cache
exofop_cache.refreshed_utcstringSame convention as NEA

Notes for callers


5GET /api/filters

GET/api/filters

Returns the catalog of filters available and, per filter, which stellar atmosphere models are populated along with their parameter grid ranges. Calling /api/filters is the authoritative way to discover what’s currently supported; new filters or new model coverage can appear in future versions.

Required parameters: none. · Optional parameters: none.

Response (HTTP 200, abbreviated to one filter entry)

{
  "filters": [
    {
      "code": "V",
      "name": "Johnson V",
      "category": "Johnson-Cousins",
      "source": "CB2011",
      "citation": "Claret & Bloemen (2011, A&A 529, A75)",
      "models": [
        {
          "model": "ATLAS",
          "model_key": "ATLAS",
          "teff_min": 3500.0, "teff_max": 50000.0,
          "logg_min": 0.0,    "logg_max": 5.0,
          "feh_min":  -5.0,   "feh_max":  1.0,
          "feh_fixed": false,
          "n_points": 7813
        },
        {
          "model": "PHOENIX",
          "model_key": "PHOENIX",
          "teff_min": 2000.0, "teff_max": 9800.0,
          "logg_min": 3.5,    "logg_max": 5.0,
          "feh_min":  0.0,    "feh_max":  0.0,
          "feh_fixed": true,
          "n_points": 116
        }
      ]
    }
  ]
}

Field semantics (per filter entry)

FieldTypeNotes
codestringFilter code used in /api/compute. Case-sensitive
namestringHuman-readable filter name
categorystringFilter family: Johnson-Cousins, Sloan/SDSS, Strömgren, Space-based, Other
sourcestringInternal source tag: CB2011, C2018, C2021, or CMG2022
citationstringSource’s bibliographic citation
modelsarrayList of model entries (typically 1 or 2 per filter)

Field semantics (per model entry)

FieldTypeNotes
modelstringDisplay name used in /api/compute’s model parameter
model_keystringInternal storage key; identical to model except for TESS (PHOENIX-COND displays as such but is stored as PHOENIX)
teff_min/maxnumberGrid extent in K. Inclusive bounds. Inputs outside fail
logg_min/maxnumberGrid extent in cgs dex
feh_min/maxnumberGrid extent in dex. For PHOENIX models, a single value at 0.0
feh_fixedbooleantrue if the grid has only one [Fe/H] value (solar metallicity only)
n_pointsintegerTotal grid points populated for this filter+model combination

Notes for callers


6GET /api/resolve

GET/api/resolve

Looks up an exoplanet name or TESS Object of Interest (TOI) candidate identifier and returns host-star stellar parameters from the authoritative source (NEA for confirmed planets; ExoFOP-TESS for TOI candidates not in NEA).

Required parameters

NameTypeNotes
planetstringPlanet name or TOI identifier. Case-insensitive on lookup

Optional parameters: none.

Examples of valid input

Response when found (HTTP 200)

{
  "found": true,
  "planet": "WASP-23 b",
  "hostname": "WASP-23",
  "teff": 5150.0,
  "logg": 4.4,
  "feh":  -0.05,
  "source": "NEA",
  "citation": "DOI: 10.26133/NEA13"
}

Response when not found (HTTP 200, found=false)

{
  "found": false,
  "planet": "<input as supplied>",
  "reason": "not_in_nea",
  "suggestions": ["WASP-23 b", "WASP-3 b", "WASP-43 b"]
}

Response on upstream error (HTTP 200, found=false)

This is only returned in a degraded mode (the server cache is empty and a live upstream query also failed). In normal operation this shape is not returned.

{
  "found": false,
  "planet": "<input as supplied>",
  "reason": "error",
  "error": "NEA query timed out"
}

Field semantics

FieldTypeNotes
foundbooleantrue if the planet was resolved; false otherwise
planetstringCanonical planet name on success; raw input on failure
hostnamestringHost star designation (e.g. ‘WASP-23’)
teffnumber / nullEffective temperature in K, or null if the source has no value
loggnumber / nullSurface gravity log g in cgs dex, or null
fehnumber / nullMetallicity [Fe/H] in dex, or null
sourcestring‘NEA’ or ‘ExoFOP’. Tells the caller which database served this
citationstringCitation for the source database
reasonstringOn failure: ‘not_in_nea’, ‘not_in_exofop’, or ‘error’
suggestionsarray<string>On not_in_nea failure: up to 3 close-match planet names from NEA
errorstringOn error reason: a short human-readable explanation

Citation strings returned

Notes for callers


7GET /api/compute

GET/api/compute

Computes quadratic limb-darkening coefficients (u1, u2) by trilinear interpolation of the Claret table corresponding to the requested filter and atmosphere model. This is the main computational endpoint.

Required parameters

NameTypeNotes
teffnumberEffective temperature in K
loggnumberSurface gravity log g in cgs dex
filterstringFilter code from the /api/filters catalog. Case-sensitive

Optional parameters

NameTypeNotes
fehnumberMetallicity [Fe/H] in dex. Defaults to 0.0 if omitted
modelstring‘ATLAS’, ‘PHOENIX’, or ‘PHOENIX-COND’. Defaults to ‘ATLAS’ if omitted

Response on success (HTTP 200)

{
  "u1": 0.5124,
  "u2": 0.1558,
  "filter_code": "i*",
  "filter_name": "SDSS i'",
  "model": "ATLAS",
  "citation": "Claret & Bloemen (2011, A&A 529, A75)",
  "grid": {
    "teff_bracket": [5000.0, 5250.0],
    "logg_bracket": [4.0, 4.5],
    "feh_bracket": [-0.5, 0.0],
    "fractions": { "teff": 0.4, "logg": 0.8, "feh": 0.9 },
    "on_grid": false
  }
}

(The numeric values above are illustrative; actual values from the live API may differ.)

Response on invalid input (HTTP 400)

{
  "detail": "Invalid Input (Teff = 1500.0 K): The PHOENIX model does not support values of Teff below 2000 K."
}

Field semantics

FieldTypeNotes
u1numberFirst quadratic LDC
u2numberSecond quadratic LDC
filter_codestringThe filter code that was used (echoes the input)
filter_namestringHuman-readable filter name
modelstringThe model used (echoes/canonicalizes the input)
citationstringSource citation for the underlying Claret table
grid.teff_bracket[num, num]The two grid Teff values bracketing the input
grid.logg_bracket[num, num]Same for logg
grid.feh_bracket[num, num]Same for [Fe/H]
grid.fractions.teffnumberInterpolation fraction in [0, 1] along the Teff axis
grid.fractions.loggnumberSame for logg
grid.fractions.fehnumberSame for [Fe/H]
grid.on_gridbooleantrue if the input falls exactly on a grid point (no interpolation)

Citation strings by source

Notes for callers


8Error responses

A summary of every error case the API can return:

ScenarioHTTP statusBody shape
Healthy successful request200Endpoint-specific success shape
/api/resolve planet not found200{ "found": false, … } (see /api/resolve)
/api/compute invalid input (out of range)400{ "detail": "…" }
/api/compute unknown filter or model400{ "detail": "…" }
Missing required query parameter422FastAPI default validation error shape
Render upstream outage (rare)502 / 503Render’s load balancer page, not JSON
HTTP 422 note. If a required query parameter is missing entirely (e.g., calling /api/compute without a filter parameter), the response is HTTP 422 with FastAPI’s standard validation error shape, not HTTP 400. The body in that case is {"detail": [{"loc": […], "msg": "…", "type": "…"}]}. Callers should handle 422 alongside 400 as ‘client input was wrong.’
HTTP 502/503 note. If sco-ldc itself is unreachable (Render outage, cold-start in progress beyond the response timeout), the response may come from Render’s load balancer rather than from the application. This response is HTML rather than JSON. Callers should not assume any non-200 response will be JSON; they should check the Content-Type header before parsing.

Callers should treat any non-2xx response as a generic failure unless they specifically want to surface the message from detail.


9Implementation notes

Caching

Both the NEA planet table and the ExoFOP TOI table are cached in-memory on the server and refreshed once daily at 17:00 UTC. Callers do not need to invalidate or refetch on a faster cadence. Repeated /api/resolve calls for the same planet within a session will return identical values until the next daily refresh.

No rate limiting (currently)

The API has no enforced rate limits. The architecture handles dozens of requests per second comfortably. That said, individual workflows should not need more than a handful of calls per target, so this is not a real concern for normal use.

Network failures

If sco-ldc is unreachable (Render outage, DNS failure, network partition), the appropriate caller behavior is to surface this to the user and fall back to manual entry. The server should not be assumed to be always available.

Connection reuse

For occasional individual calls, connection management is a minor optimization. For higher-volume callers (a script processing many targets sequentially), it matters significantly: opening a fresh TLS connection per call adds 400–500 ms of handshake latency, while reusing an open connection eliminates this entirely. Most modern HTTP client libraries handle connection reuse via configured connection pools.

Recommended timeouts

Connection timeout 10 seconds, read timeout 30 seconds. Compute calls typically respond in 50–100 ms; resolve calls take a similar amount for cached planets and may take several seconds for live fallback queries when the cache misses. The 30-second read timeout gives ample headroom for slow network conditions without aborting on transient blips.

Filter discovery

Callers should ideally call /api/filters once per session (at startup, or lazily on first use) to discover the supported filters and grid ranges, rather than hardcoding the filter list. New filters may be added in future versions; calling /api/filters keeps the caller current automatically.

Citation surfacing

Each /api/resolve and /api/compute response includes a citation field. If a caller surfaces LDC values to a user, including the citation alongside (or in a tooltip) is the appropriate attribution and makes traceability straightforward. The two citations from a chained resolve+compute call are typically both needed for complete attribution in a publication.


10Example calls

Health check

GET https://sco-ldc.com/api/health
$ curl https://sco-ldc.com/api/health

Get filter catalog

GET https://sco-ldc.com/api/filters
$ curl https://sco-ldc.com/api/filters

Resolve a planet name

GET https://sco-ldc.com/api/resolve?planet=WASP-23+b
$ curl 'https://sco-ldc.com/api/resolve?planet=WASP-23%20b'

Resolve a TOI candidate

GET https://sco-ldc.com/api/resolve?planet=TOI-700.01

Compute LDCs

GET https://sco-ldc.com/api/compute?teff=5150&logg=4.4&feh=-0.05&filter=V&model=ATLAS
$ curl 'https://sco-ldc.com/api/compute?teff=5150&logg=4.4&feh=-0.05&filter=V&model=ATLAS'

Compute with default metallicity

GET https://sco-ldc.com/api/compute?teff=5150&logg=4.4&filter=V

Omitting feh defaults to 0.0; omitting model defaults to ATLAS.

Full target-to-LDC chain

To produce LDCs for WASP-23 b in Johnson V:

  1. GET /api/resolve?planet=WASP-23+b returns teff, logg, feh values from NEA.
  2. GET /api/compute?teff=<…>&logg=<…>&feh=<…>&filter=V&model=ATLAS returns u1 and u2.

The two-step chain is the canonical pattern for integrators (such as AstroImageJ) where the user supplies a planet name and the integration tool needs to populate LDCs automatically.


11Code

Source code repository: https://github.com/SCO-SCI/sco-ldc