Lookup Sales Tax

Overview

Determining the amount of tax to collect from customers is a crucial act of citizenship for sellers. It is important to remember, sales taxes are not paid by sellers. Rather, sales taxes are paid by customers, collected and remitted by sellers. Sales tax rates and exemptions are driven by statutes enacted by customers' legislatures, reflecting customers' local funding priorities (including schools, fire departments, hospitals, etc.).

Sales tax collection and remittance obligations have been compulsory obligations for every local retailer in the United States, beginning shortly after the Great Depression (Missouri was the first state to enact sales tax laws in 1933). However, until recently, online retailers were not required to collect and remit sales tax, just like local retailers, due to a United States Supreme Court ruling from 1967, Bellas Hess v. Illinois.

The 1967 Bellas Hess ruling noted that all retailers should collect sales tax because the true burden of the tax falls on the buyer, not the seller. However, the 1967 Bellas Hess ruling also recognized, unlike local retailers that only need to track one jurisdiction's rules, remote retailers (then, mail-order/catalog retailers) would have to keep track of every possible jurisdiction in the country, an unequal and undue burden relative to local retailers. While this decision was reasonable and appropriate in 1967, technology had matured significantly in the 50 years that followed and the 2018 United States Supreme Court opinion in South Dakota v. Wayfair reflected this reality.

Today, every retailer (large or small, online or local), have access to technology and services capable of keeping track of tens of thousands (or millions) of district tax rules. In the case of TaxCloud, such services are available at no-cost to retailers because we are paid by our 25 member states to make sales tax compliance as easy and affordable as possible. In the remaining 20 states with sales tax, retailers have to pay for our service (as little as 0.0125% of sales, or $12.50 per $10,000 in sales activity).

With the civic duty imperative discussion out of the way, we can move on to our technical discussion.

Frequently we get calls from developers seeking sales tax rates. We cannot say this enough, rates are not the challenge for sales tax compliance. The actual challenge for sales tax compliance involves multiple factors:

  • Rates (easiest)
  • Jurisdiction identification (there are thousands of state, local, and special jurisdictions, all with varied rules and exemptions)
  • Exemption certificates for exempt entity purchasers
  • Sales tax holidays based upon product or service category and transaction date
  • Assorted caps and thresholds based upon destination and/or price
  • Rounding rules
  • Taxability — Full or partial exemptions based upon product or service category—This is the hardest part.

THE GOOD NEWS: TaxCloud respects all of these factors and influences so you don't have to. In addition to all of the time-of-sale considerations described above, TaxCloud also (optionally) manages all aspects of actual reporting, remittance, states' correspondence, and audit inquiries—at no cost to retailers in our 25 member states.

Lookup API Required Parameters

As with all TaxCloud API operations, a valid set of API Credentials are required. You can find your API Credentials in the TaxCloud > Settings > Stores area after signing into TaxCloud.

Parameter Description Example
apiLoginID Your unique 7 or 8 character API ID XXXXXXX
apiKey Your unique API KEY XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
customerID Your order management or e-commerce system generated unique customer identifier (not an email address) see about customerIDs
cartID Your order management or e-commerce system generated unique invoice or order number see about cartIDs
deliveredBySeller Boolean - usually false unless you are a florist or you deliver food false
origin An Address object (see below) representing where the order is shipping from see about Address objects
destination An Address object (see below) representing where the order is shipping to see about Address objects
cartItems Array of cartItem objects see about cartItems

Lookup API Optional Parameter for Exemption Certificates

TaxCloud supports Exemption Certificates for sales tax exempt entities (schools, churches, governments, non-profits, etc.) as well as sales tax exempt uses (purchase for resale, farming, etc.). Our Lookup API includes an optional exemptCert object parameter. This object parameter can have either:

  • A CertificateID property (to apply a previously saved Exemption Certificate from our AddExemptionCertificate API, usually the preferred approach), or;
  • A complete Detail property to create a new Exemption Certificate at the time of Lookup.
exemptCert Properties Description
CertificateID TaxCloud-issued Exemption Certificate ID - unique identifier (36)
Detail A complete ExemptionCertificateDetail object

What is a customerID?

Every Lookup request requires an immutable customer identifier. It is important that this unique customer identifier is sufficient for you to identify the underlying account holder during an audit.

