JSON URL Parameters GitHub issue
vibecode
{"vibecode": { "section": "overview", "scope": "ecoverse_wide", "policy": "machine_generated_urls_prefer_json_query_strings_over_key_value_pairs", "form": "https://host/path?{json}", "encoding": "percent_encoded_when_serialized" }}
Ecoverse-wide convention. When a URL is generated by code (not hand-typed by a developer), Puck services prefer passing parameters as a JSON object in the query string rather than as traditional ?key=value&key=value pairs.
https://www.puck.uno/something?{"map":true,"nw":[40.7,-74.0],"se":[40.8,-73.9]}
(The JSON is URL-encoded when actually transmitted — ?%7B%22map%22%3Atrue%7D — but the conceptual form is the JSON body after the ?.)
Why GitHub issue
For machine-generated URLs, JSON has real advantages over the traditional key-value query string:
- Structured data is natural. Arrays, nested objects, booleans, nulls — all of it expressible directly. No conventions like
?items[]=a&items[]=bfor arrays or?nested.field=...for structure. - Type fidelity.
trueis a boolean, not the string"true".42is a number, not the string"42". Saves callers from reparsing. - Single coherent payload. The whole parameter set is one logical structure; receivers parse it with one
JSON.parsecall. - Aligns with Puck's JSON-everywhere posture. Caspian, mikobase records, CaspianJ, blockchain blocks — Puck leans on JSON as the universal data carrier. URL params being JSON is consistent with that.
When to use it GitHub issue
Rule of thumb: if a machine generates the URL for one of our services on puck.uno, it should use the JSON form. That covers iframe src attributes pointing at puck.uno endpoints, embed URLs returned from puck.uno API methods, links generated programmatically that resolve to puck.uno services, and so on. URLs typed or edited by humans stay with the traditional form.
URLs pointing anywhere else — third-party APIs, external sites, or even other Puck-protocol implementations hosted by someone else — follow whatever convention those services expect (usually traditional ?key=value). The JSON convention is our preference for the services we run at puck.uno, not a protocol-level mandate. Third parties implementing Puck services on their own domains are free to follow their own URL conventions.
Why we still allow traditional parameterized queries. Even on puck.uno services where JSON is preferred for machine-generated URLs, we keep the traditional ?key=value form supported. This is a deliberate philosophical commitment: a simple Puck page should be clear enough that it can be used as a plain API without going through Puck at all. A developer poking at a service from curl, a webhook from an unrelated platform, a quick script in any language — none of these should need to learn the JSON-in-URL convention to hit a Puck endpoint. The JSON form is for our client code generating sophisticated requests; the traditional form is for everyone else. Both stay first-class.
This is part of Puck's broader first-contact strategy — developers should be able to get useful results from Puck services before buying into the whole framework. Free service tiers (see e.g. the planned logging service) are one expression of this; pages-as-plain-APIs is another. Both serve the same goal: the lowest possible barrier to a first useful interaction.
- Machine-generated URLs (preferred): URLs constructed by code, embedded in HTML by services, returned as part of API responses, etc. — JSON form is the convention.
- Hand-typed URLs (use traditional form): URLs a developer is expected to type, edit, paste, or share — keep the
?key=valueform for readability. - Mixed usage in one URL is actually encouraged for many use cases. Combining a JSON body with conventional key-value pairs in the same URL (e.g.,
?{"map":true}&debug=1&format=svg) is a legitimate pattern. The details — exact rules for mixing, parser order, precedence, whether mixed-form URLs canonicalize differently for cache keys — are TBD. Flagged as a topic to come back to.
The convention is a preference, not a hard rule. Services may support both forms where it makes sense.
Trade-offs and caveats GitHub issue
Things to keep in mind:
- URL encoding. JSON's punctuation (
{}"[],:) all needs percent-encoding when the URL is transmitted. The encoded form looks ugly. Browsers and developer tools handle encoding automatically, but the human-readable form is messier than traditional params. - Length limits. Practical URL length caps vary (~8 KB in modern browsers; some older systems ~2 KB). JSON adds punctuation overhead compared to flat key-value. For small param sets (the iframe-embed case), this is irrelevant; for large param sets, switch to a
POSTwith a JSON body. - Framework parsing. Most HTTP frameworks automatically parse the
?key=valueform into a hash. JSON-in-query-string needs custom parsing: the framework hands us the raw query string, weJSON.parseit ourselves. Not hard, but non-standard. Server-side handlers should detect "does the query start with{?" and pick the appropriate parser. - Caching keys. HTTP caches and CDNs key on full URLs. Two JSON-equivalent URLs with different key ordering or whitespace would cache as different entries unless the service normalizes them. Worth normalizing on the server side (parse + re-serialize) before doing cache lookups.
Implementation guidance GitHub issue
When Puck services emit URLs that take parameters:
- Decide whether the URL is machine-generated or human-facing.
- Machine-generated: build the JSON, URL-encode, append after
?. - Human-facing: use traditional
?key=valueform.
When Puck services receive a URL with parameters:
- Look at the raw query string. If it starts with
{(after URL decoding), parse as JSON. - Otherwise, parse as traditional
?key=value. - Either way, the handler ends up with a hash of parameters to work with.
Scope GitHub issue
Applies to every Puck service that generates URLs with parameters. The first concrete instance is the puck.uno/geo map embeds (iframe src, image URLs, etc.), but the same convention applies to anything else in the ecoverse that emits URLs containing structured params.
Dogberry support GitHub issue
Dogberry is currently undefined — see the brainstorm doc for the current shape (transforming proxy that fetches and executes remote Caspian). Whether Dogberry natively parses JSON URL parameters, and what shape that handler interface takes, is TBD as Dogberry firms up. The expectation is that any future HTTP middleware in the ecoverse will support both?key=value and the ?{"key":"value"} JSON-URL forms uniformly; this section will be fleshed out once Dogberry's request layer is specified.