Insert Text at a Position
Insert "beautiful " at position 6 of "Hello world" and you get "Hello beautiful world", 21 characters long. Nothing is overwritten, position 0 means the very start, and an emoji counts as one position. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- Hello world
- Insert text
- beautiful
- Position
- 6
- Result
- Hello beautiful world
- Original length
- 11
- Inserted length
- 10
- Result length
- 21
Insert Text at a Position adds a string exactly where you specify inside existing text. Provide the original text, the content to add, and a zero-based character position; the result preserves every original character and places the new content between the characters on either side of that index. It is useful for assembling templates, adding labels or separators, correcting generated content, and making precise edits in repeatable workflows. Unicode characters are counted consistently, so emoji and other characters outside the basic Latin alphabet do not unexpectedly consume two positions.
Choose the exact insertion point
Positions are zero-based, which means position 0 inserts before the first character. Position 1 inserts after the first character and before the second, while a position equal to the original text length appends the chosen string at the end. For example, the text Hello world has a space at position 5 and the letter w at position 6.
Inserting beautiful at position 6 produces Hello beautiful world. Nothing is overwritten: the operation splits the original at the requested boundary, places the insertion between the two pieces, and joins them again. This definition makes the operation predictable in scripts and visual editing tools.
A negative position or a value beyond the final boundary is rejected instead of being silently adjusted, preventing an unnoticed edit in the wrong place. The response repeats the applied position and reports original, inserted, and resulting character lengths so an automated workflow can verify what changed.
Work safely with Unicode text
This capability counts Unicode code points rather than JavaScript UTF-16 code units. That distinction matters whenever text contains emoji, historic scripts, or many less common symbols. A character such as an emoji may occupy two internal UTF-16 units, yet it is treated as one position here, so an insertion will not split its surrogate pair and create broken text.
The same counting rule is used for the reported original, inserted, and result lengths. Combining marks and multi-code-point emoji sequences can still contain several code points even when a font displays them as one visual cluster; this is a property of Unicode text rather than an arbitrary adjustment by the tool. If your source positions come from another system, confirm that it also counts Unicode code points.
Byte offsets, UTF-16 indexes, and grapheme-cluster indexes are different coordinate systems. Keeping the coordinate system explicit is especially valuable when templates move between browser code, databases, and backend services, because it prevents subtle position drift and makes repeated transformations produce the same result everywhere.
Build precise templates and editing workflows
Exact insertion is a small operation that becomes powerful when composed with other steps. A document workflow can insert an account name after a fixed greeting, add a tracking token before a file extension, or place a generated clause at a boundary identified by an earlier parser. Because existing text is preserved, this tool differs from replacement: there is no search term to match and no selected range to remove.
It is best when your workflow already knows the intended character boundary. Validate that boundary whenever upstream content can change, since adding or removing characters before it will shift the correct position. For reusable templates, stable markers are often easier to maintain than hard-coded offsets; once a marker has been located, its index can be passed here for the actual insertion.
Empty insertion text is accepted as a deliberate no-op, which can simplify conditional pipelines without special branching. The function is deterministic and uses no network, randomness, or current time, so identical inputs always return identical outputs.
What you can do with it
Complete a text template
Insert a customer name, reference number, or generated phrase at a known character boundary while preserving the surrounding template exactly.
Add a filename suffix
Place a version or language marker immediately before a file extension after another step determines the extension position.
Apply precise content edits
Add punctuation, annotations, separators, or missing words to generated content without searching for and replacing existing text.
FAQ
Is the position zero-based or one-based?
It is zero-based. Position 0 inserts before the first character, and a position equal to the original character length appends at the end.
Does insertion replace any existing text?
No. Every original character is preserved, and the chosen string is added at the requested boundary.
How are emoji counted?
Positions and lengths use Unicode code points, so a supplementary emoji is counted as one code point rather than two UTF-16 code units. Complex displayed symbols may contain multiple code points.
Can I insert at the beginning or end?
Yes. Use position 0 to prepend text or use the original character length to append it.
What happens if the position is past the end of the text?
The insertion is rejected instead of being quietly moved, so an edit never lands in the wrong place. Valid positions run from 0 up to the length of the text, and using the length itself appends at the end.
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/str/insert-at-position \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello world","insert_text":"beautiful ","position":6}'const res = await fetch("https://api.kit.forhosting.com/str/insert-at-position", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Hello world",
"insert_text": "beautiful ",
"position": 6
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/insert-at-position",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Hello world",
"insert_text": "beautiful ",
"position": 6
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/insert-at-position", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Hello world","insert_text":"beautiful ","position":6}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Hello world","insert_text":"beautiful ","position":6}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/insert-at-position", 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 world",
"insert_text": "beautiful ",
"position": 6
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.insert_at_position",
"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
Choose the exact insertion point
When selecting a position programmatically, remember that the permitted range includes both endpoints, from zero through the character length.
Build precise templates and editing workflows
Browser use is available for interactive edits, while API automation costs $0.002 per request.
Technical questions
What happens when the position is invalid?
A negative, fractional, or out-of-range position returns an invalid_input error instead of changing or clamping the value.