String Case
Convert between camel, snake, kebab, pascal, constant, title, and related cases. Input case is auto-detected. Use to=all to fetch all variants at once.
MCP tool: text.convert_string_case
GET /v1/string/case
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | string | ✓ | String to convert |
| to | string | ✓ | camel / snake / kebab / pascal / constant / title / lower / upper / all |
Request example:
curl "https://api.thousand-api.com/v1/string/case?text=hello_world_foo&to=camel" \
-H "x-api-key: YOUR_API_KEY"Response example:
{
"text": "hello_world_foo",
"to": "camel",
"detected_case": "snake",
"result": "helloWorldFoo"
}Response:
When to=all, result is an object keyed by case name. For strings containing non-ASCII characters (e.g. Japanese), only lower and upper are transformed; other cases return the input unchanged.
Random String
Generates cryptographically secure random strings. Configurable charset, length, and count. Uses Node.js built-in crypto.
MCP tool: text.generate_random_string
GET /v1/random/string
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| length | integer | - | String length (default: 16, max: 128) |
| charset | string | - | alphanumeric / alphabetic / numeric / hex / urlsafe / uppercase |
| count | integer | - | Number of strings to generate (default: 1, max: 10) |
Request example:
curl "https://api.thousand-api.com/v1/random/string?length=8&charset=uppercase&count=3" \
-H "x-api-key: YOUR_API_KEY"Response example:
{
"length": 8,
"charset": "uppercase",
"count": 3,
"results": ["AB3K7MN2", "PQ9XL4WZ", "R7MN2PQ9"]
}Response:
Generated strings are suitable for session tokens, temporary passwords, and invite codes. For production cryptographic keys, use purpose-appropriate key generation (e.g. crypto.generateKeyPair).
Text Stats
Extract plain text from HTML, return text statistics and approximate token counts, split long text into sentence/paragraph-aware chunks, mask PII (email, Japanese phone numbers, credit cards), compute line-based diffs and similarity scores, or generate URL-safe slugs from human-readable titles.
MCP tools: text.extract_text_from_html, text.get_text_stats, text.estimate_tokens, text.split_text, text.mask_pii, text.diff_text, text.diff_markdown_tables, text.calc_text_similarity, text.generate_slug
POST /v1/text/html-to-text
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| html | string | ✓ | HTML text to extract (max 1MB) |
| max_length | integer | - | Optional maximum character count for output (positive integer) |
| preserve_links | boolean | - | When true, return a list of { text, href } links (default false) |
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/html-to-text" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Hello</h1><p>Visit <a href=\"https://example.com\">Example</a></p>",
"max_length": 500,
"preserve_links": true
}'Response example:
{
"text": "Hello\n\nVisit Example",
"char_count": 19,
"truncated": false,
"links": [
{
"text": "Example",
"href": "https://example.com"
}
]
}Response fields:
| Parameter | Description |
|---|---|
| text | Plain text with tags removed, entities decoded, and whitespace normalized |
| char_count | Character count of text |
| truncated | True when max_length truncated the output |
| links | Present only when preserve_links is true; array of { text, href } |
Response:
script and style tags (including their contents) are removed entirely. Block elements (p, div, h1–h6, li, etc.) become line breaks; three or more consecutive newlines are compressed to two. Useful for reducing tokens from HTML fetched via the Scraper tool.
POST /v1/text/stats
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | string | ✓ | Text to analyze (max 100KB) |
| lang | string | - | Language code (ja / en, default en) |
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/stats" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "AI agents need reliable MCP utilities.",
"lang": "en"
}'Response example:
{
"characters": 42,
"characters_no_spaces": 37,
"words": 7,
"sentences": 1,
"paragraphs": 1,
"reading_time_seconds": 2
}Response fields:
| Parameter | Description |
|---|---|
| characters | Total character count (includes spaces and newlines) |
| characters_no_spaces | Character count excluding spaces, tabs, and newlines |
| words | Word count (ja: non-whitespace characters; en: space-separated tokens) |
| sentences | Sentence count (ja: 。!?; en: .!?) |
| paragraphs | Paragraph count (split on blank lines) |
| reading_time_seconds | Estimated reading time in seconds (rounded up) |
Response:
Reading speed: ja uses 500 characters/min (characters_no_spaces); en uses 225 words/min (words). No external APIs required.
POST /v1/text/estimate-tokens
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | string | ✓ | Text to estimate token count for (max 1MB) |
| model_hint | string | - | Model hint (claude / gpt / generic, default generic) |
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/estimate-tokens" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Check token usage before sending long HTML or documents to an LLM.",
"model_hint": "generic"
}'Response example:
{
"char_count": 62,
"estimated_tokens": 16,
"model_hint": "generic",
"method": "approximation",
"breakdown": {
"ascii_chars": 58,
"japanese_chars": 0,
"other_chars": 4
},
"note": "This is an approximation. Actual token count may vary by ±15%."
}Response fields:
| Parameter | Description |
|---|---|
| char_count | Total character count |
| estimated_tokens | Approximate token count (rounded up) |
| model_hint | Model hint used for the estimate |
| method | Always approximation |
| breakdown.ascii_chars | ASCII alphanumeric character count |
| breakdown.japanese_chars | Hiragana, katakana, and kanji character count |
| breakdown.other_chars | Symbols, spaces, newlines, and other characters |
| note | Disclaimer that the result is approximate (±15%) |
Response:
Ideal for saving tokens—check consumption before passing HTML or long documents to an LLM. No external libraries (e.g. tiktoken).
POST /v1/text/split
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | string | ✓ | Text to split into chunks (max 1MB). An empty string returns chunk_count: 0 |
| max_chars | integer | ✓ | Maximum characters per chunk, counted in Unicode code points (integer >= 1) |
| overlap | integer | - | Characters repeated from the end of the previous chunk (0 <= overlap < max_chars, default 0) |
| boundary | string | - | Split unit (sentence / paragraph / char, default sentence). Oversized units fall back to finer boundaries (paragraph → sentence → char) |
Example 1: boundary "sentence" (sentence boundaries, default)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/split" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "First sentence. Second one! Third?",
"max_chars": 20,
"boundary": "sentence"
}'Response example:
{
"chunk_count": 2,
"chunks": [
{ "index": 0, "text": "First sentence. ", "char_count": 16 },
{ "index": 1, "text": "Second one! Third?", "char_count": 18 }
]
}Example 2: boundary "paragraph" (blank-line separated)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/split" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Intro paragraph.\n\nMain body text here.\n\nSummary.",
"max_chars": 25,
"boundary": "paragraph"
}'Response example:
{
"chunk_count": 3,
"chunks": [
{ "index": 0, "text": "Intro paragraph.\n\n", "char_count": 18 },
{ "index": 1, "text": "Main body text here.\n\n", "char_count": 22 },
{ "index": 2, "text": "Summary.", "char_count": 8 }
]
}Example 3: boundary "char" (fixed-size slices)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/split" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "abcdefghij",
"max_chars": 4,
"boundary": "char"
}'Response example:
{
"chunk_count": 3,
"chunks": [
{ "index": 0, "text": "abcd", "char_count": 4 },
{ "index": 1, "text": "efgh", "char_count": 4 },
{ "index": 2, "text": "ij", "char_count": 2 }
]
}Example 4: overlap to preserve context between chunks (for RAG)
For RAG chunking, set overlap so each chunk starts with the tail of the previous chunk. This prevents context loss when a single chunk is retrieved by vector search.
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/split" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "The quick brown fox. Jumps over the dog.",
"max_chars": 25,
"overlap": 5,
"boundary": "sentence"
}'Response example:
{
"chunk_count": 2,
"chunks": [
{ "index": 0, "text": "The quick brown fox. ", "char_count": 21 },
{ "index": 1, "text": "fox. Jumps over the dog.", "char_count": 24 }
]
}Response fields:
| Parameter | Description |
|---|---|
| chunk_count | Number of chunks |
| chunks[].index | Zero-based chunk index |
| chunks[].text | Chunk text |
| chunks[].char_count | Character count in Unicode code points (an emoji counts as 1) |
Response:
Use it to fit long text into LLM context windows, to pre-process documents for RAG chunking, or to split text for summarization/translation while preserving sentence and paragraph meaning. Combine with text.estimate_tokens to size chunks by token budget (character-based sizing only for now). MCP tool: text.split_text
POST /v1/text/mask-pii
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | string | ✓ | Text to scan and mask (max 50,000 characters) |
| types | string[] | - | PII types to detect (email / phone_jp / credit_card). Defaults to all when omitted |
| mask_char | string | - | Single character used for masking (default *. Surrogate pairs are not allowed) |
Masking format (fixed)
| Parameter | Description |
|---|---|
| ****@****.{TLD} (local part and first domain label are always 4 mask chars regardless of length; intermediate subdomains are dropped, only the TLD remains. Example: taro.yamada@mail.example.co.jp → ****@****.jp). Fixed length is intentional so masked output does not leak the original length | |
| phone_jp | Keep the leading block and last 4 digits; replace the middle with **** (always 4 chars). Examples: 090-1234-5678 → 090-****-5678, 03-1234-5678 → 03-****-5678 |
| credit_card | Candidates of 13–19 digits are Luhn-validated; only valid cards are masked. Separators are preserved and only the last 4 digits remain. Example: 4111-1111-1111-1111 → ****-****-****-1111 |
Example 1: Email and phone masking
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/mask-pii" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Contact: taro.yamada@mail.example.co.jp / TEL: 090-1234-5678"
}'Response example:
{
"masked_text": "Contact: ****@****.jp / TEL: 090-****-5678",
"detected": [
{ "type": "email", "count": 1 },
{ "type": "phone_jp", "count": 1 }
]
}Example 2: Credit cards (Luhn-valid only)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/mask-pii" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "CARD: 4111-1111-1111-1111 / INVALID: 4111-1111-1111-1112",
"types": ["credit_card"]
}'Response example:
{
"masked_text": "CARD: ****-****-****-1111 / INVALID: 4111-1111-1111-1112",
"detected": [
{ "type": "credit_card", "count": 1 }
]
}Response fields:
| Parameter | Description |
|---|---|
| masked_text | Text after PII masking |
| detected | Per-type detection counts (types with count 0 are omitted) |
| detected[].type | email / phone_jp / credit_card |
| detected[].count | Number of matches masked for that type |
Response:
Processing order is email → credit_card → phone_jp (to avoid treating card digit runs as phone numbers). No external APIs. MCP tool: text.mask_pii
POST /v1/text/diff
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| original | string | ✓ | Original text to compare (max 256KB) |
| modified | string | ✓ | Modified text to compare against (max 256KB) |
| context_lines | integer | - | Context lines around changes (0–10, default 3) |
| format | string | - | Output format (unified / json, default unified) |
Example: format "unified" (unified diff string)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/diff" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"original": "line1\nline2\nline3\n",
"modified": "line1\nline3\nline4\n",
"context_lines": 3,
"format": "unified"
}'Response example:
{
"diff": "===================================================================\n@@ -1,3 +1,3 @@\n line1\n-line2\n line3\n+line4\n",
"added_lines": 1,
"removed_lines": 1,
"has_changes": true
}Example: format "json" (structured chunks)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/diff" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"original": "alpha\nbeta\n",
"modified": "alpha\ngamma\n",
"format": "json"
}'Response example:
{
"diff": [
{ "type": "unchanged", "lines": ["alpha"] },
{ "type": "removed", "lines": ["beta"] },
{ "type": "added", "lines": ["gamma"] }
],
"added_lines": 1,
"removed_lines": 1,
"has_changes": true
}Response fields:
| Parameter | Description |
|---|---|
| diff | Unified diff string when format is unified (--- / +++ header lines removed), or an array of { type, lines } when format is json |
| added_lines | Number of lines added |
| removed_lines | Number of lines removed |
| has_changes | True when any line was added or removed |
Response:
Line-based diff. Useful for code review, comparing AI-generated text to the original, and summarizing document revisions. MCP tool: text.diff_text
POST /v1/text/diff-table
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| before | string | ✓ | Original Markdown table string (max 100KB) |
| after | string | ✓ | Modified Markdown table string (max 100KB) |
| key_column | string | number | - | Column name or zero-based index used as row identity key. When omitted, the first column name from the before table is used; rows are matched by cell values in that column. For numeric index, the column name at that index in before or after headers is resolved. Specify explicitly when column names differ between tables. |
Example 1: DB schema change detection (key_column: "ID")
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/diff-table" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"before": "| ID | 名前 | 型 |\n|---|---|---|\n| 1 | id | bigint |\n| 2 | name | int |\n| 3 | email | varchar(255) |",
"after": "| ID | 名前 | 型 | NULL許容 |\n|---|---|---|---|\n| 1 | id | bigint | NO |\n| 2 | name | bigint | NO |\n| 4 | created_at | datetime | NO |",
"key_column": "ID"
}'Response example:
{
"headers": {
"before": ["ID", "名前", "型"],
"after": ["ID", "名前", "型", "NULL許容"]
},
"added_columns": ["NULL許容"],
"removed_columns": [],
"rows": {
"added": [{ "ID": "4", "名前": "created_at", "型": "datetime", "NULL許容": "NO" }],
"removed": [{ "ID": "3", "名前": "email", "型": "varchar(255)" }],
"changed": [{
"key": "2",
"changes": [{ "column": "型", "before": "int", "after": "bigint" }]
}],
"unchanged_count": 1
},
"has_changes": true
}Example 2: key_column omitted (first column ID as key; non-key header rename only)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/diff-table" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"before": "| ID | Label |\n|---|---|\n| 1 | alpha |\n| 2 | beta |",
"after": "| ID | Name |\n|---|---|\n| 1 | alpha |\n| 2 | gamma |"
}'Response example:
{
"headers": {
"before": ["ID", "Label"],
"after": ["ID", "Name"]
},
"added_columns": ["Name"],
"removed_columns": ["Label"],
"rows": {
"added": [],
"removed": [],
"changed": [],
"unchanged_count": 2
},
"has_changes": true
}Response fields:
| Parameter | Description |
|---|---|
| headers.before / headers.after | Column header arrays for each table |
| added_columns | Column names present only in after |
| removed_columns | Column names present only in before |
| rows.added | Rows present only in after (no matching key in before) |
| rows.removed | Rows present only in before |
| rows.changed | Rows in both tables with differing values in common columns. key is the key-column value; changes is an array of { column, before, after } |
| rows.unchanged_count | Rows with matching keys and identical values in all common columns |
| has_changes | True when columns were added/removed, rows were added/removed, or any cell changed |
text.diff_text compares Markdown tables as plain line-level text (pipe and cell boundary edits appear as line diffs). This API parses GFM tables and returns structured column, row, and cell-level changes. Use text.diff_markdown_tables for DB schemas and spec tables; use text.diff_text for prose and full document diffs.
Response:
Structured diff for GFM Markdown tables. Useful for DB schema and design doc reviews. MCP tool: text.diff_markdown_tables
POST /v1/text/similarity
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text1 | string | ✓ | First text to compare (max 10,000 characters) |
| text2 | string | ✓ | Second text to compare against (max 10,000 characters) |
| algorithms | string[] | - | Algorithms to run (levenshtein / jaro_winkler / jaccard; default: all three) |
Response fields:
| Parameter | Description |
|---|---|
| levenshtein | Character-level edit distance. Best for typos and misspellings |
| jaro_winkler | Emphasizes prefix matches. Best for names and company deduplication |
| jaccard | Token-set overlap ratio. Best for document content similarity |
Example 1: Company name matching
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/similarity" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text1": "株式会社千代田",
"text2": "(株)千代田"
}'Response example:
{
"text1_length": 7,
"text2_length": 6,
"levenshtein": { "distance": 4, "similarity": 0.4286 },
"jaro_winkler": { "similarity": 0.746 },
"jaccard": { "similarity": 0.2222 }
}Example 2: Document duplicate check
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/similarity" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text1": "AIエージェントに確実性を与えるMCPサーバー。リアルタイムデータと副作用を扱います。",
"text2": "AIエージェントに確実性を与えるMCPサーバー。為替・祝日などのリアルタイムデータを扱います。"
}'Response example:
{
"text1_length": 43,
"text2_length": 47,
"levenshtein": { "distance": 12, "similarity": 0.7447 },
"jaro_winkler": { "similarity": 0.9474 },
"jaccard": { "similarity": 0.3333 }
}Response fields:
| Parameter | Description |
|---|---|
| text1_length | Character length of text1 |
| text2_length | Character length of text2 |
| levenshtein.distance | Edit distance (number of operations) |
| levenshtein.similarity | Similarity score from 0 to 1 (4 decimal places) |
| jaro_winkler.similarity | Jaro-Winkler similarity from 0 to 1 (4 decimal places) |
| jaccard.similarity | Jaccard coefficient from 0 to 1 (4 decimal places) |
text.diff_text returns where texts differ (line-based diff). This API returns how similar they are as numeric scores. Use text.calc_text_similarity for duplicate detection and threshold matching; use text.diff_text to inspect changed sections. Combining both gives similarity and change locations.
Response:
No external APIs. Deterministic: the same input always yields the same result. MCP tool: text.calc_text_similarity
POST /v1/text/slugify
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | string | ✓ | Text to slugify (max 1000 characters) |
| locale | string | - | ja (default): romanize Japanese with Hepburn before slugify; en and others: skip romanization |
| separator | string | - | Word separator (- / _ / ., default -) |
| max_length | integer | - | Maximum slug length (1–200) |
| lowercase | boolean | - | Lowercase the slug (default true) |
text.convert_string_case (GET /v1/string/case) converts existing ASCII identifiers between camel, snake, kebab, and similar cases; Japanese only supports lower/upper. This API targets URL paths, document IDs, and navigation keys from human-readable titles, romanizing Japanese when locale is ja via kuromoji + kuroshiro before normalization.
MCP tool: text.generate_slug
Example 1: Japanese title (locale: ja)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/slugify" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Thousand API — 祝日カレンダー機能",
"locale": "ja"
}'Response example:
{
"input": "Thousand API — 祝日カレンダー機能",
"slug": "thousand-api-shukujitsu-karendaa-kinou",
"truncated": false,
"char_replaced": ["—"]
}Example 2: English text (locale: en)
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/slugify" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Hello World! This is a Test.",
"locale": "en"
}'Response example:
{
"input": "Hello World! This is a Test.",
"slug": "hello-world-this-is-a-test",
"truncated": false,
"char_replaced": ["!", "."]
}Example 3: separator and max_length
Request example:
curl -X POST "https://api.thousand-api.com/v1/text/slugify" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "My Long Document Title Here And More",
"locale": "en",
"separator": "_",
"max_length": 30
}'Response example:
{
"input": "My Long Document Title Here And More",
"slug": "my_long_document_title_here",
"truncated": true,
"char_replaced": []
}Response fields:
| Parameter | Description |
|---|---|
| input | The request text echoed back |
| slug | Generated URL-safe slug |
| truncated | True when max_length truncated the slug |
| char_replaced | Characters removed or replaced (unique, order of first appearance) |
Response:
Japanese processing uses the same Lambda as /v1/ja/convert (kuromoji dictionary). The first request after a cold start may take several seconds.
Japanese Text Conversion
Convert Japanese text to hiragana, katakana, or romaji. Uses kuromoji morphological analysis for accurate conversion of proper nouns.
MCP tool: text.convert_japanese
GET /v1/ja/convert
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | string | ✓ | Japanese text to convert (max 1000 characters) |
| to | string | ✓ | hiragana / katakana / romaji |
Request example:
curl "https://api.thousand-api.com/v1/ja/convert?text=%E6%9D%B1%E4%BA%AC%E9%83%BD%E6%B8%8B%E8%B0%B7%E5%8C%BA&to=hiragana" \
-H "x-api-key: YOUR_API_KEY"Response example:
{
"text": "東京都渋谷区",
"to": "hiragana",
"result": "とうきょうとしぶやく"
}