Articles as JSON: how every page here is built
An article is one JSON object. The page, its Markdown and its machine copy are drawn from it; widgets show other articles, pieces of data, models and sources; any piece can be read, grepped and changed alone.
Every article on this site can now be one JSON object. You post the object; the site draws the page, the Markdown and the machine copy from it. Press JSON at the top of this page and you see the object this page is drawn from, whole. Press Article and you are back here.
The point is that the same object serves three readers at once: a person reading the page, a search engine reading the HTML, and a model reading /a/<slug>.json. Nothing is written into a page by hand, so nothing on a page can drift away from its data.
The object
An article is a JSON object with a slug and a title. Everything else is optional. The schema is public at /schemas/jarticle.json.
the smallest article that works
{
"slug": "my-first-article",
"title": "My first article",
"body": "Hello. This is **Markdown**."
}The fields that matter:
| Field | What it holds |
|---|---|
slug | the address, /a/<slug> |
title, summary | the headline and the lead under it; the summary is also the text on this article's card when another article carries it |
kind | what the article is about: person, house, company, procedure, model, place … any word; it shows as the badge above the title |
status | draft (only the owner sees it) or published |
facts | the data, nested as deep as you need |
card_fields | which facts a card of this article shows |
ontology | what sits above, below, beside and inside it |
body | Markdown, or a list of blocks where a block is Markdown or a widget |
widgets | widgets placed with [[widget:<id>]] |
sources | each with its URL, its quote and the hashes the build adds |
comments | what models said, each under its model's logo |
Articles that carry each other
A house's article can show the person who lives there, and the person's article can show the house. Each one draws the other from the other's own object, so there is one copy of every fact. These two are invented examples:
Two articles that carry each other (2)
- city
- Mill Valley
- built
- 1962
- bedrooms
- 3
- title
- pediatric nurse
- children
- 1
There are three ways to put one article inside another:
![[slug]]alone on a line: that article as a card. This is Obsidian's own embed syntax, so a vault of Markdown notes moves over as it is.![[slug#facts.work]]alone on a line: one piece of that article, drawn as a JSON widget.- A widget block:
{"type":"article","slug":"…","relation":"lives here"}.
[[slug]] and [[slug|words]] inside a sentence are plain links, also as in Obsidian.
The ontology
Where an article sits is part of its JSON, not a list of links on the page:
ontology
{
"ontology": {
"above": [
"vertical-insurance"
],
"below": [
"vehicle-damage-claim"
],
"adjacent": [
"bodily-injury-claim"
],
"nested": [
"police-report"
],
"show_position": true
}
}nested articles are drawn as cards at the end of the body. show_position: true also draws the box of what is above, below, beside and inside. Without it the page shows none of those links: they stay in the JSON for machines. That is why there is no "related articles" list on these pages.
Because every article is one stored object addressed by its slug, the number of articles has no ceiling but the store. A database of a hundred gigabytes can become a hundred thousand articles: one per row that matters, each pointing at the rows it relates to through ontology and facts.
Every widget
Each widget is a JSON object with a type. These are drawn live on this page.
JSON
A collapsible, coloured tree. Click a { to fold it. value holds the data, or ref points at a piece of any article ("slug#facts.path", or "#path" for this one).
a nested object
{
"permit": {
"kind": "ADU",
"fee_usd": 1240.5,
"paid": true,
"inspector": null,
"steps": [
"apply",
"plan check",
{
"inspect": [
"framing",
"final"
]
}
],
"portal": "https://example.gov/permits"
}
}Article card
{"type":"article","slug":"example-person-dana-reyes","relation":"resident"}
Model
{"type":"model","id":"openai/gpt-5"} draws a model from the live OpenRouter catalog: its company's logo, its name, its context window and its prices. {"type":"models"} draws every model, grouped by company; it has its own article, Every AI model on OpenRouter.
inspect — the catalog entry
{
"id": "anthropic/claude-opus-4.1",
"name": "Anthropic: Claude Opus 4.1",
"description": "Claude Opus 4.1 is an updated version of Anthropic’s flagship model, offering improved performance in coding, reasoning, and agentic tasks. It achieves 74.5% on SWE-bench Verified and shows notable gains...",
"context_length": 200000,
"pricing": {
"prompt": "0.000015",
"completion": "0.000075",
"web_search": "0.01",
"input_cache_read": "0.0000015",
"input_cache_write": "0.00001875",
"input_cache_write_1h": "0.00003"
},
"created": 1754411591,
"benchmarks": {
"design_arena": [
{
"arena": "models",
"category": "3d",
"elo": 1154,
"win_rate": 51.9,
"rank": 66
},
{
"arena": "models",
"category": "asciiart",
"elo": 1170,
"win_rate": 51.5,
"rank": 30
},
{
"arena": "models",
"category": "codecategories",
"elo": 1171,
"win_rate": 55.8,
"rank": 71
},
{
"arena": "models",
"category": "dataviz",
"elo": 1166,
"win_rate": 56.4,
"rank": 72
},
{
"arena": "models",
"category": "gamedev",
"elo": 1173,
"win_rate": 58.4,
"rank": 63
},
{
"arena": "models",
"category": "svg",
"elo": 1152,
"win_rate": 60.8,
"rank": 42
},
{
"arena": "models",
"category": "uicomponent",
"elo": 1164,
"win_rate": 57.8,
"rank": 70
},
{
"arena": "models",
"category": "website",
"elo": 1178,
"win_rate": 55.3,
"rank": 73
}
],
"artificial_analysis": {
"intelligence_index": 22.8,
"coding_index": null,
"agentic_index": null
}
},
"reasoning": {
"mandatory": false
},
"architecture": {
"modality": "text+image+file->text",
"input_modalities": [
"image",
"text",
"file"
],
"output_modalities": [
"text"
],
"tokenizer": "Claude",
"instruct_type": null
},
"top_provider": {
"context_length": 200000,
"max_completion_tokens": 32000,
"is_moderated": true
},
"knowledge_cutoff": "2025-01-31",
"hugging_face_id": null,
"supported_parameters": [
"include_reasoning",
"max_tokens",
"reasoning",
"stop",
"temperature",
"tool_choice",
"tools",
"top_k",
"top_p"
]
}inspect — the catalog entry
{
"id": "google/gemini-2.5-pro",
"name": "Google: Gemini 2.5 Pro",
"description": "Gemini 2.5 Pro is Google’s state-of-the-art AI model designed for advanced reasoning, coding, mathematics, and scientific tasks. It employs “thinking” capabilities, enabling it to reason through responses with enhanced accuracy...",
"context_length": 1048576,
"pricing": {
"prompt": "0.00000125",
"completion": "0.00001",
"image": "0.00000125",
"audio": "0.00000125",
"input_audio_cache": "0.000000125",
"web_search": "0.014",
"internal_reasoning": "0.00001",
"input_cache_read": "0.000000125",
"input_cache_write": "0.000000375",
"overrides": [
{
"min_prompt_tokens": 200000,
"prompt": "0.0000025",
"completion": "0.000015",
"audio": "0.0000025",
"input_audio_cache": "0.00000025",
"input_cache_read": "0.00000025"
}
]
},
"created": 1750169544,
"benchmarks": {
"design_arena": [
{
"arena": "models",
"category": "3d",
"elo": 1081,
"win_rate": 50.6,
"rank": 94
},
{
"arena": "models",
"category": "codecategories",
"elo": 1154,
"win_rate": 57.5,
"rank": 81
},
{
"arena": "models",
"category": "dataviz",
"elo": 1223,
"win_rate": 68.2,
"rank": 49
},
{
"arena": "models",
"category": "gamedev",
"elo": 1113,
"win_rate": 54.2,
"rank": 90
},
{
"arena": "models",
"category": "uicomponent",
"elo": 1141,
"win_rate": 57.5,
"rank": 79
},
{
"arena": "models",
"category": "website",
"elo": 1169,
"win_rate": 58.4,
"rank": 78
}
],
"artificial_analysis": {
"intelligence_index": 16.1,
"coding_index": 33.3,
"agentic_index": 1.6
}
},
"reasoning": {
"mandatory": true
},
"architecture": {
"modality": "text+image+file+audio+video->text",
"input_modalities": [
"text",
"image",
"file",
"audio",
"video"
],
"output_modalities": [
"text"
],
"tokenizer": "Gemini",
"instruct_type": null
},
"top_provider": {
"context_length": 1048576,
"max_completion_tokens": 65536,
"is_moderated": false
},
"knowledge_cutoff": "2025-01-31",
"hugging_face_id": null,
"supported_parameters": [
"include_reasoning",
"max_tokens",
"reasoning",
"response_format",
"seed",
"stop",
"structured_outputs",
"temperature",
"tool_choice",
"tools",
"top_p"
]
}Comment
A model's comment, under its logo. The comments list of an article draws the same way at the bottom of the page. POST /api/jarticles/<slug>/comments with {"model":"<openrouter id>","text":"…"} adds one.
inspect — the catalog entry
{
"id": "openai/gpt-5",
"name": "OpenAI: GPT-5",
"description": "GPT-5 is OpenAI’s most advanced model, offering major improvements in reasoning, code quality, and user experience. It is optimized for complex tasks that require step-by-step reasoning, instruction following, and accuracy...",
"context_length": 400000,
"pricing": {
"prompt": "0.00000125",
"completion": "0.00001",
"web_search": "0.01",
"input_cache_read": "0.000000125"
},
"created": 1754587413,
"benchmarks": {
"design_arena": [
{
"arena": "models",
"category": "3d",
"elo": 1056,
"win_rate": 41.3,
"rank": 103
},
{
"arena": "models",
"category": "asciiart",
"elo": 1143,
"win_rate": 49,
"rank": 48
},
{
"arena": "models",
"category": "codecategories",
"elo": 1169,
"win_rate": 54.5,
"rank": 73
},
{
"arena": "models",
"category": "dataviz",
"elo": 1221,
"win_rate": 60.5,
"rank": 50
},
{
"arena": "models",
"category": "gamedev",
"elo": 1186,
"win_rate": 59.3,
"rank": 59
},
{
"arena": "models",
"category": "svg",
"elo": 1188,
"win_rate": 64.1,
"rank": 30
},
{
"arena": "models",
"category": "uicomponent",
"elo": 1179,
"win_rate": 57.4,
"rank": 64
},
{
"arena": "models",
"category": "website",
"elo": 1186,
"win_rate": 53.7,
"rank": 70
}
],
"artificial_analysis": {
"intelligence_index": 23,
"coding_index": 37.8,
"agentic_index": null
}
},
"reasoning": {
"mandatory": true,
"supported_efforts": [
"high",
"medium",
"low",
"minimal"
],
"default_effort": "medium"
},
"architecture": {
"modality": "text+image+file->text",
"input_modalities": [
"text",
"image",
"file"
],
"output_modalities": [
"text"
],
"tokenizer": "GPT",
"instruct_type": null
},
"top_provider": {
"context_length": 400000,
"max_completion_tokens": 128000,
"is_moderated": true
},
"knowledge_cutoff": "2024-09-30",
"hugging_face_id": null,
"supported_parameters": [
"include_reasoning",
"max_completion_tokens",
"max_tokens",
"reasoning",
"reasoning_effort",
"response_format",
"seed",
"structured_outputs",
"tool_choice",
"tools",
"verbosity"
]
}Source
Every item of sources is drawn as a source card at the end, with its hash. The build hashes the quote when the article is saved (quote_sha256). POST /api/jarticles/<slug>/verify fetches each URL, hashes the page that came back (snapshot_sha256) and checks the quote is in it (quote_found). A source can also be placed in the body:
Quote, stat and note
Machine JSON is the canonical object; the article is a projection of it.— the design decision this page follows
Editing a piece, not the whole article
You never have to send the whole article to change it.
Read a piece: GET /api/jarticles/<slug>/at?path=facts.address.city answers the value and that piece's own hash.
Grep: GET /api/jarticles/<slug>/grep?q=cypress answers every key or value that matches, each with the path you would use to change it. GET /api/jarticles/grep?q=… searches every article.
Patch: PATCH /api/jarticles/<slug> with if-match: <hash> and a list of operations:
PATCH body
{
"ops": [
{
"op": "set",
"path": "facts.bedrooms",
"value": 4
},
{
"op": "merge",
"path": "facts.address",
"value": {
"zip": "94941"
}
},
{
"op": "append",
"path": "tags",
"value": "marin"
},
{
"op": "insert",
"path": "body[2]",
"value": "A new paragraph."
},
{
"op": "move",
"from": "facts.old",
"path": "facts.archive.old"
},
{
"op": "delete",
"path": "facts.lot_sq_ft",
"if_piece": "<sha256 of that piece from /at>"
}
]
}If someone changed the article after you read it, the hash no longer matches and the write is refused with the current hash. Read again, apply again. if_piece does the same for one piece: the write goes through only if that piece is still what you read.
The Obsidian commands
The Obsidian CLI is on the build's Mac. Its commands work on these articles through POST /api/jarticles/cli with {"command": "...", "file": "<slug or title>", ...}:
| Command | What it does |
|---|---|
files | every article, light |
read | one article whole (format: "md" for Markdown) |
create | a new article (name, content, or a whole object; overwrite to replace) |
append, prepend | add a block to the body (content is Markdown or a widget's JSON) |
move, rename | change the slug and rewrite every link to it in every other article |
delete | remove it |
links, backlinks, unresolved | what it links to, what links to it, links to articles that do not exist yet |
outline | its headings |
search, grep | text search, or a regular expression with paths |
property:read, property:set, property:remove, properties | read or change one path, like Obsidian's properties |
tags | every tag and how many articles use it |
patch | the operations above |
The look: every variable
Nothing on the page sets its own colour, size, width or border. Each value comes from one theme object, and each value becomes a CSS variable. The theme is at /article-theme.json. Change any value with PATCH /api/jarticles/theme and {"ops":[{"op":"set","path":"color.accent","value":"#8a3ffc"}]} (with the theme's hash in if-match), and every article changes at once. color_dark is the same palette when the reader's system is dark.
Every variable this page is drawn with · 103 (open)
| color.page_bg | #f5f5f7 | --color-page-bg |
| color.sheet_bg | #ffffff | --color-sheet-bg |
| color.ink | #1d1d1f | --color-ink |
| color.soft | #424245 | --color-soft |
| color.muted | #6e6e73 | --color-muted |
| color.dim | #86868b | --color-dim |
| color.line | #d2d2d7 | --color-line |
| color.accent | #0071e3 | --color-accent |
| color.accent_soft | rgba(0,113,227,0.08) | --color-accent-soft |
| color.link | #0066cc | --color-link |
| color.selection | rgba(0,113,227,0.18) | --color-selection |
| color.widget_bg | #f5f5f7 | --color-widget-bg |
| color.widget_border | #d2d2d7 | --color-widget-border |
| color.card_bg | #ffffff | --color-card-bg |
| color.code_bg | #f5f5f7 | --color-code-bg |
| color.json_bg | #161b19 | --color-json-bg |
| color.json_ink | #e6e1d4 | --color-json-ink |
| color.json_key | #7fd3c3 | --color-json-key |
| color.json_string | #e9c46a | --color-json-string |
| color.json_number | #f4a261 | --color-json-number |
| color.json_bool | #c792ea | --color-json-bool |
| color.json_null | #928d7e | --color-json-null |
| color.json_punct | #6b6759 | --color-json-punct |
| color.json_bar | #0e1512 | --color-json-bar |
| color.kind_badge_bg | #0e6e60 | --color-kind-badge-bg |
| color.kind_badge_ink | #ffffff | --color-kind-badge-ink |
| color_dark.page_bg | #000000 | --color-page-bg (dark) |
| color_dark.sheet_bg | #1d1d1f | --color-sheet-bg (dark) |
| color_dark.ink | #f5f5f7 | --color-ink (dark) |
| color_dark.soft | #d2d2d7 | --color-soft (dark) |
| color_dark.muted | #a1a1a6 | --color-muted (dark) |
| color_dark.dim | #86868b | --color-dim (dark) |
| color_dark.line | #424245 | --color-line (dark) |
| color_dark.accent | #2997ff | --color-accent (dark) |
| color_dark.accent_soft | rgba(41,151,255,0.12) | --color-accent-soft (dark) |
| color_dark.link | #2997ff | --color-link (dark) |
| color_dark.selection | rgba(41,151,255,0.25) | --color-selection (dark) |
| color_dark.widget_bg | #2c2c2e | --color-widget-bg (dark) |
| color_dark.widget_border | #424245 | --color-widget-border (dark) |
| color_dark.card_bg | #1d1d1f | --color-card-bg (dark) |
| color_dark.code_bg | #2c2c2e | --color-code-bg (dark) |
| color_dark.json_bg | #0a0d0c | --color-json-bg (dark) |
| color_dark.json_ink | #e6e1d4 | --color-json-ink (dark) |
| color_dark.json_key | #7fd3c3 | --color-json-key (dark) |
| color_dark.json_string | #e9c46a | --color-json-string (dark) |
| color_dark.json_number | #f4a261 | --color-json-number (dark) |
| color_dark.json_bool | #c792ea | --color-json-bool (dark) |
| color_dark.json_null | #757062 | --color-json-null (dark) |
| color_dark.json_punct | #5d665f | --color-json-punct (dark) |
| color_dark.json_bar | #060807 | --color-json-bar (dark) |
| color_dark.kind_badge_bg | #4fc1ab | --color-kind-badge-bg (dark) |
| color_dark.kind_badge_ink | #0b0f0d | --color-kind-badge-ink (dark) |
| font.display | -apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text","Helvetica Neue",Helvetica,Arial,sans-serif | --font-display |
| font.body | -apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text","Helvetica Neue",Helvetica,Arial,sans-serif | --font-body |
| font.mono | ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace | --font-mono |
| font.google_fonts | ||
| size.body | 17px | --size-body |
| size.small | 17px | --size-small |
| size.eye | 17px | --size-eye |
| size.lead | 17px | --size-lead |
| size.h1 | 52px | --size-h1 |
| size.h2 | 34px | --size-h2 |
| size.h3 | 22px | --size-h3 |
| size.byline | 17px | --size-byline |
| size.h1_measure | none | --size-h1-measure |
| size.code | 17px | --size-code |
| size.json | 17px | --size-json |
| size.widget_title | 17px | --size-widget-title |
| leading.body | 1.7 | --leading-body |
| leading.head | 1.18 | --leading-head |
| leading.lead | 1.5 | --leading-lead |
| leading.json | 1.6 | --leading-json |
| weight.display | 700 | --weight-display |
| weight.head | 700 | --weight-head |
| weight.body | 400 | --weight-body |
| weight.strong | 700 | --weight-strong |
| weight.eye | 700 | --weight-eye |
| tracking.eye | 0.14em | --tracking-eye |
| tracking.display | -0.03em | --tracking-display |
| tracking.body | -0.006em | --tracking-body |
| tracking.badge | 0.08em | --tracking-badge |
| layout.sheet_width | 1000px | --layout-sheet-width |
| layout.text_width | 880px | --layout-text-width |
| layout.gutter | 16px | --layout-gutter |
| layout.sheet_padding | 56px 64px 64px | --layout-sheet-padding |
| layout.sheet_padding_mobile | 24px 18px 40px | --layout-sheet-padding-mobile |
| layout.sheet_margin | 28px auto 72px | --layout-sheet-margin |
| layout.block_gap | 1.15em | --layout-block-gap |
| layout.widget_gap | 28px | --layout-widget-gap |
| layout.grid_gap | 14px | --layout-grid-gap |
| border.sheet | 0px solid | --border-sheet |
| border.sheet_radius | 30px | --border-sheet-radius |
| border.widget | 1px solid | --border-widget |
| border.widget_radius | 24px | --border-widget-radius |
| border.card_radius | 24px | --border-card-radius |
| border.badge_radius | 999px | --border-badge-radius |
| border.rule | 1px solid | --border-rule |
| border.code_radius | 18px | --border-code-radius |
| border.accent_bar | 3px | --border-accent-bar |
| shadow.sheet | 0 1px 1px rgba(0,0,0,.02),0 6px 26px rgba(0,0,0,.05) | --shadow-sheet |
| shadow.widget | none | --shadow-widget |
| shadow.card_hover | 0 10px 28px -16px rgba(28,27,23,0.35) | --shadow-card-hover |
| motion.hover | 160ms ease | --motion-hover |
The ending of every article
Every article page ends with the same line, so any reader, person or model, can look at the JSON or the Markdown the page is drawn from. The addresses are the same for every article; only the slug changes. No key is needed to read them.
the ending, as every article carries it
{
"ending": {
"label": "View the source of this page",
"json": "/a/<slug>/json",
"markdown": "/a/<slug>/md",
"same_as": {
"json": "/a/<slug>.json",
"markdown": "/a/<slug>.md"
},
"also": [
"/schemas/jarticle.json",
"/article-theme.json"
],
"hash": "sha256 of the object, first 16 characters"
}
}The ending of every article · 2 calls2
this page's JSON, by the ending (no key)
{
"what": "this page's JSON, by the ending (no key)",
"method": "GET",
"url": "https://miscsubjects.com/a/json-articles-how-they-work/json",
"headers": {}
}this page's Markdown, by the ending (no key)
{
"what": "this page's Markdown, by the ending (no key)",
"method": "GET",
"url": "https://miscsubjects.com/a/json-articles-how-they-work/md",
"headers": {}
}Every call, whole
Each call below is one object: the method, the full address, every header and the body. The key is never written into a page. The header holds the command that prints it on the Mac (cat /Users/cyrusmassoumi/.misc-sheets-key); the shell fills it in when the call is run. Where a call needs the article's current hash, the header holds the command that reads it. Calls that change something are shown against my-first-article, the smallest article, never against this page.
Reading, with no key
Reading, with no key · 7 calls7
the page
{
"what": "the page",
"method": "GET",
"url": "https://miscsubjects.com/a/json-articles-how-they-work",
"headers": {}
}the object, its hash and every call that reads or changes it
{
"what": "the object, its hash and every call that reads or changes it",
"method": "GET",
"url": "https://miscsubjects.com/a/json-articles-how-they-work.json",
"headers": {}
}the Markdown
{
"what": "the Markdown",
"method": "GET",
"url": "https://miscsubjects.com/a/json-articles-how-they-work.md",
"headers": {}
}the object, by the ending
{
"what": "the object, by the ending",
"method": "GET",
"url": "https://miscsubjects.com/a/json-articles-how-they-work/json",
"headers": {}
}the Markdown, by the ending
{
"what": "the Markdown, by the ending",
"method": "GET",
"url": "https://miscsubjects.com/a/json-articles-how-they-work/md",
"headers": {}
}the schema every article follows
{
"what": "the schema every article follows",
"method": "GET",
"url": "https://miscsubjects.com/schemas/jarticle.json",
"headers": {}
}every variable the pages are drawn with
{
"what": "every variable the pages are drawn with",
"method": "GET",
"url": "https://miscsubjects.com/article-theme.json",
"headers": {}
}Reading, with the key
Reading, with no key · 9 calls9
every article, light (q filters)
{
"what": "every article, light (q filters)",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles?q=json",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}one article whole, with its hash, drafts too
{
"what": "one article whole, with its hash, drafts too",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles/json-articles-how-they-work",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}one piece and that piece's own hash
{
"what": "one piece and that piece's own hash",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles/json-articles-how-they-work/at?path=facts.addresses",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}grep one article: every key or value that matches, with the path to change it
{
"what": "grep one article: every key or value that matches, with the path to change it",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles/json-articles-how-they-work/grep?q=widget",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}grep every article
{
"what": "grep every article",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles/grep?q=widget",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}the OpenRouter catalog the model widgets draw from
{
"what": "the OpenRouter catalog the model widgets draw from",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles/models",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}the schema, through the API
{
"what": "the schema, through the API",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles/schema",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}the theme and its hash
{
"what": "the theme and its hash",
"method": "GET",
"url": "https://miscsubjects.com/api/jarticles/theme",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}the structured block contract
{
"what": "the structured block contract",
"method": "GET",
"url": "https://miscsubjects.com/api/blocks/contract",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
}
}Creating and changing
Reading, with no key · 8 calls8
create an article (409 if the slug exists)
{
"what": "create an article (409 if the slug exists)",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"slug": "my-first-article",
"title": "My first article",
"body": "Hello. This is **Markdown**."
}
}change pieces: set, merge, delete, append, insert, move
{
"what": "change pieces: set, merge, delete, append, insert, move",
"method": "PATCH",
"url": "https://miscsubjects.com/api/jarticles/my-first-article",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json",
"if-match": "$(curl -sS -H 'x-sheets-key: $(cat /Users/cyrusmassoumi/.misc-sheets-key)' https://miscsubjects.com/api/jarticles/my-first-article | node -p \"JSON.parse(require('fs').readFileSync(0)).hash\")"
},
"body": {
"ops": [
{
"op": "set",
"path": "facts.bedrooms",
"value": 4
},
{
"op": "merge",
"path": "facts.address",
"value": {
"zip": "94941"
}
},
{
"op": "append",
"path": "tags",
"value": "marin"
},
{
"op": "insert",
"path": "body[2]",
"value": "A new paragraph."
},
{
"op": "move",
"from": "facts.old",
"path": "facts.archive.old"
},
{
"op": "delete",
"path": "facts.lot_sq_ft",
"if_piece": "<sha256 of that piece from /at>"
}
]
}
}replace the whole object
{
"what": "replace the whole object",
"method": "PUT",
"url": "https://miscsubjects.com/api/jarticles/my-first-article",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json",
"if-match": "$(curl -sS -H 'x-sheets-key: $(cat /Users/cyrusmassoumi/.misc-sheets-key)' https://miscsubjects.com/api/jarticles/my-first-article | node -p \"JSON.parse(require('fs').readFileSync(0)).hash\")"
},
"body": {
"slug": "my-first-article",
"title": "My first article, replaced",
"body": "Replaced."
}
}remove an article
{
"what": "remove an article",
"method": "DELETE",
"url": "https://miscsubjects.com/api/jarticles/my-first-article",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json",
"if-match": "$(curl -sS -H 'x-sheets-key: $(cat /Users/cyrusmassoumi/.misc-sheets-key)' https://miscsubjects.com/api/jarticles/my-first-article | node -p \"JSON.parse(require('fs').readFileSync(0)).hash\")"
}
}fetch every source, hash what came back, check each quote is in it
{
"what": "fetch every source, hash what came back, check each quote is in it",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/my-first-article/verify",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {}
}add a model's comment (this calls no model; it files the text given)
{
"what": "add a model's comment (this calls no model; it files the text given)",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/my-first-article/comments",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"model": "openai/gpt-5",
"text": "The comment text, written by hand."
}
}change the look: PATCH one variable
{
"what": "change the look: PATCH one variable",
"method": "PATCH",
"url": "https://miscsubjects.com/api/jarticles/theme",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json",
"if-match": "$(curl -sS -H 'x-sheets-key: $(cat /Users/cyrusmassoumi/.misc-sheets-key)' https://miscsubjects.com/api/jarticles/theme | node -p \"JSON.parse(require('fs').readFileSync(0)).hash\")"
},
"body": {
"ops": [
{
"op": "set",
"path": "theme.color.accent",
"value": "#1a5fb4"
}
]
}
}append an item to a caveat or thread widget
{
"what": "append an item to a caveat or thread widget",
"method": "POST",
"url": "https://miscsubjects.com/api/articles/json-articles-how-they-work/widgets/<widget id>",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"text": "The item's text.",
"by": "who wrote it",
"reply_to": "<item id, optional>"
}
}The Obsidian commands
Every command is the same call with a different body: POST /api/jarticles/cli. file is a slug or a title.
Reading, with no key · 21 calls21
cli: files
{
"what": "cli: files",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "files"
}
}cli: read
{
"what": "cli: read",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "read",
"file": "my-first-article",
"format": "md"
}
}cli: create
{
"what": "cli: create",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "create",
"name": "my-second-article",
"content": "Hello."
}
}cli: create
{
"what": "cli: create",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "create",
"object": {
"slug": "my-third-article",
"title": "My third article",
"body": "Hello."
},
"overwrite": false
}
}cli: append
{
"what": "cli: append",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "append",
"file": "my-first-article",
"content": "A paragraph added at the end."
}
}cli: prepend
{
"what": "cli: prepend",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "prepend",
"file": "my-first-article",
"content": {
"type": "stat",
"value": "1",
"label": "an example stat"
}
}
}cli: delete
{
"what": "cli: delete",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "delete",
"file": "my-second-article"
}
}cli: move
{
"what": "cli: move",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "move",
"file": "my-third-article",
"to": "my-fourth-article"
}
}cli: rename
{
"what": "cli: rename",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "rename",
"file": "my-fourth-article",
"name": "my-fifth-article"
}
}cli: links
{
"what": "cli: links",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "links",
"file": "json-articles-how-they-work"
}
}cli: backlinks
{
"what": "cli: backlinks",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "backlinks",
"file": "json-articles-how-they-work"
}
}cli: unresolved
{
"what": "cli: unresolved",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "unresolved"
}
}cli: outline
{
"what": "cli: outline",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "outline",
"file": "json-articles-how-they-work"
}
}cli: search
{
"what": "cli: search",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "search",
"query": "widget"
}
}cli: grep
{
"what": "cli: grep",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "grep",
"file": "json-articles-how-they-work",
"pattern": "widget"
}
}cli: property:read
{
"what": "cli: property:read",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "property:read",
"file": "my-first-article",
"name": "facts.bedrooms"
}
}cli: property:set
{
"what": "cli: property:set",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "property:set",
"file": "my-first-article",
"name": "facts.bedrooms",
"value": "4"
}
}cli: property:remove
{
"what": "cli: property:remove",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "property:remove",
"file": "my-first-article",
"name": "facts.bedrooms"
}
}cli: properties
{
"what": "cli: properties",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "properties",
"file": "my-first-article"
}
}cli: tags
{
"what": "cli: tags",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "tags"
}
}cli: patch
{
"what": "cli: patch",
"method": "POST",
"url": "https://miscsubjects.com/api/jarticles/cli",
"headers": {
"x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
"content-type": "application/json"
},
"body": {
"command": "patch",
"file": "my-first-article",
"ops": [
{
"op": "set",
"path": "summary",
"value": "One sentence."
}
]
}
}Every part of an article
An article has seven parts, in this order on the page. Each is shown here as the JSON that makes it and, where it can be drawn alone, as the thing the page draws.
1. The header
The badge is kind; the small words are the first three tags; then title, summary (the lead), and the byline built from byline, the posted and updated dates, and model. hero is the image above it all. A draft says so in the byline.
the header fields
{
"hero": "https://miscsubjects.com/img/gen/example.jpg",
"kind": "guide",
"tags": [
"json",
"widgets",
"ontology"
],
"title": "Articles as JSON: how every page here is built",
"summary": "The lead under the title; also the text of this article's card elsewhere.",
"byline": "optional",
"model": "anthropic/claude-opus-5.5",
"status": "published"
}2. The body
body is a Markdown string or a list of blocks. A block is a Markdown string, {"md":"…"}, or a widget object. The marks inside Markdown:
every mark the body understands
{
"**x**": "bold",
"*x*": "italic",
"`x`": "code",
"[words](https://…)": "a link",
"[[slug]] / [[slug|words]]": "a link to another article",
"![[slug]] alone on a line": "that article as a card",
"![[slug#facts.a.b]] alone on a line": "one piece of that article as a JSON widget",
"[[widget:<id or n>]] alone on a line": "widgets[n] or the widget with that id",
"```widget {json} ```": "a widget written inside a Markdown string",
"## x / ### x": "headings",
"> x": "a quote",
"- x / 1. x": "list items",
"| a | b |": "a table"
}3. The widgets
widgets is a list; each is placed with [[widget:<id or n>]] on a line of the body, and the ones never placed are drawn after the body. Every widget type follows in the next section.
4. The structured blocks
blocks is a list of blocks of the contract miscsubjects/blocks/1. They are drawn after the body and the widgets. There are four kinds. The nine content blocks are drawn at the end of this page, just above the sources. The other three are shown here as JSON, because drawing one means reading or acting on a real object.
the four kinds
{
"schema": "miscsubjects/blocks/1",
"version": 1,
"kinds": {
"content": {
"types": [
"paragraph",
"heading",
"list",
"checklist",
"code",
"quote",
"image",
"table",
"divider"
],
"about": "words and layout; renders, never acts"
},
"proposal": {
"about": "an operation that has not run",
"fields": [
"op",
"input",
"adapter?",
"binding",
"state",
"execution_id",
"object_ref",
"receipt_ref"
]
},
"object": {
"about": "a reference to a real application object",
"fields": [
"ref.id",
"component",
"object (state read live)",
"ops"
]
},
"receipt": {
"about": "immutable record of one invocation",
"fields": [
"execution_id",
"ledger_refs"
]
}
},
"states": [
"proposed",
"pending",
"succeeded",
"failed",
"uncertain",
"refused",
"unavailable",
"invalid"
],
"sync_states": [
"current",
"stale",
"pending",
"uncertain",
"failed",
"unavailable"
],
"statuses": [
"active",
"completed",
"archived",
"cancelled",
"deleted",
"unavailable"
]
}a proposal block
{
"kind": "proposal",
"v": 1,
"op": "task.create",
"input": {
"title": "An example task"
},
"adapter": null,
"binding": null,
"state": "proposed",
"execution_id": null,
"object_ref": null,
"receipt_ref": null
}an object block
{
"kind": "object",
"v": 1,
"ref": {
"id": "<the object's canonical id>"
},
"component": "task",
"ops": [
"task.complete",
"task.update"
]
}a receipt block
{
"kind": "receipt",
"v": 1,
"execution_id": "<the execution's id>",
"ledger_refs": [
"<ledger row id>"
]
}The tags a model may write, each turned into the same proposal block as the JSON form above:
the 17 tags
{
"TASK": "task.create · title",
"REMINDER": "task.create · title · apple_reminders",
"NOTE": "note.create · title · apple_notes",
"EVENT": "event.create · title",
"INVITE": "invitation.create · title",
"BOOKING": "booking.create · slot · calendly",
"CONTACT": "contact.create · name",
"PRODUCT": "product.create · title",
"THREAD": "thread.create · title",
"TERMINAL": "terminal.run · command",
"ALFRED": "alfred.trigger · trigger",
"MAIL": "mail.compose · body · apple_mail",
"SHORTCUT": "shortcut.run · name · apple_shortcuts",
"TRELLO-CARD": "card.create · name · trello",
"TODOIST": "task.create · content · todoist",
"NOTION-PAGE": "page.create · title · notion",
"LINEAR-ISSUE": "issue.create · title · linear",
"written_as": "[TASK]title: …[/TASK]"
}5. The nested articles and the position box
ontology.nested articles are drawn as cards at the end of the content; show_position: true draws the box of what is above, below, beside and inside.
Related pages
6. The sources and the comments
The sources are drawn as a swipeable row of cards under the content, each with the hash of its quote and of the page it came from. The comments are drawn last, under each model's logo. Both are lists of objects:
a source, whole
{
"id": "s1",
"url": "https://www.bls.gov/cew/",
"title": "Quarterly Census of Employment and Wages",
"publisher": "U.S. Bureau of Labor Statistics",
"source_type": "official_agency",
"date": "2025",
"quote": "the exact words on the page that support a fact",
"quote_sha256": "set by the build from quote",
"http_status": 200,
"snapshot_sha256": "set by verify: the hash of the page as fetched",
"snapshot_bytes": 111943,
"quote_found": true,
"verified_at": "2026-10-05T01:35:49.087Z"
}a comment, whole
{
"model": "openai/gpt-5",
"by": "optional",
"text": "The comment text.",
"at": "2026-10-08T00:00:00Z",
"reply_to": "optional id of the comment it answers"
}7. The ending
The footer: the ending described at the top of this page, and the first 16 characters of the object's hash.
Every widget, written and drawn
Each widget below appears twice: first as the JSON that makes it, then as the page draws it. The examples are invented for this page; none of the people, posts or links is real, and the addresses are example.com.
Data widgets
a value written in place
{ 2 keys
"nested": { 1 key
"as": [ 3 items
{
"type": "json",
"title": "a value written in place",
"value": {
"any": "json",
"nested": {
"as": [
"deep",
"as",
"needed"
]
}
},
"open_depth": 2
}this article's addresses
{ 6 keys
{
"type": "json",
"title": "this article's addresses",
"ref": "#facts.addresses",
"open_depth": 1
}a piece of another article
{ 7 keys
"address": { 4 keys
"residents": [ 1 item
"permits": [ 2 items
{ 3 keys
{ 3 keys
{
"type": "json",
"title": "a piece of another article",
"ref": "example-house-14-cypress-lane#facts",
"open_depth": 1
}{
"type": "article",
"slug": "example-person-dana-reyes",
"relation": "resident",
"fields": [
"facts"
]
}several cards (2)
- city
- Mill Valley
- built
- 1962
- bedrooms
- 3
- title
- pediatric nurse
- children
- 1
{
"type": "articles",
"title": "several cards",
"slugs": [
"example-house-14-cypress-lane",
"example-person-dana-reyes"
]
}inspect — the catalog entry
{
"id": "openai/gpt-5",
"name": "OpenAI: GPT-5",
"description": "GPT-5 is OpenAI’s most advanced model, offering major improvements in reasoning, code quality, and user experience. It is optimized for complex tasks that require step-by-step reasoning, instruction following, and accuracy...",
"context_length": 400000,
"pricing": {
"prompt": "0.00000125",
"completion": "0.00001",
"web_search": "0.01",
"input_cache_read": "0.000000125"
},
"created": 1754587413,
"benchmarks": {
"design_arena": [
{
"arena": "models",
"category": "3d",
"elo": 1056,
"win_rate": 41.3,
"rank": 103
},
{
"arena": "models",
"category": "asciiart",
"elo": 1143,
"win_rate": 49,
"rank": 48
},
{
"arena": "models",
"category": "codecategories",
"elo": 1169,
"win_rate": 54.5,
"rank": 73
},
{
"arena": "models",
"category": "dataviz",
"elo": 1221,
"win_rate": 60.5,
"rank": 50
},
{
"arena": "models",
"category": "gamedev",
"elo": 1186,
"win_rate": 59.3,
"rank": 59
},
{
"arena": "models",
"category": "svg",
"elo": 1188,
"win_rate": 64.1,
"rank": 30
},
{
"arena": "models",
"category": "uicomponent",
"elo": 1179,
"win_rate": 57.4,
"rank": 64
},
{
"arena": "models",
"category": "website",
"elo": 1186,
"win_rate": 53.7,
"rank": 70
}
],
"artificial_analysis": {
"intelligence_index": 23,
"coding_index": 37.8,
"agentic_index": null
}
},
"reasoning": {
"mandatory": true,
"supported_efforts": [
"high",
"medium",
"low",
"minimal"
],
"default_effort": "medium"
},
"architecture": {
"modality": "text+image+file->text",
"input_modalities": [
"text",
"image",
"file"
],
"output_modalities": [
"text"
],
"tokenizer": "GPT",
"instruct_type": null
},
"top_provider": {
"context_length": 400000,
"max_completion_tokens": 128000,
"is_moderated": true
},
"knowledge_cutoff": "2024-09-30",
"hugging_face_id": null,
"supported_parameters": [
"include_reasoning",
"max_completion_tokens",
"max_tokens",
"reasoning",
"reasoning_effort",
"response_format",
"seed",
"structured_outputs",
"tool_choice",
"tools",
"verbosity"
]
}{
"type": "model",
"id": "openai/gpt-5"
}inspect — the catalog entry
{
"id": "openai/gpt-5",
"name": "OpenAI: GPT-5",
"description": "GPT-5 is OpenAI’s most advanced model, offering major improvements in reasoning, code quality, and user experience. It is optimized for complex tasks that require step-by-step reasoning, instruction following, and accuracy...",
"context_length": 400000,
"pricing": {
"prompt": "0.00000125",
"completion": "0.00001",
"web_search": "0.01",
"input_cache_read": "0.000000125"
},
"created": 1754587413,
"benchmarks": {
"design_arena": [
{
"arena": "models",
"category": "3d",
"elo": 1056,
"win_rate": 41.3,
"rank": 103
},
{
"arena": "models",
"category": "asciiart",
"elo": 1143,
"win_rate": 49,
"rank": 48
},
{
"arena": "models",
"category": "codecategories",
"elo": 1169,
"win_rate": 54.5,
"rank": 73
},
{
"arena": "models",
"category": "dataviz",
"elo": 1221,
"win_rate": 60.5,
"rank": 50
},
{
"arena": "models",
"category": "gamedev",
"elo": 1186,
"win_rate": 59.3,
"rank": 59
},
{
"arena": "models",
"category": "svg",
"elo": 1188,
"win_rate": 64.1,
"rank": 30
},
{
"arena": "models",
"category": "uicomponent",
"elo": 1179,
"win_rate": 57.4,
"rank": 64
},
{
"arena": "models",
"category": "website",
"elo": 1186,
"win_rate": 53.7,
"rank": 70
}
],
"artificial_analysis": {
"intelligence_index": 23,
"coding_index": 37.8,
"agentic_index": null
}
},
"reasoning": {
"mandatory": true,
"supported_efforts": [
"high",
"medium",
"low",
"minimal"
],
"default_effort": "medium"
},
"architecture": {
"modality": "text+image+file->text",
"input_modalities": [
"text",
"image",
"file"
],
"output_modalities": [
"text"
],
"tokenizer": "GPT",
"instruct_type": null
},
"top_provider": {
"context_length": 400000,
"max_completion_tokens": 128000,
"is_moderated": true
},
"knowledge_cutoff": "2024-09-30",
"hugging_face_id": null,
"supported_parameters": [
"include_reasoning",
"max_completion_tokens",
"max_tokens",
"reasoning",
"reasoning_effort",
"response_format",
"seed",
"structured_outputs",
"tool_choice",
"tools",
"verbosity"
]
}{
"type": "comment",
"model": "openai/gpt-5",
"text": "An example comment, written by hand to show the widget. No model was called."
}Every variable this page is drawn with · 103 (open)
| color.page_bg | #f5f5f7 | --color-page-bg |
| color.sheet_bg | #ffffff | --color-sheet-bg |
| color.ink | #1d1d1f | --color-ink |
| color.soft | #424245 | --color-soft |
| color.muted | #6e6e73 | --color-muted |
| color.dim | #86868b | --color-dim |
| color.line | #d2d2d7 | --color-line |
| color.accent | #0071e3 | --color-accent |
| color.accent_soft | rgba(0,113,227,0.08) | --color-accent-soft |
| color.link | #0066cc | --color-link |
| color.selection | rgba(0,113,227,0.18) | --color-selection |
| color.widget_bg | #f5f5f7 | --color-widget-bg |
| color.widget_border | #d2d2d7 | --color-widget-border |
| color.card_bg | #ffffff | --color-card-bg |
| color.code_bg | #f5f5f7 | --color-code-bg |
| color.json_bg | #161b19 | --color-json-bg |
| color.json_ink | #e6e1d4 | --color-json-ink |
| color.json_key | #7fd3c3 | --color-json-key |
| color.json_string | #e9c46a | --color-json-string |
| color.json_number | #f4a261 | --color-json-number |
| color.json_bool | #c792ea | --color-json-bool |
| color.json_null | #928d7e | --color-json-null |
| color.json_punct | #6b6759 | --color-json-punct |
| color.json_bar | #0e1512 | --color-json-bar |
| color.kind_badge_bg | #0e6e60 | --color-kind-badge-bg |
| color.kind_badge_ink | #ffffff | --color-kind-badge-ink |
| color_dark.page_bg | #000000 | --color-page-bg (dark) |
| color_dark.sheet_bg | #1d1d1f | --color-sheet-bg (dark) |
| color_dark.ink | #f5f5f7 | --color-ink (dark) |
| color_dark.soft | #d2d2d7 | --color-soft (dark) |
| color_dark.muted | #a1a1a6 | --color-muted (dark) |
| color_dark.dim | #86868b | --color-dim (dark) |
| color_dark.line | #424245 | --color-line (dark) |
| color_dark.accent | #2997ff | --color-accent (dark) |
| color_dark.accent_soft | rgba(41,151,255,0.12) | --color-accent-soft (dark) |
| color_dark.link | #2997ff | --color-link (dark) |
| color_dark.selection | rgba(41,151,255,0.25) | --color-selection (dark) |
| color_dark.widget_bg | #2c2c2e | --color-widget-bg (dark) |
| color_dark.widget_border | #424245 | --color-widget-border (dark) |
| color_dark.card_bg | #1d1d1f | --color-card-bg (dark) |
| color_dark.code_bg | #2c2c2e | --color-code-bg (dark) |
| color_dark.json_bg | #0a0d0c | --color-json-bg (dark) |
| color_dark.json_ink | #e6e1d4 | --color-json-ink (dark) |
| color_dark.json_key | #7fd3c3 | --color-json-key (dark) |
| color_dark.json_string | #e9c46a | --color-json-string (dark) |
| color_dark.json_number | #f4a261 | --color-json-number (dark) |
| color_dark.json_bool | #c792ea | --color-json-bool (dark) |
| color_dark.json_null | #757062 | --color-json-null (dark) |
| color_dark.json_punct | #5d665f | --color-json-punct (dark) |
| color_dark.json_bar | #060807 | --color-json-bar (dark) |
| color_dark.kind_badge_bg | #4fc1ab | --color-kind-badge-bg (dark) |
| color_dark.kind_badge_ink | #0b0f0d | --color-kind-badge-ink (dark) |
| font.display | -apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text","Helvetica Neue",Helvetica,Arial,sans-serif | --font-display |
| font.body | -apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text","Helvetica Neue",Helvetica,Arial,sans-serif | --font-body |
| font.mono | ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace | --font-mono |
| font.google_fonts | ||
| size.body | 17px | --size-body |
| size.small | 17px | --size-small |
| size.eye | 17px | --size-eye |
| size.lead | 17px | --size-lead |
| size.h1 | 52px | --size-h1 |
| size.h2 | 34px | --size-h2 |
| size.h3 | 22px | --size-h3 |
| size.byline | 17px | --size-byline |
| size.h1_measure | none | --size-h1-measure |
| size.code | 17px | --size-code |
| size.json | 17px | --size-json |
| size.widget_title | 17px | --size-widget-title |
| leading.body | 1.7 | --leading-body |
| leading.head | 1.18 | --leading-head |
| leading.lead | 1.5 | --leading-lead |
| leading.json | 1.6 | --leading-json |
| weight.display | 700 | --weight-display |
| weight.head | 700 | --weight-head |
| weight.body | 400 | --weight-body |
| weight.strong | 700 | --weight-strong |
| weight.eye | 700 | --weight-eye |
| tracking.eye | 0.14em | --tracking-eye |
| tracking.display | -0.03em | --tracking-display |
| tracking.body | -0.006em | --tracking-body |
| tracking.badge | 0.08em | --tracking-badge |
| layout.sheet_width | 1000px | --layout-sheet-width |
| layout.text_width | 880px | --layout-text-width |
| layout.gutter | 16px | --layout-gutter |
| layout.sheet_padding | 56px 64px 64px | --layout-sheet-padding |
| layout.sheet_padding_mobile | 24px 18px 40px | --layout-sheet-padding-mobile |
| layout.sheet_margin | 28px auto 72px | --layout-sheet-margin |
| layout.block_gap | 1.15em | --layout-block-gap |
| layout.widget_gap | 28px | --layout-widget-gap |
| layout.grid_gap | 14px | --layout-grid-gap |
| border.sheet | 0px solid | --border-sheet |
| border.sheet_radius | 30px | --border-sheet-radius |
| border.widget | 1px solid | --border-widget |
| border.widget_radius | 24px | --border-widget-radius |
| border.card_radius | 24px | --border-card-radius |
| border.badge_radius | 999px | --border-badge-radius |
| border.rule | 1px solid | --border-rule |
| border.code_radius | 18px | --border-code-radius |
| border.accent_bar | 3px | --border-accent-bar |
| shadow.sheet | 0 1px 1px rgba(0,0,0,.02),0 6px 26px rgba(0,0,0,.05) | --shadow-sheet |
| shadow.widget | none | --shadow-widget |
| shadow.card_hover | 0 10px 28px -16px rgba(28,27,23,0.35) | --shadow-card-hover |
| motion.hover | 160ms ease | --motion-hover |
{
"type": "theme"
}Text widgets
An example quotation.— an example citation
{
"type": "quote",
"text": "An example quotation.",
"cite": "an example citation"
}{
"type": "stat",
"value": "42",
"label": "an example figure with its label"
}{
"type": "note",
"title": "An example note",
"text": "The note's **Markdown** text."
}{
"type": "card",
"title": "An example card",
"text": "The card's text.",
"footer": "the card's footer"
}{
"type": "checklist",
"title": "An example checklist",
"items": [
{
"text": "a finished item",
"done": true
},
{
"text": "an open item",
"done": false
}
]
}1curl -sS https://class="tm-c">undefineddone
{
"type": "terminal",
"title": "an example terminal",
"lang": "bash",
"code": "curl -sS https://miscsubjects.com/a/json-articles-how-they-work/json",
"command": "echo done",
"output": "done",
"caption": "the command and what it printed"
}
{
"type": "image",
"src": "https://miscsubjects.com/brand/og.png",
"alt": "the site's card image",
"caption": "an example image with its caption"
}{
"type": "gallery",
"images": [
{
"url": "https://miscsubjects.com/brand/og.png",
"alt": "the site's card image",
"caption": "the first image"
},
{
"url": "https://miscsubjects.com/brand/og.png",
"caption": "the second image"
}
]
}Expanding widgets
Shut until opened, and grown only by appending an item with the call shown above.
{
"type": "caveat",
"id": "caveat-example",
"title": "An example caveat",
"items": [
{
"id": "1",
"text": "The first limit.",
"by": "example",
"at": "2026-10-08"
}
]
}{
"type": "thread",
"id": "thread-example",
"title": "An example thread",
"items": [
{
"id": "1",
"text": "A first message.",
"by": "example",
"at": "2026-10-08",
"items": [
{
"id": "1.1",
"text": "A reply to #1."
}
]
}
]
}Messages
{
"type": "imessage",
"contact": "Example Contact",
"subtitle": "iMessage",
"messages": [
{
"from": "them",
"text": "An example message received."
},
{
"from": "me",
"text": "An example reply."
}
]
}{
"type": "whatsapp",
"chat_name": "Example Chat",
"subtitle": "online",
"messages": [
{
"from": "them",
"text": "An example message received.",
"time": "9:41"
},
{
"from": "me",
"text": "An example reply.",
"time": "9:42"
}
]
}Social posts
{
"type": "x",
"url": "https://example.com/x",
"author": "Example Author",
"handle": "@example",
"text": "An example post."
}{
"type": "reddit",
"url": "https://example.com/reddit",
"author": "u/example",
"title": "An example thread title",
"text": "An example post body."
}{
"type": "youtube",
"url": "https://example.com/youtube",
"title": "An example video",
"channel": "Example Channel",
"description": "An example description."
}{
"type": "instagram",
"url": "https://example.com/instagram",
"handle": "@example",
"caption": "An example caption.",
"images": [
"https://miscsubjects.com/brand/og.png"
]
}{
"type": "tiktok",
"url": "https://example.com/tiktok",
"handle": "@example",
"text": "An example caption."
}{
"type": "facebook",
"url": "https://example.com/facebook",
"handle": "Example Page",
"text": "An example post."
}{
"type": "linkedin",
"url": "https://example.com/linkedin",
"author": "Example Author",
"author_title": "Example Title",
"company": "Example Co",
"text": "An example post."
}Reference widgets
{
"type": "wikipedia",
"url": "https://en.wikipedia.org/wiki/Example",
"title": "Example",
"body": "An example excerpt.",
"infobox": {
"field": "value"
}
}{
"type": "site_embed",
"site": "example",
"institution": "Example Institution",
"url": "https://example.com/",
"title": "An example page",
"body": "An example excerpt.",
"date": "2026-10-08"
}{
"type": "source",
"source_type": "official_agency",
"url": "https://example.com/source",
"title": "An example source",
"publisher": "example.com",
"quote": "An example quotation from the source."
}Source cards, one for each kind of source
A source widget, and any widget whose type is one of these words, is drawn as the card of that kind. Each card is shown with its JSON.
Source cards, one for each kind of source31
{
"type": "x",
"url": "https://example.com/x",
"title": "An example x card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real x."
}{
"type": "reddit",
"url": "https://example.com/reddit",
"title": "An example reddit card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real reddit."
}{
"type": "instagram",
"url": "https://example.com/instagram",
"title": "An example instagram card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real instagram."
}{
"type": "youtube",
"url": "https://example.com/youtube",
"title": "An example youtube card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real youtube."
}{
"type": "pubmed",
"url": "https://example.com/pubmed",
"title": "An example pubmed card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real pubmed."
}{
"type": "clinical_trial",
"url": "https://example.com/clinical_trial",
"title": "An example clinical trial card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real clinical trial."
}{
"type": "review",
"url": "https://example.com/review",
"title": "An example review card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real review."
}{
"type": "medical",
"url": "https://example.com/medical",
"title": "An example medical card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real medical."
}{
"type": "statement",
"url": "https://example.com/statement",
"title": "An example statement card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real statement."
}{
"type": "press",
"url": "https://example.com/press",
"title": "An example press card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real press."
}{
"type": "disclosure",
"url": "https://example.com/disclosure",
"title": "An example disclosure card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real disclosure."
}{
"type": "gov",
"url": "https://example.com/gov",
"title": "An example gov card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real gov."
}{
"type": "dictionary",
"url": "https://example.com/dictionary",
"title": "An example dictionary card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real dictionary."
}{
"type": "book",
"url": "https://example.com/book",
"title": "An example book card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real book."
}{
"type": "encyclopedia",
"url": "https://example.com/encyclopedia",
"title": "An example encyclopedia card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real encyclopedia."
}{
"type": "wikipedia",
"url": "https://example.com/wikipedia",
"title": "An example wikipedia card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real wikipedia."
}{
"type": "hackernews",
"url": "https://example.com/hackernews",
"title": "An example hackernews card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real hackernews."
}{
"type": "news",
"url": "https://example.com/news",
"title": "An example news card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real news."
}{
"type": "nyt",
"url": "https://example.com/nyt",
"title": "An example nyt card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real nyt."
}{
"type": "business",
"url": "https://example.com/business",
"title": "An example business card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real business."
}{
"type": "email",
"url": "https://example.com/email",
"title": "An example email card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real email."
}{
"type": "letter",
"url": "https://example.com/letter",
"title": "An example letter card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real letter."
}{
"type": "github",
"url": "https://example.com/github",
"title": "An example github card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real github."
}{
"type": "stackoverflow",
"url": "https://example.com/stackoverflow",
"title": "An example stackoverflow card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real stackoverflow."
}{
"type": "arxiv",
"url": "https://example.com/arxiv",
"title": "An example arxiv card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real arxiv."
}{
"type": "discord",
"url": "https://example.com/discord",
"title": "An example discord card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real discord."
}{
"type": "anecdotal",
"url": "https://example.com/anecdotal",
"title": "An example anecdotal card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real anecdotal."
}{
"type": "receipt",
"url": "https://example.com/receipt",
"title": "An example receipt card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real receipt."
}{
"type": "live_surface",
"url": "https://example.com/live_surface",
"title": "An example live surface card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real live surface."
}{
"type": "endpoint",
"url": "https://example.com/endpoint",
"title": "An example endpoint card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real endpoint."
}{
"type": "api",
"url": "https://example.com/api",
"title": "An example api card",
"publisher": "example.com",
"quote": "An example quotation. This is not a real api."
}aliases: these words draw the same cards
{
"twitter": "x",
"tweet": "x",
"ig": "instagram",
"yt": "youtube",
"hn": "hackernews",
"gh": "github",
"imsg": "imessage",
"imessages": "imessage",
"wa": "whatsapp",
"callout": "note",
"caveats": "caveat",
"todo": "checklist",
"code": "terminal",
"codeblock": "terminal",
"code_block": "terminal",
"img": "image"
}Structured content blocks
The nine content blocks, drawn from this article's blocks list at the very end of the content, just above the sources.
Styling, whole
Nothing on a page is styled by hand. The JSON of an article, at /a/<slug>/json, now carries a styling object: the style scope, the rule for widgets, and the whole theme, so the object alone is enough to draw the page again. Every variable of the theme is also drawn, with its value, by the theme widget further up this page.
the styling object inside every article's JSON
{
"styling": {
"scope": "shared",
"how": "no value on the page is set by hand: each comes from this theme, and each theme value becomes the CSS variable named beside it. PATCH https://miscsubjects.com/api/jarticles/theme changes them.",
"widget_style": {
"what": "every widget may carry style: {…}; these are the only keys it reads",
"rotate": "degrees, a number",
"offset_x": "pixels, a number",
"offset_y": "pixels, a number",
"pulse": "true to pulse"
},
"theme": "every variable, grouped: see GET /article-theme.json"
}
}a widget with style, the JSON
{
"type": "stat",
"value": "7",
"label": "an example stat, turned 3 degrees, moved 8 pixels right and pulsing",
"style": {
"rotate": 3,
"offset_x": 8,
"offset_y": 0,
"pulse": true
}
}the article-level style field
{
"style_scope": "shared"
}What the JSON view is
The JSON switch at the top of a page, and the address /a/<slug>#json, show the whole object: every field, every block of the body, every widget, every source, the hash, the calls that read and change it and the styling. It is printed in full, not folded, with a copy button, and it is the same text /a/<slug>/json answers. /a/<slug>/md answers the Markdown. Both work for every article: JSON articles, procedures, the recovered articles and the archived pages (an archived page that was never stored as an object answers its page and its text in the JSON).
Counting views and words
Every article page tells the build once per browser tab that it was read (POST /api/view, body {"slug":"…"}); the count is kept in the table ms.article_views and shown in the byline. A word count is the words of the article's prose; widgets and facts are data and are not counted. The list at /articles sorts by most viewed, most sourced, most claims, longest, shortest, A to Z, newest and oldest, and filters by kind.
The machine surface
Every article answers at three addresses with no key:
/a/<slug>: the page/a/<slug>.json: the object, its hash, and every call that reads or changes it, whole/a/<slug>.md: the Markdown
The owner's calls live under /api/jarticles and take the build key in the header x-sheets-key:
| Call | What it does |
|---|---|
GET /api/jarticles | every article, light (?q= filters) |
POST /api/jarticles | create one |
GET /api/jarticles/<slug> | one whole, with its hash |
PUT /api/jarticles/<slug> | replace it (if-match) |
PATCH /api/jarticles/<slug> | change pieces (if-match) |
DELETE /api/jarticles/<slug> | remove it (if-match) |
GET /api/jarticles/<slug>/at?path= | one piece and its hash |
GET /api/jarticles/<slug>/grep?q= | matches with paths |
POST /api/jarticles/<slug>/verify | fetch and hash every source |
POST /api/jarticles/<slug>/comments | add a model's comment |
POST /api/jarticles/cli | the Obsidian commands |
GET / PATCH /api/jarticles/theme | the look |
GET /api/jarticles/models | the OpenRouter catalog the model widgets use |
GET /api/jarticles/schema | the schema |
The procedure pages
The paperwork procedures on the map at /procedures are drawn in this same frame now: the same bordered page, the same theme, the same Article and JSON switch, without the lists of links.
The skill
Models that write these articles are given one skill: the skill for writing JSON articles. Its Markdown copy at /a/json-article-writing-skill.md is the skill file itself.
Content blocks, drawn
A paragraph block. It holds plain text.
- a list item
- another list item
- ☐ a finished item
- ☐ an open item
curl -sS https://miscsubjects.com/a/json-articles-how-they-work/mdA quote block.

| column one | column two |
|---|---|
| a | b |
| c | d |
References (3)
- Quarterly Census of Employment and Wages — U.S. Bureau of Labor Statistics“The Quarterly Census of Employment and Wages (QCEW) program publishes a quarterly count of employment and wages reported by employers covering more than 95 percent of U.S. jobs”
- OpenRouter models API — OpenRouter
- Embed files — Obsidian Help“Embed a note”