Documentation

Everything you need to convert one document or ten thousand.

Local: CLI and desktop app

Nothing leaves your machine. No account, no network, no AI.

pip install tablewise
tablewise report.pdf                    # -> ~/md-repo/report.md
tablewise budget.xlsx -o ./md-repo      # choose the output folder
tablewise contract.docx -n "Contract"   # choose the output name
tablewise scan.pdf --dry-run            # print the engine command only
tablewise report.pdf --force            # overwrite an existing .md
FlagMeaning
-o, --salidaOutput folder (default ~/md-repo).
-n, --nombreOutput name, without extension.
--forceOverwrite an existing .md.
--dry-runPrint the engine command, convert nothing.
--pythonInterpreter that carries the engines (or TABLEWISE_PYTHON).
--markitdownMarkItDown executable (or TABLEWISE_MARKITDOWN).
-q, --quietOnly errors.

Exit codes: 0 ok, 1 the engine produced no file, 2 invalid input. The desktop app is python tablewise_app.py.

Hosted API

Base URL: https://api.tablewise.dev. Every request needs Authorization: Bearer $TABLEWISE_API_KEY.

Get a key

curl -X POST https://api.tablewise.dev/v1/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"you@company.com"}'

The key is returned once. Free plan: 50 units a month.

Convert a document

curl -X POST https://api.tablewise.dev/v1/convert \
  -H "Authorization: Bearer $TABLEWISE_API_KEY" \
  -F "file=@budget.xlsx" \
  -F "mode=fidelity"

mode is fidelity (default, own engines) or fast (MarkItDown). Response:

{
  "markdown": "---\nsource: \"budget.xlsx\"\nengine: \"excel\"\nconverted: 2026-10-22\n---\n\n...",
  "engine": "excel",
  "units": 1,
  "usage": {"units_used": 1, "units_limit": 50, "period": "2026-10"}
}

Python

import os
import requests

r = requests.post(
    "https://api.tablewise.dev/v1/convert",
    headers={"Authorization": f"Bearer {os.environ['TABLEWISE_API_KEY']}"},
    files={"file": ("budget.xlsx", open("budget.xlsx", "rb"))},
    data={"mode": "fidelity"},
    timeout=120,
)
r.raise_for_status()
open("budget.md", "w").write(r.json()["markdown"])

Node

const fs = require("fs");
const form = new FormData();
form.append("file", new Blob([fs.readFileSync("budget.xlsx")]), "budget.xlsx");
form.append("mode", "fidelity");

const res = await fetch("https://api.tablewise.dev/v1/convert", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.TABLEWISE_API_KEY}` },
  body: form,
});
const data = await res.json();
fs.writeFileSync("budget.md", data.markdown);

Usage and quota

curl https://api.tablewise.dev/v1/me \
  -H "Authorization: Bearer $TABLEWISE_API_KEY"
{"email":"you@company.com","plan":"free","period":"2026-10",
 "units_used":12,"units_limit":50,"units_left":38,"resets_at":"2026-11-01T00:00:00+00:00"}

Batch (Pro and Business)

curl -X POST https://api.tablewise.dev/v1/batch \
  -H "Authorization: Bearer $TABLEWISE_API_KEY" \
  -F "files=@jan.xlsx" -F "files=@feb.xlsx" -F "files=@mar.xlsx"

Up to 100 files per call. Each one is charged independently: a bad file returns its own error and refunds its units, the rest still convert.

{"results": [
  {"filename": "jan.xlsx", "markdown": "...", "engine": "excel", "units": 1},
  {"filename": "feb.xlsx", "error": {"code": "unsupported_type", "message": "..."}}
], "usage": {"units_used": 12, "units_limit": 5000, "period": "2026-10"}}

Upgrade

curl -X POST https://api.tablewise.dev/v1/billing/checkout \
  -H "Authorization: Bearer $TABLEWISE_API_KEY"

Returns {"checkout_url": "https://checkout.stripe.com/..."}. The new plan is active as soon as Stripe confirms the payment.

Manage or cancel your subscription

curl -X POST https://api.tablewise.dev/v1/billing/portal \
  -H "Authorization: Bearer $TABLEWISE_API_KEY"

Returns a Stripe-hosted page where the customer updates the card or cancels. Cancelling downgrades the key to the free plan when the paid period ends.

Errors

StatusCodeWhen
400invalid_email, bad_mode, bad_signatureMalformed input.
401missing_key, invalid_keyNo key or unknown key.
402quota_exceededNot enough units left this month.
413too_large, document_too_bigOver 25 MB or 2,000 units.
415unsupported_typeExtension not supported.
422 / 500conversion_failed, office_lock_fileEngine error (units refunded).
429rate_limitedToo many requests per minute.
503billing_disabled, engine_unavailableFeature not configured or engine missing.
504timeoutEngine exceeded the time limit (units refunded).

Supported formats

The provenance header

Every output starts with exactly three keys. source is the file name only, never the path: a path leaks folder structure and adds nothing to a retrieval system.

---
source: "2026-budget.xlsx"
engine: "excel"
converted: 2026-10-22
---

Stable, parseable, and cheap to filter: engine = excel is the set of files whose tables you can trust most.

Limits