ForHosting KIT · Developer Utilities

Check If Text Contains a Substring and Find Its Position

This text contains checker gives you a direct answer to a common validation question: does one piece of text include the substring you expect?

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

It returns a boolean result and the zero-based position of the first match, or -1 when no match exists. You can preserve exact letter casing or ignore uppercase and lowercase differences. The result is deterministic, easy to test, and useful anywhere a workflow needs a quick search condition without regular expressions or fuzzy matching.

Check a substring with an unambiguous result

Provide the complete value in text and the sequence you want to locate in substring. The response includes contains, which is true when a match exists, and position, which identifies where the first match begins. Positions are zero-based, so a substring found at the very beginning has position 0. A missing substring produces false and position -1, keeping absence distinct from a match at the start. This pairing makes the result convenient for people reading it and for software applying a condition. The operation looks for a literal, contiguous substring. Spaces, punctuation, and repeated characters are treated as ordinary text rather than patterns, so symbols do not need regular-expression escaping. If the same substring occurs several times, only the first position is reported. That behavior is particularly useful for validation, where the main questions are whether an expected marker appears and where parsing could begin. An empty substring is rejected because every string technically contains it, which would provide a surprising and unhelpful validation result.

Choose whether letter case matters

The case_sensitive option defaults to true. In that mode, uppercase and lowercase letters must match exactly: searching for “Ready” does not match “ready.” Exact matching is appropriate for identifiers, protocol markers, product codes, and any content where capitalization carries meaning. Set the option to false when you want a practical text check that treats those variants alike, such as finding a status word in user-entered notes or checking whether a heading contains a phrase. Case-insensitive mode normalizes both the source text and requested substring consistently before locating the first occurrence, while the reported position still refers to the original text. The capability does not trim either value or alter punctuation, so leading spaces and punctuation remain meaningful. It also does not perform accent folding, stemming, transliteration, fuzzy comparison, or whole-word detection. For example, a search for “cat” can match the first three letters of “catalog.” Keeping these rules narrow makes every result repeatable and prevents a simple contains check from silently making linguistic assumptions that would be unsuitable for identifiers or automated gates.

Use the position safely in validation workflows

A typical workflow sends a candidate value, checks contains, and branches without having to interpret the numeric field. When a match exists, position can support diagnostics, previews, or a later parsing step. For example, an import check can confirm that a header includes a required token and record where it begins; a test can verify that generated copy contains an approved phrase; or a support tool can detect a known marker in a pasted log line. Always treat the returned position as a JavaScript string index, measured in UTF-16 code units. For ordinary Latin text this aligns with familiar character counting, but some emoji and less common Unicode symbols occupy two code units. The capability deliberately returns the platform-native index so browser and API executions remain identical and callers can use it directly with JavaScript slicing methods. This is a literal search rather than a security sanitizer or content classifier. Validate structure separately when accepting markup, commands, or other sensitive formats, and use a dedicated parser when boundaries, escaping rules, or multiple matches matter to the decision.

Validate generated text

Confirm that a generated message includes a required disclosure or approved phrase before it is published.

Check import markers

Verify that a pasted header or record contains an expected token and report where parsing can begin.

Test labels and status messages

Assert that application output contains a known label, with exact or case-insensitive matching as needed.

What does the result contain?

It returns whether a match exists, the zero-based position of the first match, and the case-sensitivity setting used.

What position is returned when there is no match?

The position is -1 and contains is false. A match at the beginning instead returns position 0.

Is matching case-sensitive by default?

Yes. Set case_sensitive to false when uppercase and lowercase variants should be treated alike.

Does the substring support regular expressions?

No. It is treated as literal text, so punctuation and symbols have no pattern syntax.

Can I search for an empty substring?

No. Empty substrings are rejected because their universal match behavior is rarely useful for validation.

How much does an API request cost?

Each API request costs $0.002. The same deterministic logic can also run in the browser client.

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.

POSThttps://api.kit.forhosting.com/str/contains

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.

curl -X POST https://api.kit.forhosting.com/str/contains \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Release candidate passed validation.","substring":"passed"}'
{
  "text": "Release candidate passed validation.",
  "substring": "passed"
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "str.contains",
  "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.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Read the full KIT documentation →