Get the current timestamp from an API
Fetch a compact server-derived receipt instead of asking an offline model or stale context to guess the current time. GET /mjd returns UTC, Unix seconds, MJD, and a source marker in one JSON response.
Get a timestamp in one call
Run the curl example below. The fixed output is an illustrative response shape generated from a fixed Worker time fixture, not a permanently current value.
Fetch and validate it in JavaScript
The JavaScript example checks response.ok, handles 429 separately, validates the fields it uses, and always clears its AbortController timeout.
Fetch and validate it with Python’s standard library
The Python example sets a five-second timeout and handles HTTP, network, timeout, decoding, JSON, and schema failures without third-party packages.
Which field should you use?
- Use utc when you need the Worker-sampled time as a textual UTC ISO string.
- Use unix when your system expects whole Unix seconds; sub-second information is discarded.
- Use mjd when an integration requires the rounded numeric day representation.
- Request /jd only when the receiving system requires the additional jd field, which is also rounded.
- Store the field name and its semantics; do not store an unexplained number.
Expected output shape
The exact expected /mjd shape contains numeric mjd, string utc, integer unix, and the literal source marker "server". The value is the Worker clock read during response construction, not request-arrival time, caller-receipt time, or external event time.
Handle rate limits, timeouts, and bad responses
With the rate-limit KV binding configured, the current free path accepts one unauthenticated GET per CF-Connecting-IP value every 30 minutes, shared across /mjd and /jd. HEAD is quota-neutral. This is best-effort KV behavior. If CF-Connecting-IP is absent, the shared key is unknown. If the Worker has no rate-limit KV binding, the implementation bypasses the check; that fallback is not a promised service tier.
A successful HTTP status is not enough: validate the fields your program will use. The source: "server" value is a literal marker for the current response shape, not an authenticity check, signature, origin proof, or clock attestation.
- On 429, read Retry-After and do not immediately repeat the request.
- Treat aborts or timeout, DNS failures, connection failures, and unavailable service as missing external data.
- Reject malformed JSON and missing or wrongly typed fields.
- Do not silently substitute the local clock while labelling it as a SpyderGoat receipt.
- If fallback is acceptable, record its source explicitly in your own schema, such as source: "local-fallback".
Examples
Fetch the receipt
curl --fail-with-body --max-time 5 --header 'Accept: application/json' https://spydergoat.com/mjdFixed illustrative response shape
{
"mjd": 61107.38011574,
"utc": "2026-03-08T09:07:22.000Z",
"unix": 1772960842,
"source": "server"
}JavaScript with timeout and validation
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch("https://spydergoat.com/mjd", {
headers: { Accept: "application/json" },
signal: controller.signal,
});
if (response.status === 429) {
const retryAfter = response.headers.get("Retry-After");
throw new Error("SpyderGoat rate limited; Retry-After=" + retryAfter);
}
if (!response.ok) {
throw new Error("SpyderGoat HTTP " + response.status);
}
const data = await response.json();
if (
data === null ||
typeof data !== "object" ||
!Number.isFinite(data.mjd) ||
typeof data.utc !== "string" ||
!Number.isFinite(Date.parse(data.utc)) ||
new Date(Date.parse(data.utc)).toISOString() !== data.utc ||
!Number.isSafeInteger(data.unix) ||
data.source !== "server"
) {
throw new Error("Unexpected SpyderGoat response");
}
console.log(data);
} finally {
clearTimeout(timer);
}Python standard library with timeout and validation
import json
import math
import re
import socket
from datetime import datetime
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen
def get_receipt():
request = Request(
"https://spydergoat.com/mjd",
headers={"Accept": "application/json"},
)
try:
with urlopen(request, timeout=5) as response:
data = json.loads(response.read().decode("utf-8"))
except HTTPError as error:
retry_after = error.headers.get("Retry-After")
raise RuntimeError(
f"SpyderGoat HTTP {error.code}; Retry-After={retry_after}"
) from error
except (URLError, TimeoutError, socket.timeout) as error:
raise RuntimeError("SpyderGoat request failed") from error
except (UnicodeDecodeError, json.JSONDecodeError) as error:
raise RuntimeError("SpyderGoat returned malformed JSON") from error
try:
utc_text = data["utc"]
datetime.strptime(utc_text, "%Y-%m-%dT%H:%M:%S.%fZ")
valid = (
type(data["mjd"]) in (int, float)
and math.isfinite(data["mjd"])
and type(data["unix"]) is int
and data["source"] == "server"
and re.fullmatch(
r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z",
utc_text,
) is not None
)
except (KeyError, AttributeError, TypeError, ValueError):
valid = False
if not valid:
raise RuntimeError("Unexpected SpyderGoat response")
return data
print(get_receipt())Limits and non-guarantees
- What this receipt does not guarantee: SpyderGoat returns a server-derived HTTP time receipt derived from the Cloudflare Worker runtime clock. The Worker clock is read during response construction. It is an unsigned HTTP receipt, not NTP, an atomic-clock feed, a signed timestamp, or an RFC 3161 authority or timestamp token. It does not synchronize or discipline your clock, and it does not prove when an external event occurred. Displayed precision is not an accuracy guarantee. HTTP and network latency affect comparisons. SpyderGoat publishes no uptime or accuracy SLA.
Runtime provenance
This page describes current behavior defined by buildTimeResponse, checkFreeRateLimit, and request routing in src/api/worker.js, with public API behavior asserted in test/worker.test.js. The value source: "server" is a literal marker added by the Worker. It is not a signature, authentication, origin proof, or clock-quality attestation.