> This page is for version v5.0.
> For other versions, use one of these documentation indexes:
> - v6.0 (default): https://docs.zip.tax/v-6-0/llms.txt
> - v5.0: https://docs.zip.tax/v-5-0/llms.txt

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

# Product Codes

Ziptax offers two endpoints for mapping product descriptions to Taxability Information Codes (TICs):

* **[Product Code Search](#product-code-search)** — returns a ranked list of all applicable TICs matching a natural language description, each with a relevance score.
* **[Product Code Recommendation](#product-code-recommendation)** — uses the same natural language input, plus an AI-powered model, to return the single best TIC match for your product.

> **Tip**
>
> Use **Search** when you want to present multiple options (e.g. in a merchant-facing UI). Use **Recommendation** when you want the system to pick the best TIC automatically.

---

## Product Code Search

The Product Code Search endpoint returns a ranked list of all applicable Product Codes (TICs) that match a natural language product description. Each result includes a relevance score so you can surface the best matches in your application.

### Endpoint

### Request

POST [https://api.zip-tax.com/search/tic](https://api.zip-tax.com/search/tic)

```curl
curl -X POST https://api.zip-tax.com/search/tic \
     -H "X-API-KEY: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "query": "Ceramic & Pottery Kilns"
}'
```

```python
import requests

url = "https://api.zip-tax.com/search/tic"

payload = { "query": "Ceramic & Pottery Kilns" }
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.zip-tax.com/search/tic';
const options = {
  method: 'POST',
  headers: {'X-API-KEY': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"query":"Ceramic & Pottery Kilns"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

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

func main() {

	url := "https://api.zip-tax.com/search/tic"

	payload := strings.NewReader("{\n  \"query\": \"Ceramic & Pottery Kilns\"\n}")

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

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/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://api.zip-tax.com/search/tic")

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

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"query\": \"Ceramic & Pottery Kilns\"\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://api.zip-tax.com/search/tic")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"query\": \"Ceramic & Pottery Kilns\"\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.zip-tax.com/search/tic', [
  'body' => '{
  "query": "Ceramic & Pottery Kilns"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api.zip-tax.com/search/tic");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"query\": \"Ceramic & Pottery Kilns\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = ["query": "Ceramic & Pottery Kilns"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.zip-tax.com/search/tic")! 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()
```

### Header Parameters

**`X-API-KEY`** `string` — required

Your Ziptax API key.

---

### Body Parameters

**`query`** `string` — required

A full-text product description. The API returns all applicable product codes matching this description, ranked by relevance.

---

### Example

#### cURL

```bash
curl -X POST https://api.zip-tax.com/search/tic \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "baked bread in plastic packaging"
  }'
```

#### Python

```python
import requests

response = requests.post(
    "https://api.zip-tax.com/search/tic",
    headers={"X-API-KEY": "YOUR_API_KEY"},
    json={"query": "baked bread in plastic packaging"},
)

print(response.json())
```

#### Go

```go
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]string{
        "query": "baked bread in plastic packaging",
    })

    req, _ := http.NewRequest("POST",
        "https://api.zip-tax.com/search/tic",
        bytes.NewBuffer(body))
    req.Header.Set("X-API-KEY", "YOUR_API_KEY")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()
}
```

#### Example Response

```json
{
  "$schema": "https://api.zip-tax.com/schemas/ticsearch",
  "nextCursor": "eyJxdWVyeV9oYXNoIjoiYmFrZWQtYnJlYWQtaW4tcGxhc3RpYy1wYWNrYWdpbmciLCJvZmZzZXQiOjEwfQ==",
  "query": "baked bread in plastic packaging",
  "results": [
    {
      "ticId": 41030,
      "label": "Bakery Items",
      "naturalLabel": "Bakery Items",
      "description": "Bakery items sold without eating utensils provided by the seller, including bread, rolls, buns, biscuits, bagels, croissants, pastries, donuts, Danish, cakes, tortes, pies, tarts, muffins, bars, cookies, tortillas ",
      "documentation": "Bakery items sold without eating utensils provided by the seller, including bread, rolls, buns, biscuits, bagels, croissants, pastries, donuts, Danish, cakes, tortes, pies, tarts, muffins, bars, cookies, and tortillas.",
      "rank": 1,
      "score": 0.891025641025641
    },
    {
      "ticId": 0,
      "label": "General",
      "naturalLabel": "Uncategorized tangilble personal property",
      "description": "Uncategorized tangilble personal property",
      "documentation": "Any tangible personal property that does not fit within the other defined categories. This TIC defaults to taxable in all states. For uncategorized services, use TIC 00001.",
      "rank": 2,
      "score": 0.8249269005847953
    },
    {
      "ticId": 40030,
      "label": "Food and Food ingredients",
      "naturalLabel": "Food and food ingredients excluding alcoholic beverages and tobacco",
      "description": "Food and food ingredients excluding alcoholic beverages and tobacco",
      "documentation": "Food and food ingredients means substances, whether in liquid, concentrated, solid, frozen, dried, or dehydrated form, that are sold for ingestion or chewing by humans and are consumed for their taste or nutritional value. Note: Excludes alcoholic beverages and tobacco.",
      "rank": 3,
      "score": 0.7809034572733202
    }
  ]
}
```

---

## Product Code Recommendation

The Product Code Recommendation endpoint accepts the same natural language input as Product Code Search, but adds an AI-powered model that selects the single best TIC match for your product. Use this endpoint when you need the most accurate automatic recommendation for a given product description.

### Endpoint

### Request

POST [https://api.zip-tax.com/search/tic/recommend](https://api.zip-tax.com/search/tic/recommend)

```curl
curl -X POST https://api.zip-tax.com/search/tic/recommend \
     -H "X-API-KEY: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "query": "wireless bluetooth headphones"
}'
```

```python
import requests

url = "https://api.zip-tax.com/search/tic/recommend"

payload = { "query": "wireless bluetooth headphones" }
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.zip-tax.com/search/tic/recommend';
const options = {
  method: 'POST',
  headers: {'X-API-KEY': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"query":"wireless bluetooth headphones"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

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

func main() {

	url := "https://api.zip-tax.com/search/tic/recommend"

	payload := strings.NewReader("{\n  \"query\": \"wireless bluetooth headphones\"\n}")

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

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/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://api.zip-tax.com/search/tic/recommend")

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

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"query\": \"wireless bluetooth headphones\"\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://api.zip-tax.com/search/tic/recommend")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"query\": \"wireless bluetooth headphones\"\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.zip-tax.com/search/tic/recommend', [
  'body' => '{
  "query": "wireless bluetooth headphones"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api.zip-tax.com/search/tic/recommend");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"query\": \"wireless bluetooth headphones\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = ["query": "wireless bluetooth headphones"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.zip-tax.com/search/tic/recommend")! 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()
```

### Header Parameters

**`X-API-KEY`** `string` — required

Your Ziptax API key.

---

### Body Parameters

**`query`** `string` — required

A full-text product description. The model returns the best matching TIC for this description.

---

### Example

#### cURL

```bash
curl -X POST https://api.zip-tax.com/search/tic/recommend \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "baked bread in plastic packaging"
  }'
```

#### Python

```python
import requests

response = requests.post(
    "https://api.zip-tax.com/search/tic/recommend",
    headers={"X-API-KEY": "YOUR_API_KEY"},
    json={"query": "baked bread in plastic packaging"},
)

print(response.json())
```

#### Go

```go
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]string{
        "query": "baked bread in plastic packaging",
    })

    req, _ := http.NewRequest("POST",
        "https://api.zip-tax.com/search/tic/recommend",
        bytes.NewBuffer(body))
    req.Header.Set("X-API-KEY", "YOUR_API_KEY")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()
}
```

#### Example Response

```json
{
    "predictions": [
        {
            "status": "success",
            "error": null,
            "ticId": 41030,
            "label": "Bakery Items",
            "naturalLabel": "Bakery Items",
            "tic_description": "Bakery items sold without eating utensils provided by the seller, including bread, rolls, buns, biscuits, bagels, croissants, pastries, donuts, Danish, cakes, tortes, pies, tarts, muffins, bars, cookies, tortillas ",
            "product_description": "baked bread in plastic packaging"
        }
    ]
}
```