API
All numbers are exact integers or rationals (e.g. "49/4"), passed
as strings to avoid precision loss. ainvs may be the short
[a4, a6] or full [a1, a2, a3, a4, a6] Weierstrass form. The
POST endpoints require an Authorization: Bearer <token> header
— create a token on your profile page. The JSON downloads are
public.
POST /api/submit
Submits a curve with a set of witness points. The points are checked to lie on the curve, and
their independence is certified exactly by 2-descent quadratic characters at good primes
(Cremona/Brumer; torsion handled via exact torsion generators), proving
rank ≥ #points in E(ℚ) modulo torsion with no
floating-point arithmetic in the decision. The response's independence.certificate
lists the primes used and the F2 matrix ranks; the Néron–Tate regulator is
still reported as an informational diagnostic. On success the
curve is recorded on the leaderboard (subject to the entry rule below); a new curve is attributed to you, while
improving an already-recorded curve's rank bound updates its witness points but leaves the
original submitter's credit in place (the improvement is credited to you in the curve's
history and on your public page). Accepted curves and
witness points are stored in the curve's global minimal model. Body:
{ ainvs, points }, where points is a list of [x, y]
(an empty list submits the curve at rank ≥ 0).
The discriminant and Faltings height are recorded for every
curve (neither needs the primes). Optionally include primes: the primes of bad
reduction, equivalently the primes dividing the minimal discriminant. If they check out, the
conductor is computed and recorded — no factoring needed — along
with the verified prime list itself (deduplicated, sorted, extraneous good primes dropped).
Re-submitting an existing curve with primes backfills the conductor even if the
rank is unchanged.
Optionally include commentary: a string recorded as the curve's initial
commentary, attributed to you. It is applied only when the curve has no commentary yet
— if the curve already exists and already has commentary, this field is
ignored (use POST /curve/:id/commentary to edit existing
commentary). Commentary is plain text, with curve#123 links as described
there.
curl -X POST https://elliptic-rank.icarm.cloud/api/submit \
-H 'content-type: application/json' \
-H 'authorization: Bearer erank_...' \
-d '{
"ainvs": ["0","0","1","-6349808647","193146346911036"],
"points": [["49421","200114"], ["49493","333458"], ...],
"primes": ["2","3","211",...],
"commentary": "Found by Mestre (1982)."
}'
Returns 200 with the result below, 422 if the submission is
invalid (singular curve, point off curve, or not independent), 401 without a valid
token, 413 if the request body is too large, 429 if your account is
submitting too quickly, or 400 if the body isn't JSON. independence.rankLowerBound is
the proven bound, canonical.key identifies the curve up to ℚ-isomorphism, and
the leaderboard field reports the outcome — status is
"created", "improved" (with previousRank),
"unchanged" (a curve's record only changes when a witness proves a strictly higher
rank), or "declined". A curve not yet on the board is added only if it places in the
top 10 on some metric among curves of rank ≥ its own, either overall or
among those with the same torsion subgroup (a "created" result carries
"viaTorsion": true when only the latter applied); otherwise the
submission is verified but not stored, and leaderboard is
{ "status": "declined", "rank", "limit", "torsion", "placement": { "naive", "faltings", "conductor", "disc" }, "torsionPlacement": { ... } }
with each 1-based place overall and within the torsion subgroup (conductor is
null when no primes were supplied, so include them if the conductor is the metric your
curve is competitive on). Curves already on the board are never re-judged or removed.
{
"ok": true,
"curve": { "ainvs": [...], "c4": "...", "c6": "...", "discriminant": "...", "nonsingular": true },
"canonical": { "c4": "...", "c6": "...", "key": "304790815056:-166878443731135320" },
"points": [ { "point": ["49421","200114"], "onCurve": true }, ... ],
"allPointsOnCurve": true,
"independence": {
"independent": true, "rankLowerBound": 12,
"certificate": { // the exact independence proof
"primes": ["7","11","17", ...], "matrixRank": 12, "torsionRank": 0,
"halvings": 0, "torsion": "[]"
},
"regulator": "...", "precisionDigits": 62, // informational diagnostic
"method": "..."
},
"height": { "naiveLogHeight": "79.3286..." },
"faltingsHeight": "...",
"conductor": "...", // only if primes were supplied/recovered
"badPrimes": ["2","3","211", ...], // ditto: the verified primes, sorted
"torsion": "[]", // torsion structure (JSON invariant factors)
"leaderboard": { "status": "created", "rank": 12 }
}
POST /api/curve/:id/primes
Backfill the conductor of an
already-recorded curve from its primes of bad reduction — the programmatic equivalent of
the primes form on a curve's page, and an alternative to re-submitting through
/api/submit. (The discriminant and Faltings height are already recorded at
submission.) Send { primes: [...] }
with the primes of bad reduction (each a prime, together dividing the minimal discriminant to a
unit), or { "mode": "auto" } to attempt bounded trial division (which gives up on
hard factorizations). No factoring of large discriminants is performed otherwise.
curl -X POST https://elliptic-rank.icarm.cloud/api/curve/123/primes \
-H 'content-type: application/json' \
-H 'authorization: Bearer erank_...' \
-d '{ "primes": ["2","3","211"] }' # or: { "mode": "auto" }
Returns 200 with the computed invariants below. If the conductor is already
recorded it is a no-op — { "ok": true, "alreadyRecorded": true } (fetch
/curve/:id.json for the stored values). Returns 422 if the primes are
invalid or incomplete (with errors and note), 404 if there
is no such curve, 401 without a valid token, 413 if the body is too
large, or 400 if the body isn't JSON or the id isn't an integer.
{
"ok": true,
"id": 123,
"alreadyRecorded": false,
"conductor": "...",
"badPrimes": ["2","3","211"]
}
GET /api/curves/missing-primes
The curves whose primes of bad reduction (and so conductor) are not yet recorded, by id:
{ "curves": [{ "id": 12345, "discriminant": "76582385085647565163089..." }] }.
Each discriminant is the minimal discriminant, so its prime divisors (ignoring the
sign) are exactly the primes to send to /api/curve/:id/primes above. No auth
required.
GET /database.json
The entire database as one JSON download. The top level carries attribution metadata
(source, url, maintainer, acknowledgement,
documentation) so a shared copy still says where it came from, then
count and curves, each curve with its
global-minimal a-invariants, transformed witness points, discriminant (the minimal
discriminant), rank lower bound, naive height, Faltings height, and (when recorded) conductor,
bad_primes (the verified primes of bad reduction — the factorization of the
conductor's support), submitter, commentary, and history: later contributions by
other users, oldest first, each { kind, user, at } with kind either
"rank_improved" (also carrying old_rank and new_rank)
or "primes_recorded". No auth required.
GET /curve/:id.json
A single curve as JSON — the same shape as one entry of the
database.json curves array. No auth required.
POST /curve/:id/commentary
Edit a curve's commentary. Form-encoded content; an empty value clears it. Each
edit is kept in the curve's commentary history.
Commentary is plain text (HTML is shown literally), except that curve#123
— no space — is displayed as a link to curve 123.
curl -X POST https://elliptic-rank.icarm.cloud/curve/123/commentary \
-H 'authorization: Bearer erank_...' \
--data-urlencode 'content=Found by Mestre (1982).'