Skip to main content

AgentTax Python SDK

Sales tax, use tax, and capital gains for AI agents. Full docs at agenttax.io/api-docs.

Install

pip install agenttax

Quickstart — no signup required

from agenttax import AgentTaxClient

client = AgentTaxClient()          # keyless: demo mode, 10 calls/day

result = client.calculate(
    role="buyer",                  # buyer side needs no nexus setup
    amount=1000.00,
    buyer_state="TX",
    transaction_type="compute",
    counterparty_id="agent_seller_001",
)

print(result["total_tax"])         # use tax owed on the purchase
print(result["combined_rate"])     # the location's composed rate (state + local)
print(result["applied_rate"])      # the rate actually applied to compute total_tax
print(result["confidence"])        # {"score": ..., "level": ...}

Demo mode returns the tax figure, the rate and a confidence score. It omits the audit trail, jurisdiction breakdown and advisories, and it keeps no history. The response also carries resolution (a resolved, partial or unknown status for location, nexus and taxability) and intent, which is always "estimate" on a keyless call.

API Key

Get a free API key at agenttax.io — 1,500 calls/month at no cost — for the full response plus transaction history, nexus monitoring, capital gains tracking and 1099 export.

client = AgentTaxClient(api_key="atx_live_...")

Why role="seller" returns $0.00 on a new account

A seller only has to collect tax where it has economic nexus, and a new account has none configured — so every seller-side calculation correctly returns total_tax 0 with final_determination: "no_nexus" until you set nexus up:

import requests
requests.post(
    "https://agenttax.io/api/v1/nexus",
    headers={"X-API-Key": "atx_live_..."},
    json={"nexus": {"TX": {"hasNexus": True, "reason": "Economic nexus"}}},
)

Or pass nexus_override={"TX": {"hasNexus": True}} to calculate() to model a seller position without saving it. Note the shape — a bare list of state codes is read as "no nexus" and silently returns $0.00. Buyer-side calls need none of this, which is why the quickstart above starts there.

Methods

calculate(**kwargs)

Calculate sales tax for a transaction.

Parameter Type Required Description
role str ✓ "seller" or "buyer"
amount float ✓ Transaction amount in USD
buyer_state str ✓ Two-letter state code
transaction_type str ✓ "saas", "compute", "consulting", etc.
counterparty_id str ✓ Counterparty identifier
work_type str What the work is. One of "compute", "research", "information_service", "content", "consulting", "trading", "payment_processing", "web_hosting", "software_maintenance", "it_support", "custom_software"
is_b2b bool Business-to-business transaction
use_context str "enterprise_system", "individual", or "mixed" — Maryland-only in v1, declares whether the purchase is solely for commercial use in an enterprise computer system (TB-56); absent = unchanged is_b2b-proxy default
buyer_zip str 5-digit ZIP for local rate lookup
seller_remitting bool Buyer mode: the seller already collected the tax
nexus_override dict Model nexus for this one call, e.g. {"TX": {"hasNexus": True}}
idempotency_key str Sent as the Idempotency-Key header; a retry with the same key and body replays the first response for 24 hours
intent str "estimate" or "record" (since 0.3.0) — see below
seller_state str Seller's two-letter state code (since 0.3.0)
seller_zip str Seller's 5-digit ZIP. Required for TX, UT, AZ and TN origin-sourced intrastate sales, and for intrastate OH license or digital_good sales (since 0.3.0)
marketplace_role str "seller", "facilitator" or "direct" (API default "direct") (since 0.3.0)
exemption_certificate str Exemption certificate reference, up to 200 characters (since 0.3.0)
description str Free-text description, up to 1000 characters, recorded with the transaction (since 0.3.0)
digital_content_type str With transaction_type="digital_good" only. What the download is: "ebook", "audio", "video", "art_image", "photograph", "printable_document", "software", "data" or "other". Absent = the generic digital_good answer (since 0.3.0)
payment_provider_type str With transaction_type="payment_processing_fee". Who provides the processing: "bank", "licensed_money_transmitter", "card_network", "processor_routing_to_bank_or_network" or "other". Absent = the conservative answer (since 0.3.0)
it_support_scope str With it_support. What the engagement is: "help_desk_advice", "remote_repair_or_config", "software_installation", "monitoring", "security_monitoring" or "managed_bundle". Absent = a managed bundle (since 0.3.0)
includes_prewritten_software_access bool With transaction_type="web_hosting". True when the plan includes vendor software beyond a control panel or file manager. Absent or False = plain hosting (since 0.3.0)
custom_software_attestation dict Required with work_type="custom_software". Without a complete attestation the call is answered as prewritten software or SaaS. See below (since 0.3.0)
maintenance_contract dict With transaction_type="software_maintenance". Facts about the contract. Every key is optional and a missing fact is answered conservatively. See below (since 0.3.0)

Estimate without saving (since 0.3.0)

Pass intent="estimate" on a keyed call to price a purchase before you commit to it. You get the same figures, and nothing is saved: no transaction row, no nexus revenue, and the Idempotency-Key header is ignored (a paid retry is a new paid call). An estimate still counts toward your monthly calls. "record" is the default on keyed calls; keyless calls are always estimates.

