Tax
curl --request POST \
--url https://win.oneshotagent.com/v1/tools/tax/rates \
--header 'Content-Type: application/json' \
--data '
{
"connection_id": "<string>",
"zip": "<string>",
"country": "<string>",
"state": "<string>",
"city": "<string>",
"street": "<string>",
"from": {},
"to": {},
"line_items": [
{}
],
"shipping": 123
}
'import requests
url = "https://win.oneshotagent.com/v1/tools/tax/rates"
payload = {
"connection_id": "<string>",
"zip": "<string>",
"country": "<string>",
"state": "<string>",
"city": "<string>",
"street": "<string>",
"from": {},
"to": {},
"line_items": [{}],
"shipping": 123
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
connection_id: '<string>',
zip: '<string>',
country: '<string>',
state: '<string>',
city: '<string>',
street: '<string>',
from: {},
to: {},
line_items: [{}],
shipping: 123
})
};
fetch('https://win.oneshotagent.com/v1/tools/tax/rates', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://win.oneshotagent.com/v1/tools/tax/rates",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'connection_id' => '<string>',
'zip' => '<string>',
'country' => '<string>',
'state' => '<string>',
'city' => '<string>',
'street' => '<string>',
'from' => [
],
'to' => [
],
'line_items' => [
[
]
],
'shipping' => 123
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/tools/tax/rates"
payload := strings.NewReader("{\n \"connection_id\": \"<string>\",\n \"zip\": \"<string>\",\n \"country\": \"<string>\",\n \"state\": \"<string>\",\n \"city\": \"<string>\",\n \"street\": \"<string>\",\n \"from\": {},\n \"to\": {},\n \"line_items\": [\n {}\n ],\n \"shipping\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/tools/tax/rates")
.header("Content-Type", "application/json")
.body("{\n \"connection_id\": \"<string>\",\n \"zip\": \"<string>\",\n \"country\": \"<string>\",\n \"state\": \"<string>\",\n \"city\": \"<string>\",\n \"street\": \"<string>\",\n \"from\": {},\n \"to\": {},\n \"line_items\": [\n {}\n ],\n \"shipping\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/tools/tax/rates")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"connection_id\": \"<string>\",\n \"zip\": \"<string>\",\n \"country\": \"<string>\",\n \"state\": \"<string>\",\n \"city\": \"<string>\",\n \"street\": \"<string>\",\n \"from\": {},\n \"to\": {},\n \"line_items\": [\n {}\n ],\n \"shipping\": 123\n}"
response = http.request(request)
puts response.read_body{
"data.combined_rate": 123,
"data.components": [
{}
],
"data.source": {},
"data.amount_to_collect": 123,
"data.rate": 123,
"data.taxable_amount": 123,
"data.breakdown": {}
}Connections
Tax
Read the sales tax rate at a location, or the tax on an order, from your connected tax system
POST
/
v1
/
tools
/
tax
/
rates
Tax
curl --request POST \
--url https://win.oneshotagent.com/v1/tools/tax/rates \
--header 'Content-Type: application/json' \
--data '
{
"connection_id": "<string>",
"zip": "<string>",
"country": "<string>",
"state": "<string>",
"city": "<string>",
"street": "<string>",
"from": {},
"to": {},
"line_items": [
{}
],
"shipping": 123
}
'import requests
url = "https://win.oneshotagent.com/v1/tools/tax/rates"
payload = {
"connection_id": "<string>",
"zip": "<string>",
"country": "<string>",
"state": "<string>",
"city": "<string>",
"street": "<string>",
"from": {},
"to": {},
"line_items": [{}],
"shipping": 123
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
connection_id: '<string>',
zip: '<string>',
country: '<string>',
state: '<string>',
city: '<string>',
street: '<string>',
from: {},
to: {},
line_items: [{}],
shipping: 123
})
};
fetch('https://win.oneshotagent.com/v1/tools/tax/rates', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://win.oneshotagent.com/v1/tools/tax/rates",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'connection_id' => '<string>',
'zip' => '<string>',
'country' => '<string>',
'state' => '<string>',
'city' => '<string>',
'street' => '<string>',
'from' => [
],
'to' => [
],
'line_items' => [
[
]
],
'shipping' => 123
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/tools/tax/rates"
payload := strings.NewReader("{\n \"connection_id\": \"<string>\",\n \"zip\": \"<string>\",\n \"country\": \"<string>\",\n \"state\": \"<string>\",\n \"city\": \"<string>\",\n \"street\": \"<string>\",\n \"from\": {},\n \"to\": {},\n \"line_items\": [\n {}\n ],\n \"shipping\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/tools/tax/rates")
.header("Content-Type", "application/json")
.body("{\n \"connection_id\": \"<string>\",\n \"zip\": \"<string>\",\n \"country\": \"<string>\",\n \"state\": \"<string>\",\n \"city\": \"<string>\",\n \"street\": \"<string>\",\n \"from\": {},\n \"to\": {},\n \"line_items\": [\n {}\n ],\n \"shipping\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/tools/tax/rates")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"connection_id\": \"<string>\",\n \"zip\": \"<string>\",\n \"country\": \"<string>\",\n \"state\": \"<string>\",\n \"city\": \"<string>\",\n \"street\": \"<string>\",\n \"from\": {},\n \"to\": {},\n \"line_items\": [\n {}\n ],\n \"shipping\": 123\n}"
response = http.request(request)
puts response.read_body{
"data.combined_rate": 123,
"data.components": [
{}
],
"data.source": {},
"data.amount_to_collect": 123,
"data.rate": 123,
"data.taxable_amount": 123,
"data.breakdown": {}
}Overview
Two read-only tools on a tax system you connected with a key (Connections). 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.
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 thepayment-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
string
required
The connection to read.
string
required
Postal code of the location.
string
default:"US"
Two-letter country code.
string
State or province code, for a more precise rate.
string
City, for a more precise rate.
string
Street address, for a rooftop-precise rate where the system offers one.
Response (200)
number
The whole rate at the location, as a fraction (0.1025 is 10.25%).
array
The rate by jurisdiction:
jurisdiction (country, state, county, city or special_district) and rate.object
system (the connected system) and id (the location reference, country:zip).{
"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
string
required
The connection to read.
object
required
Where the order ships from:
country, zip, state (required for US and CA), city, street.object
required
Where the order ships to: the same fields.
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).number
default:0
Shipping charged on the order, before tax.
Response (200)
number
The tax to collect on the order.
number
The whole rate applied, as a fraction.
number
The part of the order that is taxed.
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).object
system and id (the destination reference, country:zip).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. |