TIMELINE OF EVERYTHING — MANUAL DEVELOPER-CONSOLE SUBMISSION FORMAT =================================================================== Canonical site: https://timelineofeverything.online/ API base: https://timelineofeverything.online/api/timeline Live API instructions: https://timelineofeverything.online/llms.txt OpenAPI schema: https://timelineofeverything.online/api/timeline/openapi.json Accepted types, tags, locations, and exact location IDs: https://timelineofeverything.online/api/timeline/options PURPOSE ------- This file is meant to be handed to GPT, Claude, Codex, or another AI when a person wants the AI to prepare a manual browser Developer Tools (F12) console submission. Follow the format exactly. Do not invent facts, sources, dates, locations, people, organizations, or duplicate events. The browser console is only a transport. Every event must still be researched, properly sourced, and correctly formatted. SECURITY -------- 1. Never ask for or paste a password, browser cookie, or session token. 2. Never put an API key into an event payload or send it to another domain. 3. A timeline API key is optional. If used, it belongs only in the Authorization header as `Bearer toe_live_...` and should not be shared with an AI unless the user consciously chooses to do so. 4. Run console code only on timelineofeverything.online or lowexpectations.dev. 5. Read the code before pasting it. Do not paste unrelated or obfuscated code. REQUIRED WORKFLOW ----------------- 1. GET `/api/timeline/limits` before submitting. 2. GET `/api/timeline/options` and use its current `acceptedSubmissionTypes` and `locations`. Never guess a location ID. 3. Research each event and retain reliable HTTP(S) source URLs. 4. Check duplicates. The batch endpoint performs validation and duplicate checks, but an agent may also POST each proposed event to `/events/duplicate-check`. 5. Submit with POST `/events/batch` using `{"events":[...]}`. 6. Read every item in the response. HTTP 207 means some items failed. 7. Correct only failed items. Do not blindly retry successful items. 8. Never override `exact_duplicate`. Override `possible_duplicate` only after confirming that the proposed event is genuinely different. 9. On HTTP 429, stop and wait for `Retry-After`. Do not fan out requests or run parallel loops to evade limits. GEOGRAPHY IS REQUIRED --------------------- Every event must include a non-empty `locationIds` array. Use the IDs returned by GET `/api/timeline/options`: - One country: `"locationIds": ["loc_usa"]` - Cross-border: `"locationIds": ["loc_gbr", "loc_fra"]` - Genuinely global: `"locationIds": ["loc_worldwide"]` - Off-Earth/space: `"locationIds": ["loc_outer_space"]` - Moon: `"locationIds": ["loc_moon"]` - A launch may include both its Earth country and space, for example `"locationIds": ["loc_usa", "loc_outer_space"]`. Attach every directly involved country or territory. Do not use a free-form country tag as a substitute for `locationIds`; the server automatically adds attached country names as searchable tags. If geography is omitted, the API returns HTTP 422 and: `"code": "location_required"` The response includes `details[0].examples`. Rewrite that event with correct `locationIds` and retry only that failed event. `loc_unknown` is not accepted for new submissions. EVENT OBJECT SCHEMA ------------------- Required fields: { "title": "Concise canonical event name", "description": "A factual explanation of what happened and why it matters.", "type": "science", "startDate": {"year": "1969", "month": 7, "day": 20, "precision": "day"}, "tags": ["space exploration", "human spaceflight", "moon landing"], "locationIds": ["loc_usa", "loc_moon"], "sources": [ {"url": "https://example.org/reliable-source", "title": "Readable source title"} ] } Supported optional fields: { "endDate": {"year": "1972", "precision": "year"}, "aliases": ["Legitimate alternate name"], "translatedNames": {"fr": "Sourced French name"}, "people": ["Canonical Person Name"], "organizations": ["Canonical Organization Name"], "duplicateOverride": false } FIELD RULES ----------- `title` - Required; 1–160 characters. - Use a concise canonical English event name. - Do not stuff dates, countries, aliases, or search keywords into the title. - Birth events may use `Person Name is born`; constructions may use `Structure Name is founded`, when that is the catalog convention. `description` - Required; maximum 5,000 characters. - State what happened using real factual context. - Do not say “included in the Timeline of Everything,” “historical milestone,” “significant event in history,” or merely repeat the title. - Do not add unsupported precision or promotional language. `type` - Required. Fetch the current list from `/options`. - Current accepted values include: birth, death, war, discovery, invention, political, politics, law, technology, economy, conflict, disaster, organization, science, religion, culture, sports, society, personal, and other. `startDate` and `endDate` - `year` is a signed integer string, not a JavaScript number. - The API uses astronomical year numbering: `0` is 1 BCE and `-44` is 45 BCE. - Precision must be `year`, `month`, `day`, `circa`, or `second`. - Include month/day only when supported by a source. - Use `endDate` for a real duration; omit it for a point event. - An end date is inclusive and cannot precede the start date. `tags` - Required; 1–20 tags, with at least three precise tags preferred. - Use topics and classifications, not aliases or keyword stuffing. - Reuse canonical tags returned by `/options` when possible. - Geography still belongs in `locationIds`. `locationIds` - Required; 1–12 supported IDs from `/options`. - Include every applicable country/territory. - Use `loc_worldwide` only for genuinely global events. - Use the most specific supported space location when possible. `sources` - Required; 1–8 unique HTTP(S) URLs. - Prefer primary, institutional, scholarly, archival, or strong reference sources. - Give each source a readable title. - A restricted source may be retained, but a nonexistent source is not evidence. `aliases`, `translatedNames`, `people`, and `organizations` - Include only genuine values that identify or directly participate in the event. - Do not put people or organizations into tags when the structured field applies. COPY-READY MANUAL CONSOLE RUNNER -------------------------------- Replace the sample `EVENTS` array with researched events. Keep `API_KEY` empty for the anonymous/session flow. If the user consciously supplies a revocable timeline key, place it only in `API_KEY` immediately before running and clear the console afterward. ```javascript (async () => { "use strict"; const API_BASE = location.hostname === "lowexpectations.dev" ? "https://lowexpectations.dev/api/timeline" : "https://timelineofeverything.online/api/timeline"; // Optional. Never paste a password or cookie here. const API_KEY = ""; // Replace this sample. Do not submit the sample event. const EVENTS = [ { title: "REPLACE WITH A REAL EVENT", description: "REPLACE WITH A FACTUAL DESCRIPTION", type: "science", startDate: { year: "1969", month: 7, day: 20, precision: "day" }, tags: ["replace-topic-one", "replace-topic-two", "replace-topic-three"], locationIds: ["loc_usa", "loc_moon"], sources: [ { url: "https://REPLACE-WITH-A-REAL-SOURCE.example/", title: "REPLACE WITH SOURCE TITLE" } ], people: [], organizations: [], aliases: [], translatedNames: {} } ]; const headers = { "Content-Type": "application/json" }; if (API_KEY) headers.Authorization = `Bearer ${API_KEY}`; const request = async (path, options = {}) => { const response = await fetch(`${API_BASE}${path}`, { credentials: "include", ...options, headers: { ...headers, ...(options.headers || {}) } }); const body = await response.json().catch(() => ({ error: "Response was not JSON." })); return { response, body }; }; const { response: limitsResponse, body: limits } = await request("/limits", { method: "GET" }); if (!limitsResponse.ok) throw new Error(`Limits request failed: ${JSON.stringify(limits)}`); const { response: optionsResponse, body: options } = await request("/options", { method: "GET" }); if (!optionsResponse.ok) throw new Error(`Options request failed: ${JSON.stringify(options)}`); const validTypes = new Set(options.acceptedSubmissionTypes); const validLocationIds = new Set(options.locations.map(item => item.id)); const localErrors = []; EVENTS.forEach((event, index) => { if (!event || typeof event !== "object") localErrors.push({ index, error: "Event must be an object." }); if (!event?.title || String(event.title).includes("REPLACE")) localErrors.push({ index, error: "Replace the sample title." }); if (!event?.description || String(event.description).includes("REPLACE")) localErrors.push({ index, error: "Replace the sample description." }); if (!validTypes.has(event?.type)) localErrors.push({ index, error: `Unsupported type: ${event?.type}` }); if (!Array.isArray(event?.locationIds) || event.locationIds.length === 0) localErrors.push({ index, code: "location_required", error: "Add locationIds." }); for (const id of event?.locationIds || []) { if (!validLocationIds.has(id)) localErrors.push({ index, code: "invalid_location_id", error: `Unknown location ID: ${id}` }); } if (!Array.isArray(event?.sources) || event.sources.length === 0) localErrors.push({ index, error: "At least one source is required." }); for (const source of event?.sources || []) { const url = typeof source === "string" ? source : source?.url; if (!url || String(url).includes("REPLACE") || String(url).includes(".example")) localErrors.push({ index, error: "Replace every sample source URL." }); } }); if (localErrors.length) { console.table(localErrors); throw new Error("Nothing was submitted. Correct the local validation errors first."); } const batchMaximum = Number(limits.batchMaximum || 0); if (!batchMaximum || EVENTS.length > batchMaximum) { throw new Error(`This caller may submit at most ${batchMaximum} events in this request. Nothing was submitted.`); } console.log("Submission identity and limits:", limits); console.log("Submitting events:", EVENTS.map(({ title, startDate, locationIds }) => ({ title, startDate, locationIds }))); const { response, body } = await request("/events/batch", { method: "POST", body: JSON.stringify({ events: EVENTS }) }); window.timelineSubmissionResults = body; console.log("HTTP status:", response.status); console.log("Full response saved as window.timelineSubmissionResults:", body); const summary = (body.results || []).map(result => ({ index: result.index, ok: result.ok, status: result.status, code: result.code || "", title: result.event?.title || EVENTS[result.index]?.title || "", eventId: result.event?.id || "", error: result.error || (result.errors || []).join(" ") })); console.table(summary); const failures = (body.results || []).filter(result => !result.ok); if (failures.length) { console.warn("Some events failed. Correct only these indexes; do not resubmit successful items.", failures); } else { console.log(`Created ${body.created} event(s). They are public and awaiting moderation.`); } })(); ``` HOW TO HANDLE COMMON RESPONSES ------------------------------ `202` - The event or entire batch succeeded. `207` - Mixed batch result. Inspect each `results[index]` item. `location_required` (422) - Add a valid non-empty `locationIds` array using `/options`. `invalid_location_id` or `invalid_location_classification` (422) - Replace invalid values with IDs currently returned by `/options`. `exact_duplicate` (409) - Do not create another event. Use the existing canonical event or submit a contribution when appropriate. `possible_duplicate` (409) - Compare the returned matches. Use `duplicateOverride: true` only when the event is genuinely different. `429` - Stop. Wait for `Retry-After`, then retry only items that did not succeed. `401` - The API key is invalid or revoked. Do not fall back silently to another identity. `5xx` - The server had a temporary problem. Preserve the response, verify which items succeeded, and do not blindly resend the whole batch. FINAL AGENT CHECKLIST --------------------- - Real, distinct event? - Concise canonical title? - Substantive factual description? - Supported date and honest precision? - Correct event type? - Three or more useful topic tags where possible? - Every applicable country/location attached? - `loc_worldwide` used only for genuinely global material? - Space location attached for off-Earth activity? - One to eight real HTTP(S) sources? - Duplicate response reviewed? - Successful batch items excluded from any retry?