> This page is for Documentation, version Integration guides (default).
> For other versions, use one of these documentation indexes:
> - Integration guides (default): https://avalara.ferndocs.com/docs/integration-guides/llms.txt
> - Refactor guides: https://avalara.ferndocs.com/docs/refactor-guides/llms.txt
> - Get certified: https://avalara.ferndocs.com/docs/get-certified/llms.txt
> - Agent to Agent (A2A): https://avalara.ferndocs.com/docs/agent-to-agent-a2a/llms.txt
> - AI use cases: https://avalara.ferndocs.com/docs/ai-use-cases/llms.txt
> - API versioning: https://avalara.ferndocs.com/docs/api-versioning/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://avalara.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://avalara.ferndocs.com/_mcp/server.

# Calculate sales tax

Tax calculation happens through `POST /api/v2/transactions/create`. You describe the document — its type, addresses, and line items — and AvaTax returns tax for every applicable jurisdiction.

## Document types

The `type` field controls whether a transaction is recorded.

| Type           | Recorded? | Use it for                           |
| -------------- | --------- | ------------------------------------ |
| `SalesOrder`   | No        | Cart estimates and quotes            |
| `SalesInvoice` | Yes       | Finalized orders that feed reporting |

Use `SalesOrder` while a customer is shopping, then create a `SalesInvoice` at checkout.

## Request

### Request

