API reference

The same engines that run in the browser, exposed over HTTP for pipelines and back-office automation. Files sent to the API are processed in memory and discarded — nothing is written to disk.

Getting started

Create a key in your dashboard, then send it as a bearer token. The base URL is https://api.exceltoolkitpro.com. Every response includes rate-limit headers, and every mutating endpoint accepts an Idempotency-Key so retries are safe.

curl -X POST https://api.exceltoolkitpro.com/api/v1/convert \
  -H "Authorization: Bearer etk_live_9f2b7c..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -F "file=@report.xlsx" \
  -F "target=csv" \
  -o report.csv

Authentication

Session endpoints for the web app. Tokens are delivered as HttpOnly cookies; the access token lives 15 minutes and is refreshed silently from a 30-day refresh token scoped to the refresh path only.

POST/api/v1/auth/registerPublic

Create an account

Creates a user and sends a verification email. Passwords are hashed with bcrypt at cost 12. Rate limited to 5 attempts per hour per IP.

Request

{
  "email": "you@company.com",
  "password": "a-long-passphrase",
  "name": "Your Name"
}

Response

{
  "user": { "id": "usr_9f2b", "email": "you@company.com", "name": "Your Name", "emailVerified": false },
  "message": "Check your inbox to verify your address."
}

Errors

  • 409 EMAIL_IN_USEAn account with that email already exists.
  • 422 WEAK_PASSWORDPassword is under 12 characters or in a breach list.
POST/api/v1/auth/loginPublic

Sign in

Returns session cookies. If two-factor is enabled the response is 202 with a challenge id instead, and the client must call /auth/2fa/verify. Brute-force protection locks an account for 15 minutes after 5 failed attempts.

Request

{ "email": "you@company.com", "password": "a-long-passphrase" }

Response

{
  "user": { "id": "usr_9f2b", "email": "you@company.com", "role": "USER", "plan": "PRO" },
  "expiresIn": 900
}

Errors

  • 401 INVALID_CREDENTIALSEmail or password is wrong. Deliberately indistinguishable.
  • 423 ACCOUNT_LOCKEDToo many failed attempts. Retry after the lockout window.
POST/api/v1/auth/refreshPublic

Rotate the access token

Exchanges the refresh cookie for a new access token and rotates the refresh token. A reused refresh token invalidates the whole token family — the standard detection for a stolen token.

Response

{ "expiresIn": 900 }
POST/api/v1/auth/logoutSession

Sign out

Revokes the refresh token family and clears both cookies.

Response

204 No Content
GET/api/v1/auth/csrfPublic

Fetch a CSRF token

Returns a token and sets the paired cookie. Every state-changing request must send the token in the x-csrf-token header.

Response

{ "csrfToken": "3f9a…" }

Conversion

Server-side conversion for pipelines. Files are processed in memory and discarded immediately — nothing is written to disk. Requests are multipart/form-data; responses stream the converted file.

POST/api/v1/convertAPI key

Convert a spreadsheet

Accepts one file plus a target format. Supports xlsx, xls, ods, csv, tsv, json, xml and html in any sensible direction. Maximum 100 MB per request. Send an Idempotency-Key header to make retries safe.

Request

curl -X POST https://api.exceltoolkitpro.com/api/v1/convert \
  -H "Authorization: Bearer etk_live_..." \
  -H "Idempotency-Key: 6f1c2d84-2b1e-4a55-9a1e-1f0b9a2c33de" \
  -F "file=@report.xlsx" \
  -F "target=csv" \
  -F "delimiter=;" \
  -o report.csv

Response

Binary stream with:
Content-Type: text/csv; charset=utf-8
Content-Disposition: attachment; filename="report.csv"
X-Rows-Processed: 41823

Errors

  • 413 FILE_TOO_LARGEBody exceeds the plan limit.
  • 415 UNSUPPORTED_FORMATSource or target format is not supported.
  • 422 PARSE_FAILEDThe file could not be read. Often an encrypted workbook.
POST/api/v1/mergeAPI key

Merge multiple workbooks

Accepts 2-200 files. Columns are matched by header name; the response contains the union of all columns plus optional provenance columns.

Request

-F "files=@jan.xlsx" -F "files=@feb.xlsx" -F "mode=stack" -F "addSource=true"

Response

Binary .xlsx stream with X-Rows-Merged and X-Files-Merged headers.
POST/api/v1/cleanAPI key

Clean and deduplicate

Applies trimming, non-printing character removal, empty row removal and optional deduplication in a single pass.

Request

