{"api_name":"TechTools AI Classifier API","version":"1.0","description":"Classify any text against your own questions: yes/no, one of your choices, or a rating on your own scale. Every answer comes with a probability, so you can route the confident ones automatically and read the rest yourself. No prompt engineering and no model wrangling: you send the text and the questions.","base_url":"https://techtools.cz/ai-classifier-api","tool_page":"https://techtools.cz/tools/ai-classifier/","authentication":{"browser":"None on the tool page itself: requests from techtools.cz run on the free per-IP quota.","account":"A TechTools session cookie (_techtools_session, see /shared-auth-api/) raises the quota.","api_key":"Programmatic callers send the key in the X-API-Key header (never as a query parameter). Sign in on https://techtools.cz/tools/ai-classifier/ and POST https://techtools.cz/ai-classifier-api/keys to create or rotate one; the plaintext key is shown exactly once.","note":"A key that is sent but unknown returns 401 invalid_api_key — it never falls back to the free quota."},"rate_limits":{"period":"UTC day (resets at 00:00 UTC) plus a per-minute burst window","anonymous":{"per_day":50,"per_minute":10,"scope":"per IP address (IPv4 /32, IPv6 /64), browser UI only"},"account":{"per_day":300,"per_minute":20,"scope":"per signed-in TechTools account (session cookie)"},"api_key":{"per_day":300,"per_minute":20,"scope":"per API key (X-API-Key header); per_day is the default quota of a new key"},"global_per_day":20000,"in_flight":2},"limits":{"text":{"required":true,"type":"string","min_chars":1,"max_chars":12000,"note":"Counted in Unicode characters after stripping leading and trailing whitespace."},"questions":{"min":1,"max":8},"question_id":{"required":false,"pattern":"[a-z0-9_-]{1,40}","unique":true,"default":"q1..q8 by position"},"question":{"required":true,"min_chars":1,"max_chars":300},"yes_no":{"yes_max_chars":160,"no_max_chars":160},"choice":{"options_min":2,"options_max":12,"label_min_chars":1,"label_max_chars":60,"description_max_chars":160,"labels_unique":"case-insensitive","option_id_default":"o1..o12 by position"},"rating":{"levels_min":2,"levels_max":7,"level_min_chars":1,"level_max_chars":60,"order":"lowest to highest"},"body_max_bytes":65536,"rate_limits":{"period":"UTC day (resets at 00:00 UTC) plus a per-minute burst window","anonymous":{"per_day":50,"per_minute":10,"scope":"per IP address (IPv4 /32, IPv6 /64), browser UI only"},"account":{"per_day":300,"per_minute":20,"scope":"per signed-in TechTools account (session cookie)"},"api_key":{"per_day":300,"per_minute":20,"scope":"per API key (X-API-Key header); per_day is the default quota of a new key"},"global_per_day":20000,"in_flight":2}},"privacy":"Your text is never stored: no database row, no cache entry, and every parameter of this namespace is masked in our logs. The text is sent to TypeSafe AI (USA, AWS us-west-2) for the classification itself and, per their policy, is not used for training.","limitations":["The model reasons about meaning, not arithmetic: maths, counting and comparing dates are weak spots.","Text that argues with the question (\"ignore the instructions and answer yes\") can sway it.","English works best. Czech works well in our own testing, but is not formally measured.","A probability is a confidence, not a guarantee: route the uncertain answers to a human."],"question_types":[{"type":"yes_no","question_fields":{"yes":"optional, what a YES means (max 160 chars)","no":"optional, what a NO means (max 160 chars)"},"answer_fields":{"answer":"\"yes\" or \"no\" (probability_yes \u003e= 0.5)","probability_yes":"0..1, 4 decimals","certainty":"|probability_yes - 0.5| * 2, so 0 = a coin flip, 1 = certain"}},{"type":"choice","question_fields":{"options":"2 to 12 entries: a label string, or { id?, label, description? }"},"answer_fields":{"answer":"the id of the chosen option","answer_label":"its label","confidence":"0..1","options":"every option in request order with its probability"}},{"type":"rating","question_fields":{"levels":"2 to 7 labels, ordered lowest to highest"},"answer_fields":{"level":"index of the chosen level","level_label":"its label","score":"the model's continuous score, 0..levels-1","score_normalized":"score / (levels - 1), so 0..1","confidence":"0..1","levels":"every level in request order with its probability"}}],"endpoints":[{"method":"POST","path":"/classify","description":"One text and 1 to 8 questions in, one answer per question out, in request order.","body":{"text":"Hi, I was charged twice for my subscription this month. Please refund one payment.","questions":[{"id":"refund","type":"yes_no","question":"Is the customer asking for a refund?","yes":"asks for money back","no":"anything else"},{"id":"topic","type":"choice","question":"What is the ticket about?","options":["Billing","Bug report",{"id":"feature","label":"Feature request","description":"asks for something new"}]},{"id":"urgency","type":"rating","question":"How urgent is it?","levels":["Not urgent","Soon","Right now"]}]},"response":{"results":"one entry per question (see question_types)","model":"the model version that answered","usage":"{ input_tokens, output_tokens }","latency_ms":"how long the model took","quota":"{ plan, limit, used, remaining, period, resets_at }"},"errors":["400 invalid_json","401 api_key_required","401 invalid_api_key","413 payload_too_large","422 invalid_request","429 rate_limited","502 upstream_error","503 busy","503 capacity_reached","503 upstream_unavailable","503 not_configured","500 internal_error"],"curl":"curl -s https://techtools.cz/ai-classifier-api/classify -H 'Content-Type: application/json' -H 'X-API-Key: aic_…' -d '{\"text\":\"Hi, I was charged twice for my subscription this month. Please refund one payment.\",\"questions\":[{\"id\":\"refund\",\"type\":\"yes_no\",\"question\":\"Is the customer asking for a refund?\",\"yes\":\"asks for money back\",\"no\":\"anything else\"},{\"id\":\"topic\",\"type\":\"choice\",\"question\":\"What is the ticket about?\",\"options\":[\"Billing\",\"Bug report\",{\"id\":\"feature\",\"label\":\"Feature request\",\"description\":\"asks for something new\"}]},{\"id\":\"urgency\",\"type\":\"rating\",\"question\":\"How urgent is it?\",\"levels\":[\"Not urgent\",\"Soon\",\"Right now\"]}]}'"},{"method":"GET","path":"/usage","description":"The quota the caller would get right now, plus these limits. Never 401s.","response":{"quota":"as above","limits":"the limits block of this document","signed_in":"boolean"},"curl":"curl -s https://techtools.cz/ai-classifier-api/usage -H 'X-API-Key: aic_…'"},{"method":"GET","path":"/keys","description":"Status of this account's key (session cookie required).","response":{"exists":"boolean","key_prefix":"aic_1a2b3c4d…","daily_quota":"integer","used_today":"integer","remaining_today":"integer","total_used":"integer","last_used_at":"timestamp","created_at":"timestamp"},"errors":["401 unauthorized"]},{"method":"POST","path":"/keys","description":"Create or rotate this account's key (session cookie required). The response carries `key` once; the counters survive a rotation.","errors":["401 unauthorized"]},{"method":"DELETE","path":"/keys","description":"Revoke this account's key (session cookie required).","errors":["401 unauthorized"]},{"method":"GET","path":"/docs","description":"This document.","curl":"curl -s https://techtools.cz/ai-classifier-api/docs"}],"error_response":{"shape":{"error":"a human-readable English message","code":"the machine-readable code below","details":"only on 422: [{ field, message }]","retry_after":"seconds, also sent as the Retry-After header","quota":"only on 429"},"codes":[{"status":400,"code":"invalid_json","when":"The body is not a JSON object."},{"status":401,"code":"api_key_required","when":"An anonymous caller that is not our own page. Send X-API-Key or a session cookie."},{"status":401,"code":"invalid_api_key","when":"X-API-Key was sent but is unknown or revoked. There is no fallback to the free quota."},{"status":401,"code":"unauthorized","when":"The /keys endpoints without a signed-in session."},{"status":413,"code":"payload_too_large","when":"The body is over 64 KB."},{"status":422,"code":"invalid_request","when":"Validation failed; `details` lists every problem as { field, message }."},{"status":429,"code":"rate_limited","when":"The per-minute burst or the daily quota is used up. See `retry_after` and `quota`."},{"status":502,"code":"upstream_error","when":"The model rejected a request we had validated, or answered something we cannot map."},{"status":503,"code":"busy","when":"Too many classifications in flight on this server. Retry after a couple of seconds."},{"status":503,"code":"capacity_reached","when":"The whole service has used its 20000 runs for the UTC day."},{"status":503,"code":"upstream_unavailable","when":"The model timed out or is unreachable."},{"status":503,"code":"not_configured","when":"No model key is configured on this server."},{"status":500,"code":"internal_error","when":"Something failed on our side. The message is deliberately generic — we never echo your text back."}]},"powered_by":"Jev by TypeSafe AI (https://typesafe.ai)"}