POST [https://rest.avatax.com/api/v2/transactions/create](https://rest.avatax.com/api/v2/transactions/create)

```curl
curl -X POST https://rest.avatax.com/api/v2/transactions/create \
     -H "Authorization: <apiKey>" \
     -H "Content-Type: application/json-patch+json" \
     -d '{
  "lines": [
    {
      "amount": 100,
      "number": "1",
      "quantity": 1,
      "taxCode": "PS081282",
      "itemCode": "Y0001",
      "description": "Yarn"
    }
  ],
  "date": "2026-07-06",
  "customerCode": "ABC",
  "type": "SalesInvoice",
  "companyCode": "DEFAULT",
  "purchaseOrderNo": "2026-07-06-001",
  "addresses": {
    "singleLocation": {
      "line1": "2000 Main Street",
      "city": "Irvine",
      "region": "CA",
      "country": "US",
      "postalCode": "92614"
    }
  },
  "commit": true,
  "currencyCode": "USD",
  "description": "Yarn"
}'
```

```typescript
import { AvalaraClient } from "avalara";

async function main() {
    const client = new AvalaraClient({
        apiKey: "YOUR_API_KEY_HERE",
    });
    await client.avatax.transactions.createTransaction({
        body: {
            lines: [
                {
                    number: "1",
                    quantity: 1,
                    amount: 100,
                    taxCode: "PS081282",
                    itemCode: "Y0001",
                    description: "Yarn",
                },
            ],
            type: "SalesInvoice",
            companyCode: "DEFAULT",
            date: "2026-07-06",
            customerCode: "ABC",
            purchaseOrderNo: "2026-07-06-001",
            addresses: {
                singleLocation: {
                    line1: "2000 Main Street",
                    city: "Irvine",
                    region: "CA",
                    country: "US",
                    postalCode: "92614",
                },
            },
            commit: true,
            currencyCode: "USD",
            description: "Yarn",
        },
    });
}
main();

```

```python
from avalara import Avalara
from avalara.avatax import LineItemModel, AddressesModel, AddressLocationInfo
import datetime

client = Avalara(
    api_key="YOUR_API_KEY_HERE",
)

client.avatax.transactions.create_transaction(
    lines=[
        LineItemModel(
            number="1",
            quantity=1,
            amount=100,
            tax_code="PS081282",
            item_code="Y0001",
            description="Yarn",
        )
    ],
    type="SalesInvoice",
    company_code="DEFAULT",
    date=datetime.date.fromisoformat("2026-07-06"),
    customer_code="ABC",
    purchase_order_no="2026-07-06-001",
    addresses=AddressesModel(
        single_location=AddressLocationInfo(
            line1="2000 Main Street",
            city="Irvine",
            region="CA",
            country="US",
            postal_code="92614",
        ),
    ),
    commit=True,
    currency_code="USD",
    description="Yarn",
)

```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://rest.avatax.com/api/v2/transactions/create"

	payload := strings.NewReader("{\n  \"lines\": [\n    {\n      \"amount\": 100,\n      \"number\": \"1\",\n      \"quantity\": 1,\n      \"taxCode\": \"PS081282\",\n      \"itemCode\": \"Y0001\",\n      \"description\": \"Yarn\"\n    }\n  ],\n  \"date\": \"2026-07-06\",\n  \"customerCode\": \"ABC\",\n  \"type\": \"SalesInvoice\",\n  \"companyCode\": \"DEFAULT\",\n  \"purchaseOrderNo\": \"2026-07-06-001\",\n  \"addresses\": {\n    \"singleLocation\": {\n      \"line1\": \"2000 Main Street\",\n      \"city\": \"Irvine\",\n      \"region\": \"CA\",\n      \"country\": \"US\",\n      \"postalCode\": \"92614\"\n    }\n  },\n  \"commit\": true,\n  \"currencyCode\": \"USD\",\n  \"description\": \"Yarn\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "<apiKey>")
	req.Header.Add("Content-Type", "application/json-patch+json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://rest.avatax.com/api/v2/transactions/create")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = '<apiKey>'
request["Content-Type"] = 'application/json-patch+json'
request.body = "{\n  \"lines\": [\n    {\n      \"amount\": 100,\n      \"number\": \"1\",\n      \"quantity\": 1,\n      \"taxCode\": \"PS081282\",\n      \"itemCode\": \"Y0001\",\n      \"description\": \"Yarn\"\n    }\n  ],\n  \"date\": \"2026-07-06\",\n  \"customerCode\": \"ABC\",\n  \"type\": \"SalesInvoice\",\n  \"companyCode\": \"DEFAULT\",\n  \"purchaseOrderNo\": \"2026-07-06-001\",\n  \"addresses\": {\n    \"singleLocation\": {\n      \"line1\": \"2000 Main Street\",\n      \"city\": \"Irvine\",\n      \"region\": \"CA\",\n      \"country\": \"US\",\n      \"postalCode\": \"92614\"\n    }\n  },\n  \"commit\": true,\n  \"currencyCode\": \"USD\",\n  \"description\": \"Yarn\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://rest.avatax.com/api/v2/transactions/create")
  .header("Authorization", "<apiKey>")
  .header("Content-Type", "application/json-patch+json")
  .body("{\n  \"lines\": [\n    {\n      \"amount\": 100,\n      \"number\": \"1\",\n      \"quantity\": 1,\n      \"taxCode\": \"PS081282\",\n      \"itemCode\": \"Y0001\",\n      \"description\": \"Yarn\"\n    }\n  ],\n  \"date\": \"2026-07-06\",\n  \"customerCode\": \"ABC\",\n  \"type\": \"SalesInvoice\",\n  \"companyCode\": \"DEFAULT\",\n  \"purchaseOrderNo\": \"2026-07-06-001\",\n  \"addresses\": {\n    \"singleLocation\": {\n      \"line1\": \"2000 Main Street\",\n      \"city\": \"Irvine\",\n      \"region\": \"CA\",\n      \"country\": \"US\",\n      \"postalCode\": \"92614\"\n    }\n  },\n  \"commit\": true,\n  \"currencyCode\": \"USD\",\n  \"description\": \"Yarn\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://rest.avatax.com/api/v2/transactions/create', [
  'body' => '{
  "lines": [
    {
      "amount": 100,
      "number": "1",
      "quantity": 1,
      "taxCode": "PS081282",
      "itemCode": "Y0001",
      "description": "Yarn"
    }
  ],
  "date": "2026-07-06",
  "customerCode": "ABC",
  "type": "SalesInvoice",
  "companyCode": "DEFAULT",
  "purchaseOrderNo": "2026-07-06-001",
  "addresses": {
    "singleLocation": {
      "line1": "2000 Main Street",
      "city": "Irvine",
      "region": "CA",
      "country": "US",
      "postalCode": "92614"
    }
  },
  "commit": true,
  "currencyCode": "USD",
  "description": "Yarn"
}',
  'headers' => [
    'Authorization' => '<apiKey>',
    'Content-Type' => 'application/json-patch+json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://rest.avatax.com/api/v2/transactions/create");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "<apiKey>");
request.AddHeader("Content-Type", "application/json-patch+json");
request.AddParameter("application/json-patch+json", "{\n  \"lines\": [\n    {\n      \"amount\": 100,\n      \"number\": \"1\",\n      \"quantity\": 1,\n      \"taxCode\": \"PS081282\",\n      \"itemCode\": \"Y0001\",\n      \"description\": \"Yarn\"\n    }\n  ],\n  \"date\": \"2026-07-06\",\n  \"customerCode\": \"ABC\",\n  \"type\": \"SalesInvoice\",\n  \"companyCode\": \"DEFAULT\",\n  \"purchaseOrderNo\": \"2026-07-06-001\",\n  \"addresses\": {\n    \"singleLocation\": {\n      \"line1\": \"2000 Main Street\",\n      \"city\": \"Irvine\",\n      \"region\": \"CA\",\n      \"country\": \"US\",\n      \"postalCode\": \"92614\"\n    }\n  },\n  \"commit\": true,\n  \"currencyCode\": \"USD\",\n  \"description\": \"Yarn\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "<apiKey>",
  "Content-Type": "application/json-patch+json"
]

let postData = NSData(data: "{
  "lines": [
    {
      "amount": 100,
      "number": "1",
      "quantity": 1,
      "taxCode": "PS081282",
      "itemCode": "Y0001",
      "description": "Yarn"
    }
  ],
  "date": "2026-07-06",
  "customerCode": "ABC",
  "type": "SalesInvoice",
  "companyCode": "DEFAULT",
  "purchaseOrderNo": "2026-07-06-001",
  "addresses": {
    "singleLocation": {
      "line1": "2000 Main Street",
      "city": "Irvine",
      "region": "CA",
      "country": "US",
      "postalCode": "92614"
    }
  },
  "commit": true,
  "currencyCode": "USD",
  "description": "Yarn"
}".data(using: String.Encoding.utf8)!)

let request = NSMutableURLRequest(url: NSURL(string: "https://rest.avatax.com/api/v2/transactions/create")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

## Line-level detail

Each entry in `lines` can carry its own item code, tax code, and amount. AvaTax maps `itemCode` to the tax rules you've configured, so a potted fern and a gift card on the same order are taxed correctly.

**`Multi-line order with a discount`**

```json title="Multi-line order with a discount"
{
  "type": "SalesInvoice",
  "companyCode": "GREENLEAF",
  "customerCode": "CUST-4021",
  "date": "2026-07-06",
  "discount": 5.00,
  "addresses": {
    "shipFrom": { "line1": "312 Nursery Row", "city": "Seattle", "region": "WA", "postalCode": "98101", "country": "US" },
    "shipTo":   { "line1": "88 Garden Ave", "city": "Denver", "region": "CO", "postalCode": "80202", "country": "US" }
  },
  "lines": [
    { "number": "1", "quantity": 3, "amount": 74.97, "itemCode": "FERN-06", "description": "Potted Boston fern", "discounted": true },
    { "number": "2", "quantity": 1, "amount": 24.00, "itemCode": "SOIL-01", "description": "Organic potting mix" }
  ]
}
```

> **Tip**
>
> Set `discounted: true` on the lines a document-level `discount` should apply to. AvaTax spreads the discount across those lines before calculating tax.

## Response

The response echoes each line with its computed `tax`, plus a `summary` array breaking tax down by jurisdiction and tax type.

### Response (201)

```json
{
  "id": 123456789,
  "code": "becc7b69-e05c-489a-95c7-52f0a0794099",
  "companyId": 12345,
  "date": "2026-07-06",
  "status": "Committed",
  "type": "SalesInvoice",
  "currencyCode": "USD",
  "exchangeRateCurrencyCode": "USD",
  "entityUseCode": "",
  "customerVendorCode": "ABC",
  "customerCode": "ABC",
  "exemptNo": "",
  "reconciled": true,
  "locationCode": "DEFAULT",
  "salespersonCode": "DEF",
  "taxOverrideType": "None",
  "taxOverrideAmount": 0,
  "taxOverrideReason": "",
  "totalAmount": 1000,
  "totalExempt": 0,
  "totalDiscount": 0,
  "totalTax": 62.5,
  "totalTaxable": 1000,
  "totalTaxCalculated": 62.5,
  "adjustmentReason": "NotAdjusted",
  "adjustmentDescription": "",
  "locked": false,
  "region": "CA",
  "country": "US",
  "version": 0,
  "originAddressId": 123456789,
  "destinationAddressId": 123456789,
  "exchangeRateEffectiveDate": "2026-07-06",
  "exchangeRate": 2,
  "isSellerImporterOfRecord": false,
  "description": "Yarn",
  "taxDate": "2026-07-06T00:00:00+00:00",
  "lines": [
    {
      "id": 123456789,
      "transactionId": 123456789,
      "lineNumber": "1",
      "boundaryOverrideId": 0,
      "entityUseCode": "",
      "description": "Yarn",
      "destinationAddressId": 12345,
      "originAddressId": 123456789,
      "discountAmount": 100,
      "discountTypeId": 0,
      "exemptAmount": 0,
      "exemptCertId": 0,
      "exemptNo": "",
      "isItemTaxable": true,
      "isSSTP": false,
      "itemCode": "116292",
      "lineAmount": 1000,
      "quantity": 1,
      "ref1": "Note: Deliver to Bob",
      "reportingDate": "2026-07-06",
      "revAccount": "",
      "sourcing": "Destination",
      "tax": 62.5,
      "taxableAmount": 1000,
      "taxCalculated": 62.5,
      "taxCode": "PS081282",
      "taxDate": "2026-07-06",
      "taxEngine": "",
      "taxOverrideType": "None",
      "taxOverrideAmount": 0,
      "taxOverrideReason": "",
      "taxIncluded": false,
      "details": [
        {
          "id": 123456789,
          "transactionLineId": 123456789,
          "transactionId": 123456789,
          "addressId": 12345,
          "country": "US",
          "region": "CA",
          "stateFIPS": "06",
          "exemptAmount": 0,
          "exemptReasonId": 4,
          "exemptRuleId": 0,
          "inState": false,
          "jurisCode": "06",
          "jurisName": "CALIFORNIA",
          "jurisdictionId": 5000531,
          "signatureCode": "AGAM",
          "stateAssignedNo": "",
          "jurisType": "STA",
          "nonTaxableAmount": 0,
          "nonTaxableRuleId": 0,
          "nonTaxableType": "BaseRule",
          "rate": 0.0625,
          "rateRuleId": 1321915,
          "rateSourceId": 3,
          "serCode": "",
          "sourcing": "Destination",
          "tax": 62.5,
          "taxableAmount": 1000,
          "taxType": "Sales",
          "taxName": "CA STATE TAX",
          "taxAuthorityTypeId": 45,
          "taxRegionId": 2127184,
          "taxCalculated": 62.5,
          "taxOverride": 0,
          "rateType": "General",
          "taxableUnits": 62.5,
          "nonTaxableUnits": 1000,
          "exemptUnits": 62.5,
          "reportingTaxableUnits": 125,
          "reportingNonTaxableUnits": 2000,
          "reportingExemptUnits": 125,
          "reportingTax": 125,
          "reportingTaxCalculated": 125,
          "recoverabilityPercentage": 1,
          "recoverableAmount": 62.5,
          "nonRecoverableAmount": 0,
          "vatCode": "",
          "granularDutyDetails": [
            {
              "amount": "105.00",
              "dutyType": "ImportDuty",
              "rate": "10.5"
            }
          ]
        }
      ],
      "vatNumberTypeId": 0,
      "recoverabilityPercentage": 1,
      "recoverableAmount": 62.5,
      "nonRecoverableAmount": 0
    }
  ],
  "addresses": [
    {
      "id": 0,
      "transactionId": 0,
      "boundaryLevel": "Address",
      "line1": "100 Ravine Lane Northeast #220",
      "city": "Bainbridge Island",
      "region": "WA",
      "postalCode": "98110",
      "country": "US",
      "taxRegionId": 0
    }
  ],
  "taxDetailsByTaxType": [
    {
      "taxType": "SalesAndUse",
      "totalTaxable": 100,
      "totalExempt": 0.05,
      "totalNonTaxable": 0,
      "totalTax": 0.625
    }
  ]
}
```

## Exemptions

To exempt a line or document, pass an `exemptionNo` or an `entityUseCode` (for example, `G` for a government buyer). AvaTax validates the reason and zeroes out tax where the exemption applies.

> **Note**
>
> Calculation is deterministic: the same document always yields the same tax. Persist the returned transaction `code` so you can commit, adjust, or void it later.