Template placeholder extractor
Paste Hi {{name}} and {{name}} and get one placeholder, name, counted once: every distinct gap in your template, with nothing filled in. Double braces, dollar braces, the printf form and colon prefixes are recognized. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- Hi {{name}} and {{name}}
- Style
- Mustache
- Placeholders
- name
- Quantity
- 1
Extract unique template placeholders without filling them. Search intent: extract mustache variables / template placeholders. No network calls, no random seeds, and no server state are required for a correct answer.
Finding the gaps in a template
A template is text with gaps that get filled later: a greeting with the customer's name, an email with an order number, a message with a date. Each gap is marked with a placeholder, and different tools mark them differently. This one recognizes four common forms, double braces like {{name}}, a dollar sign with braces like ${name}, the printf form %(name)s and a colon prefix like :name, and returns every distinct name it finds without filling anything in. In Hi {{name}} and {{name}} the same name appears twice, so you get a single entry and a count of 1.
Why a clean list helps
Knowing exactly which placeholders a template contains tells you which pieces of data must exist before it is used, and a misspelled name stands out in the list straight away. Because repeated placeholders are listed once, the count tells you how many different values you need, not how many times they appear. The extraction runs entirely in your browser, with no network calls, random elements or stored state, so the same template always yields the same list.
How it works
Extract unique template placeholders without filling them. Supports mustache, ${}, printf %(name)s, and :colon styles. The implementation is pure JavaScript with no external services.
No network calls, no random seeds, and no server state are required for a correct answer. Failed jobs are not billed. Landings target the stated search intent with precise keywords.
Prefer explicit units and ranges over silent coercion of bad types. When a field is optional, defaults are documented in params and echoed in the output.
When to use it
Use this when your search intent matches the calculator name and you need a reproducible answer for teaching, finance ops, GIS, text tooling, or unit history work. Extract unique template placeholders without filling them. No network calls, no random seeds, and no server state are required for a correct answer.
Failed jobs are not billed. Landings target the stated search intent with precise keywords. Prefer explicit units and ranges over silent coercion of bad types.
When a field is optional, defaults are documented in params and
FAQ
Does it call the network?
No. All math and text transforms are local and deterministic.
Which placeholder syntaxes can it find?
Four common ones: double braces such as {{name}}, a dollar sign with braces such as ${name}, the printf form %(name)s and a colon prefix such as :name. You choose which syntax to look for.
Why does a repeated placeholder appear only once?
Because the list holds unique names. In Hi {{name}} and {{name}} the same placeholder appears twice, so the result is a single entry, name, with a count of 1.
Does it fill in the placeholders with values?
No. It only lists them and leaves the template exactly as it was. That way you can see which pieces of data a template expects before anything is filled in.
Does the same template always give the same list?
Yes. There are no random elements and no stored state, so the same template and the same syntax always produce exactly the same placeholders.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/text/placeholder-extract \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello {{name}}, id=${id}"}'const res = await fetch("https://api.kit.forhosting.com/text/placeholder-extract", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Hello {{name}}, id=${id}"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/placeholder-extract",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Hello {{name}}, id=${id}"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/placeholder-extract", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Hello {{name}}, id=${id}"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Hello {{name}}, id=${id}"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/placeholder-extract", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "Hello {{name}}, id=${id}"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.placeholder_extract",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
The calculator is free in the browser, deterministic, and identical in the API path. Inputs are validated before any arithmetic so invalid payloads fail with invalid_input. Half-up rounding is applied once from raw IEEE results when decimals are requested. Use the same JSON contract from spreadsheets, CMS hooks, automation,
How it works
The calculator is free in the browser, deterministic, and identical in the API path. Inputs are validated before any arithmetic so invalid payloads fail with invalid_input. Half-up rounding is applied once from raw IEEE results when decimals are requested. Use the same JSON contract from spreadsheets, CMS hooks, automation, or teaching demos.
Inputs, limits and rounding
Optional decimals use half-up once. No network calls, no random seeds, and no server state are required for a correct answer. Failed jobs are not billed. Landings target the stated search intent with precise keywords. Prefer explicit units and ranges over silent coercion of bad types. When Provide the required parameters as JSON numbers or strings as documented. Invalid types, missing required fields, or out-of-range values raise invalid_input with a clear message. Outputs echo key inputs so automation can log the full context of each call. The calculator is free in the browser, deterministic, and identical in the API path. Inputs are validated before any arithmetic so invalid payloads fail with invalid_input. Half-up rounding is applied once from raw IEEE results when decimals are requested. Use the same JSON contract from spreadsheets, CMS hooks, automation, or teaching demos.
When to use it
The calculator is free in the browser, deterministic, and identical in the API path. Inputs are validated before any arithmetic so invalid payloads fail with invalid_input. Half-up rounding is applied once from raw IEEE results when decimals are requested. Use the same JSON contract from spreadsheets, CMS hooks, automation, or teaching demos.
Integration use cases
Quick check
Paste values in the free widget and compare with a spreadsheet.
Automation
Call the API with the same JSON contract from n8n, scripts, or CMS.
Teaching
Show the formula and pinned golden examples without proprietary software.
Technical questions
Is it free in the browser?
Yes. Tier A runs fully client-side with the same core as the API.
What happens on bad input?
The handler throws invalid_input; failed jobs are not billed.
Can I use it from the API?
Yes. Send the same JSON fields documented in params.
Who authors this?
Aspire (elon@forhosting.com), EN-only delivery; Nitro hydrates locales.