The customerID (unique customer identifier) should not be your customer's email address or any other piece of Personally Identifiable Information (PII).
PRO TIP: A unique customer identifier may not be programmatically available in the first steps of a checkout/order sequence because most commerce platforms do not expose a unique customer identifier until a customer has authenticated (signed in). Most commerce platforms return a "-1" customer identifier if a session has not been authenticated. If your commerce platform restricts programmatic access to a unique customer identifier until after customer sign-in, you must remember to perform a new Lookup request after customer sign-in, using the updated actual unique customer identifier.

What is a cartID?

TaxCloud requires a customer’s shopping cart to be assigned a unique identifier before checkout. That way, TaxCloud can later connect the right Lookup with the right customer shopping cart. This cart identifier (cartID) should be used throughout a customer’s shopping experience, including checkout.

Explicit cartID (Preferred)

An Explicit CartID is usually the unique identifier automatically generated by the shopping cart system when a new customer cart is created. If the shopping cart does not automatically create an identifier, you can use any GUID-generating algorithm to create one. There are two requirements for implementing Explicit CartIDs:

  1. The shopping cart system must generate a unique cart identifier before a transaction is completed.
  2. You must have the ability to persist (via server-side database or client-side cookie) and reassociate the cartID for each unique customer session.

Passive cartID

If the shopping cart system is unable to supply a unique identifier before checkout, the initial lookup can simply omit the cartID parameter and our Lookup API will provide a unique CartID in the Response for the shopping cart system to use in all subsequent requests for the customer's checkout sequence. The only requirement for implementing Passive CartIDs is that the shopping cart system must have the ability to persist (via server-side database or client-side cookie) and reassociate such cartID for each unique customer session.

What is an Address object?

TaxCloud requires both an origin and destination address for all Lookup API requests. We understand this may be inconvenient, but it is not our fault.