quote = client.calculate(
    role="buyer",
    amount=1000.00,
    buyer_state="TX",
    transaction_type="compute",
    counterparty_id="agent_seller_001",
    intent="estimate",
)

print(quote["intent"])                            # "estimate"
print(quote["resolution"]["taxability"]["status"])  # "resolved" | "partial" | "unknown"

Every response carries resolution: a typed status (resolved, partial or unknown) and a basis for each of location, nexus and taxability. total_tax is never withheld, so if you want "unknown means don't charge", branch on resolution[...]["status"] yourself.

Classification facts (since 0.3.0)

Some products are taxed differently depending on facts only you know. Send them and the API uses them. Leave them out and you get the conservative answer. The SDK checks no values. The API does, and a bad value raises ValidationError. Dict facts are sent unchanged, so their inner keys use the API's snake_case names. Each fact is your representation, recorded with the transaction. It is not a state safe harbor.

# A printable planner sold as a download
client.calculate(
    role="seller",
    amount=12.00,
    buyer_state="NY",
    transaction_type="digital_good",
    counterparty_id="buyer_001",
    digital_content_type="printable_document",
)

# Custom software written for one buyer
client.calculate(
    role="seller",
    amount=5000.00,
    buyer_state="TX",
    transaction_type="service",
    work_type="custom_software",
    counterparty_id="buyer_002",
    custom_software_attestation={
        "written_for_buyer": True,
        "not_offered_to_others": True,
        "deliverable": "source_code",           # or "compiled_artifact"; "hosted" is SaaS
        "is_modification_of_prewritten": False,
    },
)

# A software maintenance contract with itemized parts
client.calculate(
    role="seller",
    amount=1000.00,
    buyer_state="PA",
    transaction_type="software_maintenance",
    counterparty_id="buyer_003",
    maintenance_contract={
        "includes_upgrades": True,
        "includes_support": True,
        "separately_itemized": True,
        "itemized_amounts": {"updates": 600, "support": 400},  # sums to amount
    },
)

The optional state facts inside custom_software_attestation and maintenance_contract are listed at agenttax.io/api-docs.

get_rates(state=None, format=None, explain=False)

Fetch sales tax rates for all 51 jurisdictions. No auth required.

get_capital_gains_rates(state=None)

Fetch state capital gains rates. No auth required.

get_local_rate(zip_code)

Fetch combined local + state rate for a ZIP code.

get_transactions(limit=50, buyer_state=..., role=..., since=...)

Fetch transaction history — the newest limit rows (max 1000). Filters: buyer_state, role, since (ISO date), passed as keywords. Auth required. The endpoint has no offset or transaction-type filter: passing offset or transaction_type raises ValidationError rather than being silently ignored. Page with since.

log_trade(**kwargs) / get_trades(**kwargs)

Capital gains trade tracking (FIFO/LIFO/Specific ID). Auth required. log_trade takes fee_amount, accounting_method ("fifo", "lifo", "specific_id"), specific_lot_id (required with "specific_id") and resident_state (the taxpayer's state of residence, for the state estimate). The 0.1.0 names fees, cost_basis_method and buyer_state are still accepted and sent under the canonical names.

Error Handling

from agenttax import AgentTaxClient, AuthError, RateLimitError, ValidationError

client = AgentTaxClient(api_key="atx_live_...")

try:
    result = client.calculate(...)
except AuthError:
    # Invalid or missing API key
    pass
except RateLimitError:
    # Monthly quota exceeded — upgrade tier or wait
    pass
except ValidationError as e:
    # Bad request parameters
    print(e)

Free Tier

1,500 API calls/month at $0. Paid plans start at $25/month (10K calls). See agenttax.io/pricing.

Metadata

Release files for agenttax 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agenttax 0.3.0
File Size Uploaded Provenance Actions
agenttax-0.3.0.tar.gz 21.1 kB With provenance Details for agenttax-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for agenttax 0.3.0
File Interpreter ABI Platform Actions
agenttax-0.3.0-py3-none-any.whl Python 3 none any Details for agenttax-0.3.0-py3-none-any.whl

Total release size: 35.7 kB

Release files / agenttax-0.3.0.tar.gz

Download URL agenttax-0.3.0.tar.gz
Size 21.1 kB
Tags Source
SHA-256 checksum
How to use checksums
7e0f5bda476b308fc8f746e498027bf06b9faab71f8252765de227acaf3e485d
BLAKE2b-256 checksum
How to use checksums
a26dbc7af755af35b5e965b26ad55628eedee48818cc9cae9aeea1a10f7b8538
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 3, 2026.

Transparency log

Release files / agenttax-0.3.0-py3-none-any.whl

Download URL agenttax-0.3.0-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d9c39f1ba6d882ef70b50c457aa03cc276c5022da27db58c33319b4824fc269b
BLAKE2b-256 checksum
How to use checksums
dec2449cf18858dd9d4e4bbd4839fd62410f5651163f1b9f1ddb93d9e56f152a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 3, 2026.

Transparency log

Security for agenttax 0.3.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for agenttax-0.3.0.tar.gz

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 Nov 3, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page