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.
Quick start
- Get Pro or Pro Max. The API is included with both.
- In your account’s Developer section, create an API key and copy it. It is shown only once.
- 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.
| Scope | Allows |
|---|---|
read | GET /api/v1/status and GET /api/v1/entitlements |
transform | POST /api/v1/transform |
jobs | POST /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 path | What it does |
|---|---|
GET /api/v1/status | Health check. Confirms your key works and returns the service version. |
GET /api/v1/entitlements | Your plan, limits and remaining credits for this billing month. |
POST /api/v1/transform | Run up to your plan’s batch size of operations synchronously. Body: {"jobs":[{"operation":"…","input":"…"}]}. |
POST /api/v1/jobs | Queue 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
| Operation | Description |
|---|---|
json-format | Pretty-print JSON with two-space indentation |
json-minify | Remove whitespace from JSON |
text-upper | Convert text to UPPER CASE |
text-lower | Convert text to lower case |
deduplicate-lines | Keep the first copy of each line |
sort-lines | Sort lines alphabetically |
base64-encode | Encode UTF-8 text as Base64 |
base64-decode | Decode Base64 to UTF-8 text (strict) |
url-encode | Percent-encode a URL component |
url-decode | Decode a percent-encoded component |
sha256 | SHA-256 hex digest of the text |
uuid | Generate 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
| Plan | Credits per month | Requests per minute | Requests per day | Items per request |
|---|---|---|---|---|
| Pro | 10,000 | 30 | 500 | 50 |
| Pro Max | 50,000 | 60 | 1,000 | 100 |
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:
| Status | Example message | What to do |
|---|---|---|
400 | Invalid request | The JSON body is malformed, an operation is unknown, or an input breaks a limit. The message says which. |
401 | A valid API key is required. | The Authorization header is missing, mistyped, revoked or expired. |
403 | An 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. |
404 | API endpoint not found. | Check the path and method. |
409 | Conflict | For example, no credits are left this billing month. |
413 | Request is too large. | Bodies are limited to 64 KiB. |
415 | Send JSON data. | Set Content-Type: application/json on POST requests. |
429 | Too many requests | A per-minute or per-day limit was reached. Wait for the Retry-After seconds, then retry. |
503 | Temporarily unavailable | The service is busy or a dependency is offline. Retry with backoff. |