In the US, all interstate (crossing state borders) commerce transactions enjoy consistent tax sourcing rules to the destination of the transaction (the buyer's shipping address, or billing address for digital goods)—this is called destination sourcing in tax-geek circles. However, for intrastate (within a single state) transactions, a handful of states source the tax jurisdiction to the origin of the transaction—this is called origin sourcing in tax-geek circles.

At TaxCloud, we don't think you should be forced to keep track of varied state-by-state tax sourcing rules (or any other interstate sales tax intricacies), so we handle that for you. However, to accomplish this feat, we need both addresses (origin and destination) at the time of Lookup. Each address object has the following properties:

Property Description Example
Address1 Numbered Street Address - string (50) 162 East Avenue
Address2 Additional Address Information - optional string (50) Third Floor
City City/Locality Name - string (50) Norwalk
State TWO CHARACTER state abbreviation - string (2) - see CT
Zip5 5-digit US Zip Code - int (5) 06851
Zip4 4-digit US Plus4 Zip Code - optional, but preferred int (4) 5715

Example

{
    "destination": {
        "Address1": "162 East Ave",
        "Address2": "Third Floor",
        "City": "Norwalk",
        "State": "CT",
        "Zip5": 06851,
        "Zip4": 5715
    }
}

Important Note About State Abbreviations

It is very important to only pass in two-character state abbreviations in the address objects of a Lookup API request. If you pass in a full state name (for example, "New York" or "South Carolina") that value will be truncated to the first two characters. Using the examples cited above, "New York" would be truncated to "NE" which is Nebraska, while "South Carolina" would be truncated to "SO" which is not a US state, but could be interpreted as Somolia.

THE GOOD NEWS: If you use our VerifyAddress API, it will automatically correct/update complete state names with the appropriate two-character abbreviation.

The current TaxCloud API does not manage sales tax for non-US jurisdictions. Please do not send VerifyAddress or Lookup requests for non-US destinations. Our TaxCloud Hydro APIs support all US Jurisdictions plus 205 countries. Contact our TaxCloud Customer Success team for more information about our TaxCloud Hydro APIs.

What is a cartItem?

TaxCloud uses a shopping cart metaphor for orders and order items. When a customer selects an item to purchase, she puts that item in her shopping cart when she presses the "Add to Order" button. Each item in her shopping cart is a unique cart item.

Property Description Example
Index The index (count) of the item, relative all items in the cart - int 0
ItemID The system maintained product identifier (sometimes called a SKU) see advisory - string(50) prod23523
TIC Taxability Information Code - int(5) 20010
Price Per-Item purchase price (after discounts) - double/decimal/money 21.95
Qty Quantity of Item being purchased - float/decimal/int 3

Example

{
    "cartItems":[
        {
            "Index": 0,
            "ItemID": "prod23523",
            "TIC": 20010,
            "Price": 21.95,
            "Qty": 3
        },
        {
            "Index": 1,
            "ItemID": "shipping",
            "TIC": 10010,
            "Price": 8.45,
            "Qty": 1
        }
    ]
}
ItemID ADVISORY:
ItemID values should be the abstract unique identifier assigned to products by your commerce platform or order management system. ItemID values should not be product details, such as a product name or book title.
 
Why?
ItemIDs are used in conjunction with the assigned TIC during tax audits to determine if a particular product (or service) was properly taxed. ItemIDs should not reveal customer-sensitive information (such as a book title) because your customers' purchasing activities should be protected from government scrutiny beyond category of goods. As Federal District Court Judge Marsha Pechman wrote in an October 2010 ruling in Amazon v. North Carolina:
The First Amendment protects a buyer from having the expressive content of her purchase of books, music, and audiovisual materials disclosed to the government. Citizens are entitled to receive information and ideas through books, films, and other expressive materials anonymously... The fear of government tracking and censoring one’s reading, listening, and viewing choices chills the exercise of First Amendment rights.

Essentially, for sales tax purposes, states can either obtain:

  • Customer Product/Purchase Details, or
  • Customer Delivery Address Information
But they cannot get both at the same time. Since address information is inherently required for accurate sales tax sourcing, the state cannot seek product details beyond basic tax category (represented by our TaxCloud TICs).

Let's do this

REQUEST

HTTPS POST api.taxcloud.net/1.0/TaxCloud/Lookup

{
    "apiLoginID": "XXXXXXX",
    "apiKey": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "customerID": "WonderfulCustomer33",
    "deliveredBySeller": false,
    "destination": {
        "Address1": "255 S King St",
        "Address2": "18th Floor",
        "City": "Seattle",
        "State": "WA",
        "Zip5": 98104,
        "Zip4": 2832
    },
    "origin": {
        "Address1": "162 East Ave # 3",
        "City": "Norwalk",
        "State": "CT",
        "Zip5": 06851,
        "Zip4": 5715
    },
    "cartItems": [
        {
            "Index": 0,
            "ItemID": "prod23523",
            "TIC": 20010,
            "Price": 21.95,
            "Qty": 3
        },
        {
            "Index": 1,
            "ItemID": "shipping",
            "TIC": 10010,
            "Price": 8.45,
            "Qty": 1
        }
    ]
}

RESPONSE (success)

{
  "CartID": "B0DABCEE-34EE-4A76-B4C5-B5F32F430B74",
  "CartItemsResponse": [
    {
      "CartItemIndex": 0,
      "TaxAmount": 6.65
    },
    {
      "CartItemIndex": 1,
      "TaxAmount": 0.85
    }
  ],
  "ResponseType": 3,
  "Messages": []
}

RESPONSE (error)

{
  "CartID": null,
  "CartItemsResponse": [],
  "ResponseType": 0,
  "Messages": [
    {
      "ResponseType": 0,
      "Message": "The Ship To zip code (98104) is not valid for this state (AL)"
    }
  ]
}

About ResponseTypes and Messages

ResponseType 3 = SUCCESS. If the ResponseType is anything other than 3, the request has failed and your commerce platform should log all errors, not just for development purposes, but more importantly for audit purposes. If the ResponseType is not 3, TaxCloud will provide a Message which will be either a single string message, or an array of string messages. All response messages should be added to your commerce platform error log, and may optionally be presented to the customer.

What's Next?

After determining the amount of sales tax to collect, the next step is to notify TaxCloud that an order has been Authorized, then Captured, or in a single API call AuthorizedWithCapture. You can proceed to our next guide: Order Completion: The Most Important Step, or you go directly to the AuthorizedWithCapture API documentation.

  • VerifyAddress
  • Lookup
  • AuthorizedWithCapture
  • Returned