URI template expander
The template language the GitHub API, OpenAPI links and every HAL or Hydra response speak — https://api.example.com/repos{/owner,repo}/issues{?state,labels*}. It looks like curl's {a,b} globbing and behaves nothing like it: the character after the brace is an operator that decides the prefix, the separator between values, and whether the value is escaped as a whole URI or as a single component. Paste a template and some JSON, and see exactly what it produces.
How to use
- Paste the template. Every variable it declares is listed under the result with its operator and modifier, and whether you have supplied a value for it.
- Press Fill variables from template to get a JSON skeleton with the right shape for each one — a string for a plain variable, a list or a key/value object for an exploded one.
- Edit the values. Expansion runs as you type, so the URL and the character count update immediately.
- Switch the direction to Match to go the other way: give it a real URL and it recovers the variables the template would have used.
The eight operators
Assume var = "value", list = ["red","green"] and keys = {"a":1,"b":2}.
| Form | Name | Result | What it is for |
|---|---|---|---|
{var} | simple | value | A single path or query component. Reserved characters are escaped. |
{+var} | reserved | value | Values that are themselves URIs or paths — / and ? pass through unescaped. |
{#var} | fragment | #value | Adds the # only when the variable is defined. |
{.var} | label | .value | Subdomains and file extensions. |
{/var} | path | /value | Path segments. {/list*} gives /red/green. |
{;var} | path-style parameter | ;var=value | Matrix parameters. The name is included automatically. |
{?var} | form query | ?var=value | The first query parameter. {?keys*} gives ?a=1&b=2. |
{&var} | form continuation | &var=value | A later query parameter, when the ? is already in the literal text. |
The two modifiers
:n— prefix.{var:3}takes the first three characters:val. Used for sharded paths like{hash:2}/{hash:4}/{hash}. It applies to strings only; combining it with*is an error, not a silent choice.*— explode. Changes how a list or an object is laid out. Without it,{?list}is one parameter with a comma-joined value:?list=red,green. With it,{?list*}is one parameter per item:?list=red&list=green. For an object,{?keys}flattens to?keys=a,1,b,2while{?keys*}becomes?a=1&b=2. Getting this wrong is the single most common URI-template bug, which is why the result is shown live.
An undefined variable is not an error
RFC 6570 is explicit: a variable with no value expands to nothing, and the surrounding operator
characters vanish with it. /users{/id} with no id is /users,
not /users/ and not an error. That is genuinely useful — it is how optional query
parameters work — and it is also how a typo in a variable name produces a URL that looks plausible
and points at the wrong resource.
So the variable table marks every declared variable you have not supplied, and the status line names them. If that list is not empty and you did not intend it to be, you have found your bug.
Matching in reverse
Given /users{/name}/posts{/id} and /users/ada/posts/42, the variables can
be recovered exactly: {"name":"ada","id":"42"}. That is useful for turning access logs
or a router table back into structured data.
It does not always work, and where it cannot the tool says so rather than guessing. Once an
expression declares several variables at once ({/owner,repo}) or explodes a list
({?labels*}), the output is ambiguous in reverse — nothing in
?a=1&b=2&c=3 says which parameters came from which variable, and
/a/b/c could be two variables or three. Those expressions are skipped, listed by name
in the status line, and the rest are still recovered.
FAQ
How is this different from the URL pattern expander?
Completely. URL pattern expander does curl-style globbing — {a,b} alternation and [1-100] ranges — and produces many URLs from one pattern. A URI template produces one URL from one set of variables, and the braces mean something entirely different. If you pasted a GitHub API template into a glob expander you would get nonsense; that is why both exist.
Which characters get escaped?
Every operator except + and # escapes anything outside the unreserved set A-Z a-z 0-9 - . _ ~, so a space becomes %20 and a slash becomes %2F. {+var} and {#var} additionally allow the reserved set and leave existing %XX triplets alone, which is what makes them safe for values that are already URLs.
Are the reserved operators supported?
No — =, ,, !, @ and | are reserved by the specification for future use and have no defined expansion, so a template using one is reported as an error instead of being guessed at.
Is anything uploaded?
No. Templates and variables are expanded in your browser. See the privacy note.