humantone-sdk
Official Python SDK for HumanTone. Humanize AI-generated text and check AI likelihood from your Python code. One API key, same credits you already use in the HumanTone web app.
Install
pip install humantone-sdk
For the async client (uses httpx):
pip install "humantone-sdk[async]"
Requires Python 3.10 or later.
Quickstart
import os
from humantone import HumanTone
client = HumanTone(api_key=os.environ["HUMANTONE_API_KEY"])
result = client.humanize(
text="Your AI-generated draft goes here. Must be at least 30 words for the API to accept it.",
)
print(result.text)
print(f"Credits used: {result.credits_used}")
The client also picks up HUMANTONE_API_KEY from the environment automatically:
client = HumanTone()
API
client.humanize(text, *, level, output_format, custom_instructions)
Rewrites AI-generated text to sound more natural.
| Argument | Type | Default | Notes |
|---|---|---|---|
text |
str |
required | Min 30 words. Max depends on plan (Basic 750, Standard 1000, Pro 1500). |
level |
HumanizationLevel or "standard" | "advanced" | "extreme" |
"standard" |
advanced and extreme are English-only. |
output_format |
OutputFormat or "text" | "html" | "markdown" |
"text" |
SDK default is "text" even though the API default is "html". |
custom_instructions |
str | None |
None |
Free-form rewrite guidance. Max 1000 chars. |
Returns HumanizeResult with text: str, output_format: OutputFormat, credits_used: int, request_id: str | None.
client.detect(text)
Returns AI likelihood score 0-100. Free, but limited to 30 calls per day per account (shared between the web app and the API).
score = client.detect(text="...")
print(score.ai_score) # 0-100
client.account.get()
Returns plan, credit balance, and subscription status.
info = client.account.get()
print(info.plan.name)
print(info.credits.total)
print(info.plan.max_words)
print(info.subscription.active)
print(info.subscription.expires_at) # datetime | None
Configuration
client = HumanTone(
api_key="ht_...", # or HUMANTONE_API_KEY env
base_url="https://api.humantone.io", # or HUMANTONE_BASE_URL env, default is api.humantone.io
timeout=120.0, # seconds
max_retries=2,
retry_on_post=False, # POST endpoints retry only when explicit
user_agent="my-app/1.0", # appended to default UA after a single space
)
You can inject any requests.Session-compatible HTTP client:
import requests
from humantone import HumanTone
session = requests.Session()
session.proxies = {"https": "http://proxy.internal:8080"}
client = HumanTone(api_key="ht_...", http_client=session)
Error handling
All errors raised by the SDK extend HumanToneError.
from humantone import (
HumanTone,
HumanToneError,
InsufficientCreditsError,
DailyLimitExceededError,
InvalidRequestError,
AuthenticationError,
RateLimitError,
)
client = HumanTone()
try:
result = client.humanize(text="...")
except InsufficientCreditsError:
print("Buy more credits at https://app.humantone.io/settings/credits")
except RateLimitError as e:
print(f"Rate limited. Retry in {e.retry_after_seconds}s.")
except InvalidRequestError as e:
print(f"Bad input: {e}")
except AuthenticationError:
print("Check your API key.")
except HumanToneError as e:
print(f"HumanTone API error ({e.error_code}): {e}")
if e.request_id:
print(f"Request ID: {e.request_id}")
Every error exposes:
e.message: str(usestr(e))e.status_code: int | Nonee.request_id: str | Nonee.error_code: str | Nonee.details: dict | Nonee.retryable: bool
Specific exceptions add typed accessors: RateLimitError.retry_after_seconds: int, DailyLimitExceededError.time_to_next_renew: int | None, InsufficientCreditsError.required_credits: int | None and available_credits: int | None.
Python's stdlib has a builtin
TimeoutError. The SDK'shumantone.TimeoutErrorshadows it inside thehumantonenamespace. Usefrom humantone import TimeoutError as HumanToneTimeoutErrorif you need to disambiguate.
Retry behavior
The SDK retries account.get() on network errors, 5xx, and 429 (up to 2 retries). POST methods (humanize, detect) do not retry on network or 5xx by default. Humanize debits credits, so a retried request risks double-billing. Pass retry_on_post=True to opt in. 429 always retries on every method.
Retry-After headers are honored in both numeric (seconds) and HTTP-date formats.
Async usage
import asyncio
from humantone import AsyncHumanTone
async def main():
async with AsyncHumanTone() as client:
result = await client.humanize(text="...")
print(result.text)
asyncio.run(main())
The async client uses httpx and is exposed via pip install "humantone-sdk[async]".
Limits to remember
- Per-request word limit. Basic 750, Standard 1000, Pro 1500. Inputs must be at least 30 words.
- Credits. Humanize consumes 1 credit per 100 words. Account checks and AI likelihood checks do not consume credits.
- AI likelihood quota. 30 checks per day per account, shared between the HumanTone web app and any API or SDK usage. Resets at midnight UTC.
- API access. Included on all paid plans. Free trial accounts cannot use the API.
Get an API key
Sign up at humantone.io. The HumanTone API is paid only.
License
MIT
Links
- API docs: https://humantone.io/docs/api/
- MCP server: https://humantone.io/docs/mcp/
- Issues: https://github.com/humantone/humantone-python/issues
- Support: help@humantone.io
Metadata
Release files for humantone-sdk 0.0.1.post1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| humantone_sdk-0.0.1.post1.tar.gz | 17.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| humantone_sdk-0.0.1.post1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.7 kB
Release files / humantone_sdk-0.0.1.post1.tar.gz
| Download URL | humantone_sdk-0.0.1.post1.tar.gz |
|---|---|
| Size | 17.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
180b0687ba5f76e211b2f85dea17db372eeed2686ada33c9483f8a42e6b2c97b
|
|
BLAKE2b-256 checksum How to use checksums |
5e8ec9f5a5d8bb8101d0b496c7125b65d8e784e8a19c3083bc323e78bd89a434
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 4, 2026.
Transparency logRelease files / humantone_sdk-0.0.1.post1-py3-none-any.whl
| Download URL | humantone_sdk-0.0.1.post1-py3-none-any.whl |
|---|---|
| Size | 23.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9a9ca97ca21d2327315a65cde2627b53fd0bc03a42193b11ff5761335d32f41e
|
|
BLAKE2b-256 checksum How to use checksums |
cb500e68676646a829e425ba023729e308e8f1d04ff71cddbd512330ab03dd4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 4, 2026.
Transparency log