APISchemas

Schemas

Every document has a versioned JSON Schema (2020-12), served publicly. Validate against them.

Three documents, three schemas, all JSON Schema 2020-12:

SchemaDescribesServed at
theme-1.jsonA theme (Themes)/schemas/theme-1.json
card-1.jsonA card: which stats show (Card stats)/schemas/card-1.json
profile-1.jsonThe public page (Public profile API)/schemas/profile-1.json

The index

bash
curl https://api.taste.dev/schemas
Responsejson
{
  "schemas": [
    { "name": "theme", "version": 1, "url": "/schemas/theme-1.json" },
    { "name": "card", "version": 1, "url": "/schemas/card-1.json" },
    { "name": "profile", "version": 1, "url": "/schemas/profile-1.json" }
  ]
}

url is relative to the API host. No auth. Cached for a day.

One schema

bash
curl https://api.taste.dev/schemas/theme-1.json

Each file is served as application/schema+json. An unknown file is 404 {"error": "not_found"}.

  • Each schema's $id is https://taste.dev/schemas/{name}-{version}.json.
  • profile-1.json points at the other two by relative $ref (theme-1.json, card-1.json). Load all three into your validator and the refs resolve by $id.
  • theme-1.json is closed (additionalProperties: false): a theme may hold only the fields it defines. card-1.json and profile-1.json are open, so new fields can be added without breaking your validator.
  • theme-1.json uses "format": "uri" for background.image. Validators that don't check formats simply skip it.

Validate

Fetch all three, register them, validate against profile-1.json.

JavaScript (Ajv)
bash
npm install ajv ajv-formats
validate.mjsjs
import Ajv2020 from 'ajv/dist/2020.js';
import addFormats from 'ajv-formats';

const API = 'https://api.taste.dev';
const get = async (path) => (await fetch(API + path)).json();

const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);
for (const file of ['theme-1.json', 'card-1.json', 'profile-1.json']) {
  ajv.addSchema(await get(`/schemas/${file}`));
}

const validate = ajv.getSchema('https://taste.dev/schemas/profile-1.json');
const page = await get('/public/u/mika');
if (!validate(page)) console.warn(validate.errors); // render what you can anyway
Python (jsonschema)
bash
pip install jsonschema referencing requests
validate.pypython
import requests
from jsonschema import Draft202012Validator
from referencing import Registry, Resource

API = "https://api.taste.dev"
schemas = [requests.get(f"{API}/schemas/{f}").json()
           for f in ("theme-1.json", "card-1.json", "profile-1.json")]
registry = Registry().with_resources(
    (s["$id"], Resource.from_contents(s)) for s in schemas
)

validator = Draft202012Validator(schemas[2], registry=registry)
page = requests.get(f"{API}/public/u/mika").json()
for error in validator.iter_errors(page):
    print(error.json_path, error.message)  # render what you can anyway

To check a theme you wrote, validate it against https://taste.dev/schemas/theme-1.json the same way. The schema doesn't check contrast; see Contrast rules.

When validation fails

Reads are lenient. If a page doesn't validate, render what you can and skip what you don't understand. Never refuse to show a builder's page because of one field.