HTH Developer

Use HandyTechHelper from your own code.

The HTH API runs the same dependable text and data operations as the website: JSON formatting, encoding, hashing, cleanup and more. Send a request with your key and get a result back in milliseconds.

Keys you controlCreate up to five keys, see their usage and revoke any of them instantly.
Clear limitsPer-minute, per-day and monthly credit limits are enforced on our server and shown in your account.
Private by designNo file uploads, no remote fetching and no code execution. Job contents expire after an hour.

Quick start

  1. Get Pro or Pro Max. The API is included with both.
  2. In your account’s Developer section, create an API key and copy it. It is shown only once.
  3. Call the API:
curl https://handytechhelper.com/api/v1/transform \
  -H "Authorization: Bearer $HTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jobs":[{"operation":"json-format","input":"{\"hello\":\"world\"}"}]}'

The response contains one output string per job, in the same order, plus the credits the request used:

{"results":["{\n  \"hello\": \"world\"\n}"],"creditsUsed":1}

Field names in the response may gain additions over time; ignore fields you don’t use.

JavaScript

const response = await fetch('https://handytechhelper.com/api/v1/transform', {
  method: 'POST',
  headers: {Authorization: `Bearer ${process.env.HTH_API_KEY}`, 'Content-Type': 'application/json'},
  body: JSON.stringify({jobs: [{operation: 'sha256', input: 'Hope This Helps.'}]}),
});
if (!response.ok) throw new Error((await response.json()).error);
console.log(await response.json());

Python

import os, requests
r = requests.post("https://handytechhelper.com/api/v1/transform",
    headers={"Authorization": f"Bearer {os.environ['HTH_API_KEY']}"},
    json={"jobs": [{"operation": "text-upper", "input": "hello"}]}, timeout=10)
r.raise_for_status()
print(r.json())

Keys and scopes

Send your key in the Authorization header as Bearer hth_… on every request. Keys are stored only as hashes, so we can’t show a key again after you create it. Never put a key in browser code or a public repository. If a key leaks, revoke it in your account straight away.

Scopes

Each key has one or more scopes, chosen when you create it. Give each app only what it needs.

ScopeAllows
readGET /api/v1/status and GET /api/v1/entitlements
transformPOST /api/v1/transform
jobsPOST /api/v1/jobs and GET /api/v1/jobs

Rotation and expiry

Keys expire after 90 days. Click Rotate next to a key to get a replacement with the same name and scopes. The old key keeps working for 24 hours, so you can update your apps without downtime. Each key shows its request count and when it was last used. You can have up to 5 keys, plus retiring keys during a rotation (10 active at most).

Endpoints

Method and pathWhat it does
GET /api/v1/statusHealth check. Confirms your key works and returns the service version.
GET /api/v1/entitlementsYour plan, limits and remaining credits for this billing month.
POST /api/v1/transformRun up to your plan’s batch size of operations synchronously. Body: {"jobs":[{"operation":"…","input":"…"}]}.
POST /api/v1/jobsQueue the same kind of batch to run in the background. Returns a job ID.
GET /api/v1/jobs?id=…Check a queued job and read its results. Results expire after one hour.

Operations

OperationDescription
json-formatPretty-print JSON with two-space indentation
json-minifyRemove whitespace from JSON
text-upperConvert text to UPPER CASE
text-lowerConvert text to lower case
deduplicate-linesKeep the first copy of each line
sort-linesSort lines alphabetically
base64-encodeEncode UTF-8 text as Base64
base64-decodeDecode Base64 to UTF-8 text (strict)
url-encodePercent-encode a URL component
url-decodeDecode a percent-encoded component
sha256SHA-256 hex digest of the text
uuidGenerate a random UUID v4 (input ignored)

Each operation uses one credit. Inputs are plain text up to 8 KiB each and 64 KiB per request.

Plans and limits

PlanCredits per monthRequests per minuteRequests per dayItems per request
Pro10,0003050050
Pro Max50,000601,000100

Credits reset at the start of each billing period and don’t roll over. The site administrator may set lower temporary ceilings to protect the shared server; the effective limits are always reported by /api/v1/entitlements.

Errors

Errors return a JSON body like {"error":"A valid API key is required."} with one of these status codes:

StatusExample messageWhat to do
400Invalid requestThe JSON body is malformed, an operation is unknown, or an input breaks a limit. The message says which.
401A valid API key is required.The Authorization header is missing, mistyped, revoked or expired.
403An active Pro plan or Developer role is required.The key’s account has no current Pro or Pro Max membership, or the account is suspended or not fully verified. “This API key does not have the … scope” means the key wasn’t given that permission.
404API endpoint not found.Check the path and method.
409ConflictFor example, no credits are left this billing month.
413Request is too large.Bodies are limited to 64 KiB.
415Send JSON data.Set Content-Type: application/json on POST requests.
429Too many requestsA per-minute or per-day limit was reached. Wait for the Retry-After seconds, then retry.
503Temporarily unavailableThe service is busy or a dependency is offline. Retry with backoff.

See plansManage API keys