Line Deduplicator
text.deduplicate_lines
Overview
Removes duplicate lines from text using exact or normalized comparison. Supports case-insensitive matching, Unicode normalization, keep-first or keep-last policy, and configurable line endings. Reports removed lines with details. Accepts file input via file_ref — no need to extract file content first.
Agents frequently produce or collect lists with duplicates. We give you deterministic, policy-driven deduplication across encodings and normalization forms.
Reliability
STRICT and deterministic — identical inputs with the same mode, keep, caseSensitive, and normalization settings always produce identical output. TEXT_INVALID_ENCODING — trigger: you set requireNormalized and your text is not already NFC, so exact matching could miss canonically equal lines; retryable: yes, once the text is normalized; next: run text.normalize_unicode with form NFC and call us again. A normalization value we do not recognise quietly falls back to NFC instead of failing. Input validation (not retryable): a mode, keep, or lineEnding outside the listed values; neither text nor file_ref; both text and file_ref; text longer than 1,048,576 characters.
Context footprint
Accepts inline text up to ~1M chars or file_ref (up to 2 MB). Output exceeding 100 KB is stored as a downloadable file automatically. Upload files via POST /v1/files/upload before passing file_ref. A successful call costs 1 execution credit.
When to use it
When you need exact duplicate-line removal with control over matching, ordering, case sensitivity, and normalization.
Do not use when duplicates are approximate, semantically similar, or within a single line — this skill operates line-by-line only.
Scope
Non-goals
- Does not deduplicate tokens within a single line
- Does not merge similar or fuzzy-matched lines
- Does not perform semantic deduplication
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
File limits
Constraints this skill applies to your input and generated files. The “Limited by” column shows the static source of each cap; none of these can be raised by upgrading your plan.
| Limit | Value | Limited by |
|---|---|---|
| Maximum size per input file | 1.9 MiB | Skill maximum |
How we handle your data
What this means
This skill may receive sensitive content and may return submitted, transformed, extracted, or reformatted content.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response may contain submitted or transformed content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| text | string | No | Bounded inline text source. Required unless file_ref is provided. |
| file_ref | string | No | Tenant-scoped opaque text-file reference. Omit it to use the required inline text; never send both. |
| mode | string | No | Comparison mode; omit it for exact. |
| normalization | string | No | Unicode normalization; omit it for none. |
| keep | string | No | Duplicate retention policy; omit it for first. |
| caseSensitive | boolean | No | Whether comparison is case-sensitive; omit it for true. |
| lineEnding | string | No | Output line ending; omit it for LF. |
| requireNormalized | boolean | No | Whether non-normalized input is refused; omit it for false. |
| outputToFile | boolean | No | Whether a large result is stored as a file; omit it for false. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| text | string | No | Deduplicated inline text when returned inline. |
| file_ref | string | No | Stored deduplicated-text reference when returned by file. |
| download_url | string | No | Temporary platform download URL when returned by file. |
| size_bytes | integer | No | Returned UTF-8 byte size. |
| totalLines | integer | Yes | Original logical-line count. |
| keptLines | integer | Yes | Returned logical-line count. |
| removedCount | integer | Yes | Removed duplicate-line count. |
| mode | string | Yes | Applied comparison mode. |
| keep | string | Yes | Applied retention policy. |
| removedDetails | array | No | Bounded array of removed-line receipts with source index and retained-line details. The item shape is defined by the nested schema and the array contains from 0 through 2000000 items. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"text.deduplicate_lines","input":{"text":"apple\nbanana\napple\ncherry","mode":"exact","keep":"first"}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("text.deduplicate_lines", {"text":"apple\nbanana\napple\ncherry"});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
| TEXT_INVALID_ENCODING | 400 | No | The request payload failed this skill's input validation. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- Does not deduplicate tokens within a single line
- Does not merge similar or fuzzy-matched lines
- Does not perform semantic deduplication
- Fuzzy or semantic deduplication
- Within-line token deduplication
- Merging lines that differ only by formatting you have not normalized
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "text.deduplicate_lines",
"input": {
"text": "apple\nbanana\napple\ncherry"
}
}Examples
Exact dedup keeping first occurrence
{
"text": "apple\nbanana\napple\ncherry"
}{
"text": "apple\nbanana\ncherry",
"removedCount": 1,
"keep": "first",
"removedDetails": [
{
"line": 3,
"duplicateOf": 1,
"content": "apple"
}
],
"keptLines": 3,
"totalLines": 4,
"mode": "exact"
}Case-insensitive exact dedup
{
"caseSensitive": false,
"text": "Apple\napple\nBANANA"
}{
"text": "Apple\nBANANA",
"removedCount": 1,
"keep": "first",
"removedDetails": [
{
"line": 2,
"duplicateOf": 1,
"content": "apple"
}
],
"keptLines": 2,
"totalLines": 3,
"mode": "exact"
}Recommended use cases
- Clean up log files with repeated entries
- Deduplicate exported lists or CSV-like text
- Remove redundant lines from generated or scraped content
Avoid for
- Fuzzy or semantic deduplication
- Within-line token deduplication
- Merging lines that differ only by formatting you have not normalized
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.