API
Tools HTTP API
Every browser tool is also a JSON endpoint. No API key, no signup — POST a body, get the same result the page computes. Free, rate-limited per IP.
API
Every browser tool is also a JSON endpoint. No API key, no signup — POST a body, get the same result the page computes. Free, rate-limited per IP.
Send a POST to /api/v1/tools/<slug> with a JSON body. The response is the same ToolResult envelope the browser tools return: { ok, output, meta?, error?, code? }. No authentication is required. Requests are rate-limited to 30 per minute per IP, with a 2 MB body cap. The legacy path /api/tools/<slug> still works as an alias.
Want a machine-readable index? GET /api/tools returns every endpoint, its params, and example bodies. An OpenAPI 3.1 spec is also available for import into Postman, Swagger, or codegen tools.
curl -X POST https://data-migration-tools.com/api/v1/tools/convert \
-H "Content-Type: application/json" \
-d '{"from":"csv","to":"json","input":"id,name\n1,Ada\n2,Grace"}'
{
"ok": true,
"output": {
"text": "[\n { \"id\": 1, \"name\": \"Ada\" },\n { \"id\": 2, \"name\": \"Grace\" }\n]",
"rows": 2,
"steps": ["csvToJson"]
},
"meta": { "rows": 2, "format": "json" }
}
Every endpoint below accepts POST with a JSON body and returns a ToolResult. Click an endpoint to see its full parameter reference.
| Endpoint | What it does | Params |
|---|---|---|
POST /api/v1/tools/convert |
Convert text between CSV, JSON, XML, YAML, and SQL by pivoting through JSON when no direct converter exists. | 7 params |
POST /api/v1/tools/base64 |
Encode a string to Base64 or decode Base64 back to text. Supports URL-safe (RFC 4648 §5) and PEM-style line-wrap on encode. | 5 params |
POST /api/v1/tools/jwt-decode |
Decode a JWT header and payload, describe registered claims, and report expiry status. Optionally verify an HS256 signature. | 2 params |
POST /api/v1/tools/cron |
Parse a 5-field cron expression (or @-macro), describe it in English, and compute the next N run times. | 3 params |
POST /api/v1/tools/regex-test |
Test a JavaScript regex against a subject string. Returns all matches (capped at 10,000) with groups, named groups, and timing. | 3 params |
POST /api/v1/tools/pii-scan |
Scan CSV, JSON, or plain text for PII (emails, phones, SSNs, cards, IPs, IBANs, passports, URLs, names) with GDPR/CCPA risk flags. | 5 params |
POST /api/v1/tools/pii-mask |
Replace PII with shape-valid, deterministic fake values so masked exports still join and load. The real→fake mapping is returned separately. | 4 params |
POST /api/v1/tools/csv-validate |
Validate CSV structure: duplicate headers, ragged rows, type inference, and per-column null/unique stats. | 1 param |
POST /api/v1/tools/data-clean |
Trim whitespace, drop empty rows and columns, normalize line endings, and rename duplicate headers in a CSV. | 6 params |
POST /api/v1/tools/schema-map |
Suggest field mappings between a source and target schema by name and type similarity. | 3 params |
POST /api/v1/tools/migration-validate |
Reconcile source and target CSVs by a key column: matched count, only-in-source, only-in-target, and per-field diffs. | 5 params |
POST /api/v1/tools/vendor-evaluate |
Score vendors against weighted criteria. Each category holds criteria scored 0-10 per vendor; the weighted sum is normalized to a 0-100 score with an A-F grade. | 2 params |
POST /api/v1/tools/roi-calculate |
Compute a 36-month cost-of-inaction vs migration NPV. Compares keeping the legacy stack (license + labor + data-error risk) against migrating to a new SaaS, with an overlap period and retained legacy cost. | 10 params |
POST /api/v1/tools/data-profile |
Profile CSV or JSON data: per-column type inference (Numeric/Date/Text/Mixed/Empty), unique and missing counts, and top 50 values. | 2 params |
POST /api/v1/tools/helpdesk-evaluate |
Rank 23 helpdesk plans against required features. Returns a match score (0-100), missing features, annual cost, and per-category coverage for each plan. | 5 params |
POST /api/v1/tools/helpdesk-plan |
Estimate a helpdesk migration timeline: split entities into API vs manual tasks, compute throughput based on platform rate limits, and assess risk. | 8 params |
GET /api/tools |
Machine-readable index of every endpoint, its params, and example bodies. | — |
GET /api/openapi.json |
OpenAPI 3.1 spec for import into Postman, Swagger, or codegen. | — |
/api/v1/tools/convertConvert text between CSV, JSON, XML, YAML, and SQL by pivoting through JSON when no direct converter exists.
Returns: The converted text, the row count from the last step that reported one, and the converter chain that ran.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
from |
string (csv|json|xml|yaml|sql) | Yes | — | Source format. |
to |
string (csv|json|xml|yaml|sql) | Yes | — | Target format. |
input |
string | Yes | — | The text to convert, in the source format. |
autoTypes |
boolean | No | true |
Infer number/boolean/null types when parsing CSV rather than treating every cell as a string. |
dialect |
string (mysql|postgres|sqlserver|sqlite) | No | — | SQL dialect for CSV-to-SQL output. Ignored for other target formats. |
table |
string | No | "data" |
Table name for CSV-to-SQL INSERT statements. Ignored for other target formats. |
rootElement |
string | No | "root" |
Root XML element name for JSON-to-XML output. Ignored for other target formats. |
curl -X POST https://data-migration-tools.com/api/v1/tools/convert \
-H "Content-Type: application/json" \
-d '{"from":"csv","to":"json","input":"id,name\n1,Ada\n2,Grace"}'
CSV to PostgreSQL INSERT statements.
curl -X POST https://data-migration-tools.com/api/v1/tools/convert \
-H "Content-Type: application/json" \
-d '{"from":"csv","to":"sql","input":"id,name\n1,Ada","dialect":"postgres","table":"users"}'
JSON to XML with a custom root element.
curl -X POST https://data-migration-tools.com/api/v1/tools/convert \
-H "Content-Type: application/json" \
-d '{"from":"json","to":"xml","input":"{\"user\":{\"name\":\"Ada\"}}","rootElement":"user"}'
/api/v1/tools/base64Encode a string to Base64 or decode Base64 back to text. Supports URL-safe (RFC 4648 §5) and PEM-style line-wrap on encode.
Returns: The encoded or decoded Base64 string, plus the byte count of the input.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
action |
string (encode|decode) | Yes | — | Whether to encode or decode. |
input |
string | Yes | — | The text to encode, or the Base64 string to decode. |
urlSafe |
boolean | No | false |
Produce (or accept) the URL-safe alphabet with - and _ instead of + and /. |
lineWrap |
boolean | No | false |
On encode, wrap output into lines of lineWrapWidth characters (PEM-style). |
lineWrapWidth |
number | No | 76 |
Line width when lineWrap is true. Default 76 (RFC 1421). |
curl -X POST https://data-migration-tools.com/api/v1/tools/base64 \
-H "Content-Type: application/json" \
-d '{"action":"encode","input":"hello world","urlSafe":true}'
PEM-style wrapped output.
curl -X POST https://data-migration-tools.com/api/v1/tools/base64 \
-H "Content-Type: application/json" \
-d '{"action":"encode","input":"a long payload...","lineWrap":true,"lineWrapWidth":64}'
/api/v1/tools/jwt-decodeDecode a JWT header and payload, describe registered claims, and report expiry status. Optionally verify an HS256 signature.
Returns: The decoded header and payload, registered-claim descriptions, expiry status, and (when verified) the signature check result.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
token |
string | Yes | — | The JWT (three Base64URL segments separated by dots). |
verify.secret |
string | No | — | Shared secret for HS256 signature verification. Omit to skip verification. |
curl -X POST https://data-migration-tools.com/api/v1/tools/jwt-decode \
-H "Content-Type: application/json" \
-d '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkYSIsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"}'
Verify an HS256 signature against a shared secret.
curl -X POST https://data-migration-tools.com/api/v1/tools/jwt-decode \
-H "Content-Type: application/json" \
-d '{"token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c","verify":{"secret":"shh"}}'
/api/v1/tools/cronParse a 5-field cron expression (or @-macro), describe it in English, and compute the next N run times.
Returns: A plain-English description of the schedule and the next run timestamps.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
expression |
string | Yes | — | A 5-field cron expression or an @-macro (@daily, @hourly, etc.). |
runs |
number | No | 5 |
How many next-run timestamps to return (1-100, default 5). |
from |
string | No | — | ISO 8601 reference time to compute next runs from. Defaults to now. |
curl -X POST https://data-migration-tools.com/api/v1/tools/cron \
-H "Content-Type: application/json" \
-d '{"expression":"0 9 * * 1-5","runs":5}'
Next runs from a fixed reference time.
curl -X POST https://data-migration-tools.com/api/v1/tools/cron \
-H "Content-Type: application/json" \
-d '{"expression":"@daily","from":"2026-01-01T00:00:00Z"}'
/api/v1/tools/regex-testTest a JavaScript regex against a subject string. Returns all matches (capped at 10,000) with groups, named groups, and timing.
Returns: The match count, an array of matches with captured and named groups, and the elapsed time in milliseconds.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
pattern |
string | Yes | — | The regex pattern (without surrounding slashes). |
flags |
string | No | — | Regex flags (e.g. "g", "i", "u"). Default empty. |
input |
string | Yes | — | The subject string to test against. |
curl -X POST https://data-migration-tools.com/api/v1/tools/regex-test \
-H "Content-Type: application/json" \
-d '{"pattern":"\\d+","flags":"g","input":"a1 b22 c333"}'
/api/v1/tools/pii-scanScan CSV, JSON, or plain text for PII (emails, phones, SSNs, cards, IPs, IBANs, passports, URLs, names) with GDPR/CCPA risk flags.
Returns: A roll-up of findings per entity/column, plus optionally the per-span detail array when detailed is true.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
input |
string | Yes | — | The data to scan. |
format |
string (csv|json|text) | No | "text" |
How to interpret the input. CSV and JSON scan per-field; text scans the whole string. |
entities |
string[] | No | — | Restrict detection to these entity types (e.g. ["EMAIL","SSN"]). Omit for all recognizers. |
detectNames |
boolean | No | — | Also test whether whole fields are person names. Defaults to true for CSV/JSON, false for text. |
detailed |
boolean | No | false |
Include the per-span detail array (offsets, values) alongside the roll-up. |
curl -X POST https://data-migration-tools.com/api/v1/tools/pii-scan \
-H "Content-Type: application/json" \
-d '{"input":"contact: ada@example.com, +1 555-123-4567","format":"text"}'
CSV scan with per-span detail.
curl -X POST https://data-migration-tools.com/api/v1/tools/pii-scan \
-H "Content-Type: application/json" \
-d '{"input":"email,phone\nada@example.com,+15551234567","format":"csv","detailed":true}'
/api/v1/tools/pii-maskReplace PII with shape-valid, deterministic fake values so masked exports still join and load. The real→fake mapping is returned separately.
Returns: The masked output, the real→fake entity mapping, and a count of masked values per entity.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
input |
string | Yes | — | The data to mask. |
format |
string (csv|json|text) | No | "text" |
How to interpret the input. |
entities |
string[] | No | — | Restrict masking to these entity types. Valid: EMAIL, SSN, CREDIT_CARD, PHONE, IPV4, IBAN, URL, PERSON_NAME, PASSPORT, DOB. Defaults to EMAIL, SSN, CREDIT_CARD, PHONE, IPV4, IBAN, URL, PERSON_NAME. |
seed |
string | No | — | Deterministic seed for the pseudonymizer. Same seed + same input → same masked output. Defaults to "dmt". |
curl -X POST https://data-migration-tools.com/api/v1/tools/pii-mask \
-H "Content-Type: application/json" \
-d '{"input":"email,phone\nada@example.com,+15551234567","format":"csv","seed":"run-42"}'
/api/v1/tools/csv-validateValidate CSV structure: duplicate headers, ragged rows, type inference, and per-column null/unique stats.
Returns: A validity flag, a list of structural issues, and per-column statistics (type, nulls, unique count).
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
input |
string | Yes | — | The CSV to validate. |
curl -X POST https://data-migration-tools.com/api/v1/tools/csv-validate \
-H "Content-Type: application/json" \
-d '{"input":"id,name\n1,Ada\n2,Grace\n3,"}'
/api/v1/tools/data-cleanTrim whitespace, drop empty rows and columns, normalize line endings, and rename duplicate headers in a CSV.
Returns: The cleaned CSV text and a summary of what was changed.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
input |
string | Yes | — | The CSV to clean. |
options.trimWhitespace |
boolean | No | true |
Trim leading/trailing whitespace in every cell. |
options.dropEmptyRows |
boolean | No | true |
Drop rows where every cell is empty. |
options.dropEmptyColumns |
boolean | No | true |
Drop columns where every cell is empty. |
options.normalizeLineEndings |
boolean | No | true |
Normalize CRLF/CR to LF. |
options.deduplicateHeaders |
boolean | No | true |
Rename duplicate header names (the second "id" becomes "id_2"). Set false to keep the names exactly as they appear in the file. Does not deduplicate rows. |
curl -X POST https://data-migration-tools.com/api/v1/tools/data-clean \
-H "Content-Type: application/json" \
-d '{"input":"id,name\n1,Ada\n1,Ada\n2,"}'
Rename the duplicate header.
curl -X POST https://data-migration-tools.com/api/v1/tools/data-clean \
-H "Content-Type: application/json" \
-d '{"input":"id,id\n1,2","options":{"deduplicateHeaders":true}}'
/api/v1/tools/schema-mapSuggest field mappings between a source and target schema by name and type similarity.
Returns: An array of matches per source field: the target field, a 0-1 score, and the match method (exact/fuzzy/skip).
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
sourceFields |
object[] | Yes | — | Source schema fields, each { name, type }. |
targetFields |
object[] | Yes | — | Target schema fields, each { name, type }. |
threshold |
number | No | 0.4 |
Minimum 0-1 score for a match to be accepted. Lower returns more (weaker) matches. |
curl -X POST https://data-migration-tools.com/api/v1/tools/schema-map \
-H "Content-Type: application/json" \
-d '{"sourceFields":[{"name":"email","type":"string"},{"name":"phone","type":"string"}],"targetFields":[{"name":"email_address","type":"text"},{"name":"mobile","type":"text"}]}'
/api/v1/tools/migration-validateReconcile source and target CSVs by a key column: matched count, only-in-source, only-in-target, and per-field diffs.
Returns: Matched/only-in-source/only-in-target counts, and a per-field diff of mismatched values.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
source |
string | Yes | — | The source CSV text. |
target |
string | Yes | — | The target CSV text. |
srcKey |
string | No | — | Column name to use as the key in the source. Defaults to the first header. |
tgtKey |
string | No | — | Column name to use as the key in the target. Defaults to the first header. |
mode |
string (trim|smart) | No | — | Comparison mode: trim (whitespace-insensitive) or smart (also normalize case/quotes). |
curl -X POST https://data-migration-tools.com/api/v1/tools/migration-validate \
-H "Content-Type: application/json" \
-d '{"source":"id,name\n1,Ada\n2,Grace","target":"id,name\n1,Ada\n3,Mary"}'
/api/v1/tools/vendor-evaluateScore vendors against weighted criteria. Each category holds criteria scored 0-10 per vendor; the weighted sum is normalized to a 0-100 score with an A-F grade.
Returns: Per-vendor final score and grade, plus per-category averages for breakdown charts.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
vendors |
object[] | Yes | — | Array of { id, name, color? } objects (max 10). |
categories |
object[] | Yes | — | Array of { id, name, weight, criteria: [{ id, name, scores: { vendorId: number } }] }. |
curl -X POST https://data-migration-tools.com/api/v1/tools/vendor-evaluate \
-H "Content-Type: application/json" \
-d '{"vendors":[{"id":"v1","name":"Global IT"},{"id":"v2","name":"SaaS Co"}],"categories":[{"id":"security","name":"Security","weight":1.3,"criteria":[{"id":"enc","name":"Encryption","scores":{"v1":8,"v2":9}},{"id":"soc","name":"SOC 2","scores":{"v1":7,"v2":9}}]}]}'
/api/v1/tools/roi-calculateCompute a 36-month cost-of-inaction vs migration NPV. Compares keeping the legacy stack (license + labor + data-error risk) against migrating to a new SaaS, with an overlap period and retained legacy cost.
Returns: Per-month cumulative cost arrays for legacy and migration curves, NPV of each, net savings NPV, breakeven month, and cost composition percentages.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
rev |
number | Yes | — | Annual revenue. Used to size the data-error risk cost. |
leg |
number | Yes | — | Legacy monthly license cost. |
hours |
number | Yes | — | Maintenance hours per week. |
rate |
number | Yes | — | Hourly labor cost. |
err |
number | Yes | — | Data error impact as a percentage of revenue (e.g. 1.5 = 1.5%). |
mig |
number | Yes | — | One-time migration fee. |
newSaaS |
number | Yes | — | New SaaS monthly cost. |
dur |
number | Yes | — | Overlap duration in months (legacy + new SaaS run side by side). |
growth |
number | Yes | — | Annual data growth as a percentage (e.g. 10 = 10%). |
eff |
number | Yes | — | Operational efficiency as a percentage (e.g. 90 = 90% of labor eliminated). |
curl -X POST https://data-migration-tools.com/api/v1/tools/roi-calculate \
-H "Content-Type: application/json" \
-d '{"rev":5000000,"leg":4000,"hours":20,"rate":75,"err":1,"mig":25000,"newSaaS":1500,"dur":3,"growth":15,"eff":85}'
/api/v1/tools/data-profileProfile CSV or JSON data: per-column type inference (Numeric/Date/Text/Mixed/Empty), unique and missing counts, and top 50 values.
Returns: Per-column metadata (type, unique count, missing count, top values) and the total row count.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
input |
string | Yes | — | The data to profile. CSV text or a JSON array of objects. |
format |
string (csv|json) | No | "csv" |
How to interpret the input. |
curl -X POST https://data-migration-tools.com/api/v1/tools/data-profile \
-H "Content-Type: application/json" \
-d '{"input":"id,name,email\n1,Ada,ada@example.com\n2,Grace,grace@example.com","format":"csv"}'
curl -X POST https://data-migration-tools.com/api/v1/tools/data-profile \
-H "Content-Type: application/json" \
-d '{"input":"[{\"id\":1,\"name\":\"Ada\"},{\"id\":2,\"name\":\"Grace\"}]","format":"json"}'
/api/v1/tools/helpdesk-evaluateRank 23 helpdesk plans against required features. Returns a match score (0-100), missing features, annual cost, and per-category coverage for each plan.
Returns: An array of scored plans (match score, missing features, annual cost, category scores) and the total count.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
search |
string | No | — | Filter plans by brand name (case-insensitive substring). |
budget |
number | No | 200 |
Maximum cost per agent per month. Flat-fee plans always pass. |
teamSize |
number | No | 5 |
Number of agents, used to compute annual cost for per-agent plans. |
filters |
object | No | — | Object of feature-key → boolean. Only keys set to true are required. See the docs page for the full feature key list. |
sort |
string (match_desc|price_asc|price_desc|name) | No | "match_desc" |
Sort order for the results. |
Find plans that support email, generative drafts, and SSO.
curl -X POST https://data-migration-tools.com/api/v1/tools/helpdesk-evaluate \
-H "Content-Type: application/json" \
-d '{"filters":{"email":true,"ai_gen":true,"sec_sso":true},"teamSize":10,"sort":"match_desc"}'
/api/v1/tools/helpdesk-planEstimate a helpdesk migration timeline: split entities into API vs manual tasks, compute throughput based on platform rate limits, and assess risk.
Returns: Total/min/max duration in hours, a breakdown (foundation/core data/attachments), per-entity hours, the bottleneck platform, risk level, and API vs manual task lists.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
source |
string (zendesk|freshdesk|salesforce|hubspot|intercom|helpscout|jira|front|gladly|gorgias) | Yes | — | Source platform. |
sourcePlan |
string | Yes | — | Plan key on the source platform (e.g. "suite_growth"). |
destination |
string (zendesk|freshdesk|salesforce|hubspot|intercom|helpscout|jira|front|gladly|gorgias) | Yes | — | Destination platform. |
destPlan |
string | Yes | — | Plan key on the destination platform. |
selectedEntities |
string[] | Yes | — | Entities to migrate. Valid: tickets, users, organizations, groups, articles, macros, triggers, automations, tags, custom_fields, ticket_forms, sla_policies. |
volumes |
object | No | — | Record counts per entity, e.g. { "tickets": 50000, "users": 10000 }. |
avgAttachmentsPerTicket |
number | No | 0 |
Average attachments per ticket. |
avgAttachmentSizeMB |
number | No | 0 |
Average attachment size in MB. |
curl -X POST https://data-migration-tools.com/api/v1/tools/helpdesk-plan \
-H "Content-Type: application/json" \
-d '{"source":"zendesk","sourcePlan":"suite_growth","destination":"freshdesk","destPlan":"pro","selectedEntities":["tickets","users","organizations"],"volumes":{"tickets":50000,"users":10000},"avgAttachmentsPerTicket":2,"avgAttachmentSizeMB":0.5}'
A failed request returns a non-2xx status with the same ToolResult shape. The code field is the stable way to branch on the failure reason.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | EMPTY_INPUT | No input provided. |
| 400 | INVALID_INPUT | The input is present but malformed (bad regex, bad JWT, etc.). |
| 400 | UNSUPPORTED | The requested format or tool is not supported. |
| 400 | PARSE_ERROR | The input could not be parsed (invalid CSV, JSON, XML, YAML). |
| 408 | TIMEOUT | The regex engine timed out (likely catastrophic backtracking). |
| 413 | TOO_LARGE | The input exceeds the 2 MB body cap. (Browser tools accept up to 5 MB — try the page if your input is just over.) |
| 429 | RATE_LIMIT | Too many requests from this IP in the last minute. See Retry-After and X-RateLimit-* headers. |
| 503 | DEPENDENCY_MISSING | A required parser is unavailable. |
| 500 | INTERNAL | An unexpected error — please report it with the X-Request-Id header. |
Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (Unix seconds), and X-Request-Id for log correlation. A 429 response also includes Retry-After (seconds until the window resets).
The API is free and runs on the Cloudflare Workers free tier. There is no paid subscription required to use it. The per-IP rate limit (30 req/min) and 2 MB body cap are the only ceilings. If you need higher limits for production use, contact us.