> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oneshotagent.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tax

> Read the sales tax rate at a location, or the tax on an order, from your connected tax system

## Overview

Two read-only tools on a tax system you connected with a key ([Connections](/api-reference/connections/overview)). Connected system: TaxJar. Nothing is written at the system: a calculation is a quote, and no transaction is created. Nothing fetched is kept by OneShot.

* `POST /v1/tools/tax/rates`: the rate for a location.
* `POST /v1/tools/tax/calculate`: the tax on an order.

Both take `connection_id`. An agent can have several connections to the same system: list your connections first (`GET /v1/connections`) and pick by `system` and `account_label`.

## Authentication

Requires x402 payment in the `payment-signature` header. A refused request (an unknown or inactive connection, a connection on another kind of system, an unavailable system, an invalid body) is answered before payment and is not charged.

## Tax rates

`POST /v1/tools/tax/rates`

<ParamField body="connection_id" type="string" required>
  The connection to read.
</ParamField>

<ParamField body="zip" type="string" required>
  Postal code of the location.
</ParamField>

<ParamField body="country" type="string" default="US">
  Two-letter country code.
</ParamField>

<ParamField body="state" type="string">
  State or province code, for a more precise rate.
</ParamField>

<ParamField body="city" type="string">
  City, for a more precise rate.
</ParamField>

<ParamField body="street" type="string">
  Street address, for a rooftop-precise rate where the system offers one.
</ParamField>

<Snippet file="audit-context-params.mdx" />

### Response (200)

<ResponseField name="data.combined_rate" type="number">
  The whole rate at the location, as a fraction (0.1025 is 10.25%).
</ResponseField>

<ResponseField name="data.components" type="array">
  The rate by jurisdiction: `jurisdiction` (`country`, `state`, `county`, `city` or `special_district`) and `rate`.
</ResponseField>

<ResponseField name="data.source" type="object">
  `system` (the connected system) and `id` (the location reference, `country:zip`).
</ResponseField>

```json theme={null}
{
  "success": true,
  "data": {
    "combined_rate": 0.1025,
    "components": [
      { "jurisdiction": "state", "rate": 0.0625 },
      { "jurisdiction": "county", "rate": 0.01 },
      { "jurisdiction": "special_district", "rate": 0.03 }
    ],
    "source": { "system": "taxjar", "id": "US:90210" }
  }
}
```

## Tax calculation

`POST /v1/tools/tax/calculate`

<ParamField body="connection_id" type="string" required>
  The connection to read.
</ParamField>

<ParamField body="from" type="object" required>
  Where the order ships from: `country`, `zip`, `state` (required for US and CA), `city`, `street`.
</ParamField>

<ParamField body="to" type="object" required>
  Where the order ships to: the same fields.
</ParamField>

<ParamField body="line_items" type="array" required>
  The goods on the order, 1 to 100 lines: `unit_price` (required), `quantity` (default 1), `discount`, `product_tax_code` (the system's product tax category, when the goods are not taxed at the general rate) and `id` (your reference, returned in the breakdown).
</ParamField>

<ParamField body="shipping" type="number" default={0}>
  Shipping charged on the order, before tax.
</ParamField>

<Snippet file="audit-context-params.mdx" />

### Response (200)

<ResponseField name="data.amount_to_collect" type="number">
  The tax to collect on the order.
</ResponseField>

<ResponseField name="data.rate" type="number">
  The whole rate applied, as a fraction.
</ResponseField>

<ResponseField name="data.taxable_amount" type="number">
  The part of the order that is taxed.
</ResponseField>

<ResponseField name="data.breakdown" type="object">
  `jurisdictions` (per jurisdiction: `taxable_amount`, `tax_collectable`, `rate`), `line_items` (per line, with your `id`) and `shipping` (or null when shipping is not taxed).
</ResponseField>

<ResponseField name="data.source" type="object">
  `system` and `id` (the destination reference, `country:zip`).
</ResponseField>

## Errors

| Status | Error | Meaning |
| - | - | - |
| 400 | `invalid_request` | The body is not valid. |
| 400 | `connection_wrong_system` | The connection is not on a tax system. |
| 404 | `connection_not_found` | No such connection for this agent. |
| 409 | `connection_expired`, `connection_revoked`, `connection_not_active` | The connection cannot be read; reconnect or start a new one. |
| 503 | `not_configured` | The system is not available right now. |
| 503 | `rate_limited`, `system_unavailable` | The system is busy or did not answer; a call that was paid is returned as account credit. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.