-F "file=@contacts.csv" -F "trim=true" -F "dedupeOn=email" -F "target=xlsx"

Response

Binary stream with X-Rows-Removed and X-Cells-Cleaned headers.
POST/api/v1/validateAPI key

Validate against rules

Returns a JSON violation report rather than a file. Rules are supplied as a JSON string in the rules field.

Request

-F "file=@orders.xlsx" \
-F 'rules=[{"column":"email","type":"email"},{"column":"total","type":"numeric","min":0}]'

Response

{
  "rowsChecked": 12480,
  "violations": [
    { "row": 47, "column": "email", "rule": "email", "value": "n/a", "detail": "Not a valid email address" }
  ],
  "passRate": 0.9994
}

AI

Backed by Claude. Only the payload you send is processed — send a schema and a few sample rows rather than a full dataset.

POST/api/v1/ai/askSession

Ask about a spreadsheet

Answers questions about a described spreadsheet structure. Usage is metered against the account plan; limits reset at midnight UTC.

Request

{
  "task": "assistant",
  "question": "Which region missed target last quarter?",
  "context": {
    "sheets": [{
      "name": "Sales",
      "columns": ["Date", "Region", "Rep", "Amount", "Target"],
      "rowCount": 4210,
      "sample": [["2025-01-04", "West", "A. Rahman", 4200, 5000]]
    }]
  }
}

Response

{
  "answer": "Use SUMIFS to compare actuals against target by region…",
  "model": "claude-opus-5",
  "usage": { "inputTokens": 412, "outputTokens": 338 }
}

Errors

  • 401 UNAUTHENTICATEDAI endpoints require a signed-in session.
  • 429 AI_QUOTA_EXCEEDEDDaily message allowance used. Resets at midnight UTC.

Account

Profile, API keys, usage and subscription state for the signed-in user.

GET/api/v1/meSession

Current user

Returns the profile, plan, usage counters and notification preferences.

Response

{
  "id": "usr_9f2b",
  "email": "you@company.com",
  "role": "USER",
  "plan": "PRO",
  "usage": { "aiMessagesToday": 3, "apiCallsThisMonth": 1204, "filesProcessed": 892 }
}
PATCH/api/v1/meSession

Update the profile

Updates name, locale, theme and notification preferences. Email changes require re-verification.

Request

{ "name": "New Name", "notifications": { "product": true, "marketing": false } }

Response

{ "id": "usr_9f2b", "name": "New Name" }
GET/api/v1/api-keysSession

List API keys

Returns key metadata. The secret is shown only once, at creation.

Response

{ "keys": [{ "id": "key_2c8", "name": "CI pipeline", "prefix": "etk_live_9f2b", "lastUsedAt": "2025-07-20T11:04:00Z" }] }
POST/api/v1/api-keysSession

Create an API key

Returns the full secret exactly once. Only a SHA-256 hash is stored server-side.

Request

{ "name": "CI pipeline", "scopes": ["convert", "merge"] }

Response

{ "id": "key_2c8", "secret": "etk_live_9f2b7c…", "warning": "Store this now — it is not retrievable." }
DELETE/api/v1/api-keys/:idSession

Revoke an API key

Revocation is immediate and irreversible.

Response

204 No Content

Admin

Restricted to ADMIN role. Every call is written to the audit log with actor, IP and payload digest.

GET/api/v1/admin/statsAdmin only

Platform statistics

Aggregate counts for the admin dashboard: users, subscriptions, revenue, tool usage and error rates.

Response

{
  "users": { "total": 341208, "activeLast30d": 88214, "newLast7d": 3910 },
  "revenue": { "mrr": 48210, "arr": 578520, "churnRate": 0.021 },
  "usage": { "filesProcessed30d": 1840221, "apiCalls30d": 942018 }
}
GET/api/v1/admin/usersAdmin only

List users

Paginated and filterable by plan, role and status. Never returns password hashes.

Response

{ "users": [...], "page": 1, "pageSize": 50, "total": 341208 }
GET/api/v1/admin/audit-logsAdmin only

Read the audit log

Immutable, append-only record of authentication and administrative actions. Exportable as CSV.

Response

{ "logs": [{ "id": "log_71a", "actorId": "usr_1", "action": "USER_ROLE_CHANGED", "ip": "203.0.113.4", "createdAt": "..." }] }

Rate limits

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. On a 429, respect the Retry-After header rather than retrying immediately.

API rate limits by plan
PlanMonthly quotaSustained rateBurst
FreeNo API access
Pro10,000 calls60 requests120
Business250,000 calls300 requests600