Heads up: these endpoints are CORS-open, unauthenticated, and free to use. If you build automation on top of them, please be a good neighbour — cache aggressively for the GET endpoints (they only change when the wiki redeploys) and avoid runaway loops on /validate.

Overview

All endpoints share the same base URL and conventions:

  • Base URL: https://api.unofficial.voyage
  • CORS: open to all origins — safe to call from any web page, terminal, or agent runtime.
  • Auth: none. The wiki is a public reference.
  • Versioning: every endpoint serves the currently deployed wiki. The validator endpoint returns its validatorVersion in the response body.

Quick reference

EndpointMethodPurpose
/validatePOSTValidate a world JSON. Returns errors, warnings, and recommendations.
/GETManifest of every API endpoint.
/sections.jsonGETLightweight index of every documented section.
/sections/<section>.jsonGETOne section — prose, field notes, schema fragment.
/sections/<section>.mdGETSame as above, formatted as Markdown.
/wiki.jsonGETEntire wiki, all sections in one payload (JSON).
/wiki.mdGETEntire wiki concatenated as Markdown.
/schema.jsonGETRaw V36 codec schema.

POST /validate

Validates a world JSON against the live V36 schema plus every semantic check the in-browser Validator performs — cross-references, enum validity, size limits, runtime-affecting authoring patterns. Output is identical to the in-browser tool.

Request

  • Content-Type: application/json
  • Body: the world JSON object (the same JSON you would paste into the Voyage editor).

Response

JSON object with:

  • counts{ errors, warnings, recommendations } totals.
  • errors — array of { path, title, fix, detail?, value?, message }. If any are present, Voyage rejects the world — it won't pass validation or load (missing required fields, broken references, invalid values, malformed JSON). Zero errors means Voyage will accept it.
  • warnings — array of the same shape. Might break at runtime — behaviour degraded, fragile, or silently wrong.
  • recommendations — array of the same shape. Might improve quality — missing optional context the AI would benefit from. Safe to ignore by design.
  • validatorVersion — ISO-8601 timestamp of the currently deployed validator.

Example (curl)

bash
curl -X POST https://api.unofficial.voyage/validate \
  -H 'Content-Type: application/json' \
  --data-binary @MyWorld.json

Example (JavaScript)

javascript
const result = await fetch('https://api.unofficial.voyage/validate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(world),
}).then(r => r.json());

console.log(result.counts);
result.errors.forEach(({ path, message }) => console.log(path, message));

Example (Python)

python
import json, urllib.request

with open('MyWorld.json', 'rb') as f:
    body = f.read()

req = urllib.request.Request(
    'https://api.unofficial.voyage/validate',
    data=body,
    headers={'Content-Type': 'application/json'},
)
result = json.loads(urllib.request.urlopen(req).read())
print(result['counts'])

GET /sections.json

Lightweight index of every documented section — section key, title, tab, summary. No body content. Good for an agent to enumerate before fetching specific sections.

bash
curl https://api.unofficial.voyage/sections.json

GET /sections/<section>.json or .md

One section, fully self-contained. The .json form returns structured data; the .md form returns Markdown formatted for direct ingestion by an LLM. Both contain section metadata, the full prose body, per-field notes, and the V36 schema fragment for that section.

bash
curl https://api.unofficial.voyage/sections/npcs.json
curl https://api.unofficial.voyage/sections/locations.md

GET /wiki.json or .md

The entire wiki in one payload — useful when an agent wants the full V36 reference loaded into its context in a single request. The Markdown form is typically the better fit for LLM ingestion.

bash
curl https://api.unofficial.voyage/wiki.json
curl https://api.unofficial.voyage/wiki.md

GET /schema.json

Raw V36 codec schema as JSON — the same schema fragments embedded in the section endpoints, aggregated.

bash
curl https://api.unofficial.voyage/schema.json

Mirror the wiki for an offline agent

Some agents — notably ChatGPT and Codex in long-running threads — intermittently fail to fetch live URLs they should be able to reach. Mirroring the wiki to local disk once sidesteps that entirely: the agent reads from files instead of fetching. This pulls the top-level payloads plus every section, driving the section loop from /sections.json so it never goes stale when sections are added or removed.

bash
set -e
base='https://api.unofficial.voyage'
out='./voyage-wiki'   # change to your docs folder
mkdir -p "$out/sections"

curl -sSL "$base/"              -o "$out/manifest.json"
curl -sSL "$base/sections.json" -o "$out/sections.json"
curl -sSL "$base/schema.json"   -o "$out/schema.json"
curl -sSL "$base/wiki.json"     -o "$out/wiki.json"
curl -sSL "$base/wiki.md"       -o "$out/wiki.md"

# Drive the per-section loop from the live manifest (requires jq) so it never goes stale
curl -sSL "$base/sections.json" | jq -r '.[].section' | while read -r s; do
  curl -sSL "$base/sections/$s.md" -o "$out/sections/$s.md"
done

On Windows, the bash version needs Git Bash or WSL. PowerShell does the same thing natively with no jq dependency, since it parses JSON for you:

powershell
$base = 'https://api.unofficial.voyage'
$out  = './voyage-wiki'   # change to your docs folder
New-Item -ItemType Directory -Force -Path "$out/sections" | Out-Null

Invoke-WebRequest "$base/"              -OutFile "$out/manifest.json"
Invoke-WebRequest "$base/sections.json" -OutFile "$out/sections.json"
Invoke-WebRequest "$base/schema.json"   -OutFile "$out/schema.json"
Invoke-WebRequest "$base/wiki.json"     -OutFile "$out/wiki.json"
Invoke-WebRequest "$base/wiki.md"       -OutFile "$out/wiki.md"

# Section loop driven from the live manifest, so it never goes stale
Invoke-RestMethod "$base/sections.json" | ForEach-Object {
  Invoke-WebRequest "$base/sections/$($_.section).md" -OutFile "$out/sections/$($_.section).md"
}

If you only need the full reference in one file, skip the loop entirely and fetch /wiki.md — it bundles every section into a single Markdown document. The per-section mirror is for agents that want to open one topic at a time.

Agent prompt snippet

Drop this into your agent's system prompt or task instructions so it validates as it works:

You are authoring or editing a Voyage V36 world JSON.

Reference docs: every wiki section is available as a self-contained
endpoint at https://api.unofficial.voyage/sections/<section>.md or .json. Fetch only the
sections you need, or pull the whole wiki from https://api.unofficial.voyage/wiki.md in one request.

Verification: POST the JSON to https://api.unofficial.voyage/validate. The response groups
issues by severity:

  - errors: runtime-affecting problems. Fix these.
  - warnings: quality issues. Many are intentional; read the
    "Safe to ignore when..." line before acting.
  - recommendations: best-practice suggestions, same rule as warnings.

Validate after each batch of changes. Do not declare work complete
until counts.errors is 0.

Conventions and notes

  • Backtick chips in messages. Validator messages use backtick-wrapped tokens to mark field names and values, so agents can parse them as code-like literals.
  • Path notation. Validator path values use dot/bracket notation into the world JSON — e.g. locations.Acorn Hall.factions[0], npcs.Maren Halst.type.
  • Identical surfaces. The in-browser validator and this endpoint share the same engine. Output is identical across both.
  • No write endpoints. The wiki is read-only. Validation does not modify the submitted JSON.