humantone
Official Ruby SDK for the HumanTone API. Rewrites AI-generated text into natural-sounding prose. Adds an AI Likelihood Indicator that scores how AI-like any text reads.
Install
Add to your Gemfile:
gem "humantone", "~> 0.0.1"
Then bundle install.
Or directly: gem install humantone.
Requires Ruby 3.3 or later. Zero runtime dependencies (uses stdlib net/http).
Quickstart
require "humantone"
client = HumanTone::Client.new(api_key: ENV.fetch("HUMANTONE_API_KEY"))
result = client.humanize(
text: "Your AI-generated draft goes here. At least 30 words for the API to accept it."
)
puts result.text
puts "Credits used: #{result.credits_used}"
The client also picks up HUMANTONE_API_KEY from the environment automatically:
client = HumanTone::Client.new
API
client.humanize(text:, level:, output_format:, custom_instructions:)
| Argument | Type | Default | Notes |
|---|---|---|---|
text: |
String |
required | Min 30 words. Max depends on plan (Basic 750, Standard 1000, Pro 1500). |
level: |
`:standard \ | :advanced \ | :extreme` |
output_format: |
`:text \ | :html \ | :markdown` |
custom_instructions: |
String or nil |
nil |
Free-form rewrite guidance. Max 1000 chars. |
Returns HumanTone::HumanizeResult Data with #text, #output_format, #credits_used, #request_id.
client.detect(text:)
Returns DetectResult with #ai_score (0-100 integer). Free, but limited to 30 calls per day per account.
client.account.get
info = client.account.get
puts info.plan.name
puts info.credits.total
puts info.subscription.expires_at # Time or nil
Configuration
client = HumanTone::Client.new(
api_key: "ht_...", # or HUMANTONE_API_KEY env
base_url: "https://api.humantone.io", # or HUMANTONE_BASE_URL env, default
timeout: 120, # 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
)
Error handling
All errors inherit from HumanTone::Error.
begin
result = client.humanize(text: "...")
rescue HumanTone::InsufficientCreditsError
puts "Buy more credits at https://app.humantone.io/settings/credits"
rescue HumanTone::RateLimitError => e
puts "Rate limited. Retry in #{e.retry_after_seconds}s."
rescue HumanTone::AuthenticationError
puts "Check your API key."
rescue HumanTone::Error => e
puts "HumanTone error (#{e.error_code}): #{e.}"
puts "Request ID: #{e.request_id}" if e.request_id
end
Error classes:
AuthenticationError,PermissionError,RateLimitErrorInsufficientCreditsError,DailyLimitExceededErrorInvalidRequestError,NotFoundErrorAPIError,TimeoutError,NetworkError
Common methods on every error:
#message,#status_code,#request_id,#error_code,#details,#retryable?
Specific accessors: RateLimitError#retry_after_seconds: Integer, DailyLimitExceededError#time_to_next_renew: Integer | nil, InsufficientCreditsError#required_credits and #available_credits.
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.
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/
- RubyGems: https://rubygems.org/gems/humantone
- Issues: https://github.com/humantone/humantone-ruby/issues
- Support: help@humantone.io