Sync US sales tax exemption certificates to a customer profile.
If you sell to resellers, government agencies, or nonprofits, those buyers hold exemption certificates that exempt them from sales tax in specific states. Zonos stores those certificates against a customer profile so an exempt buyer can be recognized at checkout.
Exemptions are recorded per jurisdiction. A customer exempt in South Carolina is not automatically exempt in Texas, so each state the customer holds a certificate for is a separate record with its own dates and certificate number.
Exemptions attach to an existing customer, so syncing is two calls: create the customer, then sync their certificates. Both are keyed on your own customer ID — the same customerId you use elsewhere in Checkout. Zonos never requires you to store an internal ID.
Exemptions are not yet applied to landed cost quotes
You can sync and manage exemptions today, and the records are stored against the customer
profile. Deducting an exemption from the tax on a landed cost is coming soon, so a
synced exemption does not change the tax a shopper is quoted yet. Syncing now means your
certificates are already in place when it does.
checkoutCustomerUpsert creates a customer profile, or updates it if one already exists for that customerId. Unlike checkoutCustomerProfileAuthenticate, this does not require the shopper to be present, so you can provision your customer list ahead of time. See create or update a profile without a shopper for the full field behavior.
Because it matches on customerId, calling it repeatedly updates the same profile rather than creating duplicates. It is safe to run across your whole customer list on every sync.
The list is authoritative.taxExemptions is the customer's complete set, not a list of changes. Any exemption already on record that is missing from the list is removed — that is how a withdrawn certificate stops being honored. Sending a partial list silently removes everything it leaves out.
Every record is an exemption. There is no way to record that a customer is not exempt somewhere — see the note below.
Removing all exemptions is an empty list. To clear a customer's certificates, send them with "taxExemptions": []. Leaving the customer out of the payload entirely leaves their existing records untouched.
Send only jurisdictions the customer is exempt in
Zonos has no "not exempt" record — a jurisdiction is either in the list or it isn't. If your
system stores exempt and non-exempt jurisdictions together, filter to the exempt ones before
syncing. A non-exempt record is indistinguishable from a real certificate, so it is accepted
rather than rejected, and the customer will be treated as exempt in that state.
exemptionReason describes why the customer is exempt. It is optional and defaults to UNSPECIFIED, but supplying it is worth the effort — see below.
Value↕
Applies to↕
RESALE
Goods purchased to resell rather than consume
FEDERAL_GOVERNMENT
A US federal agency or department
STATE_LOCAL_GOVERNMENT
A state agency, county, municipality, or school district
TRIBAL_GOVERNMENT
A federally recognized tribe or tribal member
CHARITABLE
A charitable nonprofit
RELIGIOUS_ORGANIZATION
A church or other religious organization
EDUCATIONAL_ORGANIZATION
A school or university
DIRECT_PAY
A buyer who holds a direct pay permit and remits tax themselves
OTHER
Anything else, including foreign diplomat, agricultural production, industrial production, and direct mail
UNSPECIFIED
No reason supplied
Reasons fall into two groups, and the difference matters. Entity-based reasons — government, charitable, religious, educational — exempt the buyer no matter what they purchase. Use-based reasons, RESALE above all, only cover qualifying goods: a resale certificate covers inventory the buyer will resell, not the office furniture on the same order.
Without a reason, Zonos cannot tell the two apart and can only exempt whole orders, which is hardest to defend for resale certificates. If most of your exemptions are resale, sending RESALE as a default with exceptions listed individually is usually much less work than classifying every customer.
exemptionReference is the number printed on the customer's exemption paperwork. Depending on the state and the type of exemption, that may be a resale or seller's permit number, a state exemption certificate number, a direct pay permit number, or a federal tax ID.
It is required on every record. Store and send it exactly as it appears on the certificate — formats vary widely by jurisdiction (SR EAA 12-345678, 85-8012345678C-9, 12-3456789), and Zonos preserves the value as sent apart from trimming surrounding whitespace. Do not change capitalization or strip hyphens and spaces.
For privacy, exemptionReference can be sent but is not returned when reading exemptions
back, since it may contain a federal tax ID.
Records are validated one at a time. A rejected record is reported in rejected and does not fail the rest of the batch, nor does it disturb the exemption already on record for that jurisdiction.
Code↕
Cause↕
UNKNOWN_CUSTOMER
No customer matches customerId. Create the customer first
UNKNOWN_JURISDICTION
administrativeArea is not a recognized US state, district, or territory
INVALID_DATE_RANGE
expiresAt is not after effectiveAt
MISSING_EXEMPTION_REFERENCE
exemptionReference is empty
DUPLICATE_JURISDICTION
Two records in one payload share a country, area, and effective date. The first is kept
Unknown customers are rejected rather than created, so a mistyped customerId surfaces in the response instead of creating a profile that never matches a real buyer.
Only US administrative areas are validated. Subdivisions of other countries are accepted as sent.
To remove every exemption for a customer — when they close their account, for example — use checkoutCustomerTaxExemptionsDelete. It returns SUCCESS whether or not the customer had any exemptions, so it is safe to call more than once.
Tax exemptions
Tax exemptions
Sync US sales tax exemption certificates to a customer profile.
If you sell to resellers, government agencies, or nonprofits, those buyers hold exemption certificates that exempt them from sales tax in specific states. Zonos stores those certificates against a customer profile so an exempt buyer can be recognized at checkout.
Exemptions are recorded per jurisdiction. A customer exempt in South Carolina is not automatically exempt in Texas, so each state the customer holds a certificate for is a separate record with its own dates and certificate number.
Exemptions attach to an existing customer, so syncing is two calls: create the customer, then sync their certificates. Both are keyed on your own customer ID — the same
customerIdyou use elsewhere in Checkout. Zonos never requires you to store an internal ID.This feature is available for custom API integrations only.
You can sync and manage exemptions today, and the records are stored against the customer profile. Deducting an exemption from the tax on a landed cost is coming soon, so a synced exemption does not change the tax a shopper is quoted yet. Syncing now means your certificates are already in place when it does.
Create or update the customer
checkoutCustomerUpsertcreates a customer profile, or updates it if one already exists for thatcustomerId. UnlikecheckoutCustomerProfileAuthenticate, this does not require the shopper to be present, so you can provision your customer list ahead of time. See create or update a profile without a shopper for the full field behavior.mutation checkoutCustomerUpsert($input: CheckoutCustomerProfileInput!) {checkoutCustomerUpsert(input: $input) {customerIdemailnamephone}}Because it matches on
customerId, calling it repeatedly updates the same profile rather than creating duplicates. It is safe to run across your whole customer list on every sync.Sync tax exemptions
checkoutCustomerTaxExemptionsSyncaccepts several customers at once. Each entry replaces that customer's full set of exemptions.mutation checkoutCustomerTaxExemptionsSync($input: [CheckoutCustomerTaxExemptionSyncInput!]!) {checkoutCustomerTaxExemptionsSync(input: $input) {customerIdaccepted {idcountryCodeadministrativeAreaeffectiveAtexpiresAtexemptionReason}rejected {codemessageadministrativeAreaeffectiveAt}}}An omitted
expiresAtmeans the certificate does not expire. An omittedexemptionReasondefaults toUNSPECIFIED.How syncing works
Three rules govern every sync.
The list is authoritative.
taxExemptionsis the customer's complete set, not a list of changes. Any exemption already on record that is missing from the list is removed — that is how a withdrawn certificate stops being honored. Sending a partial list silently removes everything it leaves out.Every record is an exemption. There is no way to record that a customer is not exempt somewhere — see the note below.
Removing all exemptions is an empty list. To clear a customer's certificates, send them with
"taxExemptions": []. Leaving the customer out of the payload entirely leaves their existing records untouched.Zonos has no "not exempt" record — a jurisdiction is either in the list or it isn't. If your system stores exempt and non-exempt jurisdictions together, filter to the exempt ones before syncing. A non-exempt record is indistinguishable from a real certificate, so it is accepted rather than rejected, and the customer will be treated as exempt in that state.
Exemption reasons
exemptionReasondescribes why the customer is exempt. It is optional and defaults toUNSPECIFIED, but supplying it is worth the effort — see below.RESALEFEDERAL_GOVERNMENTSTATE_LOCAL_GOVERNMENTTRIBAL_GOVERNMENTCHARITABLERELIGIOUS_ORGANIZATIONEDUCATIONAL_ORGANIZATIONDIRECT_PAYOTHERUNSPECIFIEDReasons fall into two groups, and the difference matters. Entity-based reasons — government, charitable, religious, educational — exempt the buyer no matter what they purchase. Use-based reasons,
RESALEabove all, only cover qualifying goods: a resale certificate covers inventory the buyer will resell, not the office furniture on the same order.Without a reason, Zonos cannot tell the two apart and can only exempt whole orders, which is hardest to defend for resale certificates. If most of your exemptions are resale, sending
RESALEas a default with exceptions listed individually is usually much less work than classifying every customer.Exemption reference
exemptionReferenceis the number printed on the customer's exemption paperwork. Depending on the state and the type of exemption, that may be a resale or seller's permit number, a state exemption certificate number, a direct pay permit number, or a federal tax ID.It is required on every record. Store and send it exactly as it appears on the certificate — formats vary widely by jurisdiction (
SR EAA 12-345678,85-8012345678C-9,12-3456789), and Zonos preserves the value as sent apart from trimming surrounding whitespace. Do not change capitalization or strip hyphens and spaces.For privacy,
exemptionReferencecan be sent but is not returned when reading exemptions back, since it may contain a federal tax ID.Rejected records
Records are validated one at a time. A rejected record is reported in
rejectedand does not fail the rest of the batch, nor does it disturb the exemption already on record for that jurisdiction.UNKNOWN_CUSTOMERcustomerId. Create the customer firstUNKNOWN_JURISDICTIONadministrativeAreais not a recognized US state, district, or territoryINVALID_DATE_RANGEexpiresAtis not aftereffectiveAtMISSING_EXEMPTION_REFERENCEexemptionReferenceis emptyDUPLICATE_JURISDICTIONUnknown customers are rejected rather than created, so a mistyped
customerIdsurfaces in the response instead of creating a profile that never matches a real buyer.Only US administrative areas are validated. Subdivisions of other countries are accepted as sent.
Read back and remove
Read a customer's exemptions to confirm a sync landed:
query checkoutCustomerTaxExemptions($customerId: String!) {checkoutCustomerTaxExemptions(customerId: $customerId) {countryCodeadministrativeAreaeffectiveAtexpiresAtexemptionReason}}To remove every exemption for a customer — when they close their account, for example — use
checkoutCustomerTaxExemptionsDelete. It returnsSUCCESSwhether or not the customer had any exemptions, so it is safe to call more than once.mutation checkoutCustomerTaxExemptionsDelete($customerId: String!) {checkoutCustomerTaxExemptionsDelete(customerId: $customerId)}CheckoutCustomerProfileInput CheckoutCustomerTaxExemptionSyncInput
checkoutCustomerTaxExemptionsDelete checkoutCustomerTaxExemptionsSync checkoutCustomerUpsert
Was this page helpful?