ITS-AI Python SDK
Typed, ergonomic Python client for the ITS-AI API with sync and async interfaces, robust error mapping, attempts, and helpful docs.
- Sync and async clients:
ItsAIClient(requests) andAsyncItsAIClient(httpx) - Strongly-typed results via dataclasses
- Attempts on 5xx and rate limits, with exponential backoff and
Retry-Aftersupport - Rich, typed error hierarchy mapped from API
typeand HTTP status - Safe logging with masked API keys
Installation
pip install its-ai
Quick start
Single text analysis
from its_ai import ItsAIClient, AnalyzeTextResult
client = ItsAIClient(api_key="api_key")
try:
result: AnalyzeTextResult = client.analyze_text("Your English text here.")
print(result.answer)
finally:
client.close()
With deep scan:
with ItsAIClient(api_key="api_key") as client:
result = client.analyze_text("Your English text here.", deep_scan=True)
print(result.answer, result.segmentation_tokens)
Batch analysis
from its_ai import ItsAIClient, AnalyzeBatchItemResult
texts = [
"Short text", # might trigger LowWords
"A sufficiently long English text ...",
]
with ItsAIClient(api_key="api_key") as client:
items: list[AnalyzeBatchItemResult] = client.analyze_batch(texts, deep_scan=False)
for item in items:
print(item.text, item.answer)
Chunking large batches automatically:
with ItsAIClient(api_key="api_key") as client:
results = client.analyze_batch(texts, max_batch_size=50)
Plagiarism
A plagiarism check costs twice the words of an AI scan of the same text and can take
minutes, so it uses its own generous timeout (PLAGIARISM_TIMEOUT) and is not
retried — a retry cannot resume the abandoned scan, it starts a second one that is
billed again. Pass timeout only to go higher.
with ItsAIClient(api_key="api_key") as client:
result = client.check_plagiarism("Your text here.")
print(result.score) # 0.0 original – 1.0 fully copied
for source in result.results:
print(source.score, source.link, source.title)
for match in source.matches: # the fragments that matched this source
print(match.match_score, match.text_sentence, match.link)
Grammar & style
Unlike AI detection, the grammar endpoints are multilingual and accept short texts (from 20 characters). There is no score — the result is the list of issues.
with ItsAIClient(api_key="api_key") as client:
result = client.check_grammar("She go to school every day.")
print(result.language, result.stats.errors)
for match in result.matches:
print(match.severity, match.message, match.replacements)
# Several texts at once — a failing text carries `error` instead of matches
for item in client.check_grammar_batch(["First text ...", "Second text ..."]):
print(item.error or item.stats.total)
report_id opens the web report, but the PDF certificate covers AI and plagiarism only —
downloading it for a grammar-only scan returns 404.
PDF certificate
Every AI and plagiarism scan returns a report_id you can exchange for the PDF certificate.
The endpoint takes no API key — the report_id is the secret — so the link is shareable.
with ItsAIClient(api_key="api_key") as client:
result = client.analyze_text_v2("Your text here ...")
pdf = client.download_report(result.report_id, lang="fr", tz="Europe/Paris")
open("certificate.pdf", "wb").write(pdf)
lang and tz are optional (English / UTC by default). An unknown report_id, or one from
a grammar-only check, raises NotFound.
Async usage
import asyncio
from its_ai import AsyncItsAIClient
async def main():
async with AsyncItsAIClient(api_key="api_key") as client:
res = await client.analyze_text("hello world", deep_scan=True)
print(res)
asyncio.run(main())
Errors and attempts
The client raises typed exceptions derived from ItsAIError based on the API error type and HTTP status. Common ones include:
ValidationError,AuthenticationFailed,PermissionDenied,NotFound,NotAcceptable- Domain errors:
LowWords,ManyWords,OnlyEnglish,RateLimitExceeded, etc. - Transport failures:
RequestTimeout,NetworkError
API errors arrive as <type>:<code> (e.g. validation:low_words, server:server) and are
matched on both halves, so an unfamiliar code still lands on its category's class rather than
on the bare ItsAIError.
Idempotent POSTs are retried up to 3 times on 5xx and on a rate limit, with exponential backoff and Retry-After respected. A rate limit arrives as HTTP 400 with code validation:rate_limit (not 429) and is raised as RateLimitExceeded; every other 4xx is final. Plagiarism checks are never retried — see below.
from its_ai import ItsAIClient, LowWords, ManyWords, OnlyEnglish, AuthenticationFailed
try:
with ItsAIClient() as client: # reads ITS_AI_API_KEY from env by default
client.analyze_text("too short")
except LowWords as e:
print("Text too short:", e.message)
except ManyWords:
print("Text too long")
except OnlyEnglish:
print("Only English is supported")
except AuthenticationFailed:
print("Invalid/absent API key")
Configuration
api_key: string, required (defaults fromITS_AI_API_KEY)base_url: defaults tohttps://api.its-ai.org(trailing slashes trimmed)timeout: default 10s (override per-call viatimeout=)max_attempts: default 3 (5xx and rate limits)max_batch_size(batch-only): optional chunking of input texts
Headers are set automatically: User-Agent: its-ai-python-sdk/<version>, Accept: application/json, Content-Type: application/json.
Logging
The package uses Python's logging under the logger name its_ai. Enable DEBUG to see request URLs, status codes, and trimmed payloads. The api_key is masked.
import logging
logging.basicConfig(level=logging.DEBUG)
Environment
ITS_AI_API_KEY– used by default ifapi_keyis not passed.ITS_AI_E2E=1– enable smoke tests to hit the real API in CI (optional).
Testing
Run unit tests:
python -m pytest -q
Run smoke (real API) tests when you have a valid key:
export ITS_AI_API_KEY="api_key"
export ITS_AI_E2E=1
python -m pytest -q
API Reference (brief)
Every method has an await-able twin with the same signature on AsyncItsAIClient.
AI detection
analyze_text(text, deep_scan=False, *, timeout=None) -> AnalyzeTextResult— v1analyze_batch(texts, deep_scan=False, *, timeout=None, max_batch_size=None) -> list[AnalyzeBatchItemResult]— v1analyze_text_v2(text, *, timeout=None) -> AnalyzeTextV2Result— richer result (score,ai_percentage,probabilities,segments), always a deep scananalyze_batch_v2(texts, *, timeout=None, max_batch_size=None) -> list[AnalyzeBatchV2ItemResult]— per-texterrorinstead of one error for the whole batch
Plagiarism
check_plagiarism(text, *, timeout=None) -> PlagiarismResult
Grammar & style
check_grammar(text, *, timeout=None) -> GrammarResultcheck_grammar_batch(texts, *, timeout=None, max_batch_size=None) -> list[GrammarBatchItemResult]
Reports
download_report(report_id, *, lang=None, tz=None, timeout=None) -> bytes— the PDF certificate
Note that API access is an Enterprise-plan feature, enforced per request: a key issued on
Enterprise stops working after a downgrade (PermissionDenied).
License
MIT
For API details and the hosted endpoint see https://api.its-ai.org.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file its_ai-0.2.0.tar.gz.
File metadata
- Download URL: its_ai-0.2.0.tar.gz
- Upload date:
- Size: 32.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccd45b73b4dcb8a03a5266d1c79b6a8a03b47241ddadef6eba1cfd7233987c1d
|
|
| MD5 |
8a55814bdfaffe025efd94be0a33781e
|
|
| BLAKE2b-256 |
f6b3be54119a274b012bb8676cf14a1b9426e8935af4e3fca96036cf50b9bac9
|
File details
Details for the file its_ai-0.2.0-py3-none-any.whl.
File metadata
- Download URL: its_ai-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d1cfc85995cccf310a1b2682b14274ecec999d7615a95a8552e2e6f6a1c0046
|
|
| MD5 |
0fe2a1d6bce20116d2454d4b4edaac93
|
|
| BLAKE2b-256 |
2b76636e3ec0182d0b86a38fb55bd296f963cc908d77f27789ee02a3c7e78e9c
|